module_nginx.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright 2017 The go-ethereum Authors
  2. // This file is part of go-ethereum.
  3. //
  4. // go-ethereum is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // go-ethereum is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
  16. package main
  17. import (
  18. "bytes"
  19. "fmt"
  20. "html/template"
  21. "math/rand"
  22. "path/filepath"
  23. "github.com/ethereum/go-ethereum/log"
  24. )
  25. // nginxDockerfile is theis the Dockerfile required to build an nginx reverse-
  26. // proxy.
  27. var nginxDockerfile = `FROM jwilder/nginx-proxy`
  28. // nginxComposefile is the docker-compose.yml file required to deploy and maintain
  29. // an nginx reverse-proxy. The proxy is responsible for exposing one or more HTTP
  30. // services running on a single host.
  31. var nginxComposefile = `
  32. version: '2'
  33. services:
  34. nginx:
  35. build: .
  36. image: {{.Network}}/nginx
  37. ports:
  38. - "{{.Port}}:80"
  39. volumes:
  40. - /var/run/docker.sock:/tmp/docker.sock:ro
  41. logging:
  42. driver: "json-file"
  43. options:
  44. max-size: "1m"
  45. max-file: "10"
  46. restart: always
  47. `
  48. // deployNginx deploys a new nginx reverse-proxy container to expose one or more
  49. // HTTP services running on a single host. If an instance with the specified
  50. // network name already exists there, it will be overwritten!
  51. func deployNginx(client *sshClient, network string, port int) ([]byte, error) {
  52. log.Info("Deploying nginx reverse-proxy", "server", client.server, "port", port)
  53. // Generate the content to upload to the server
  54. workdir := fmt.Sprintf("%d", rand.Int63())
  55. files := make(map[string][]byte)
  56. dockerfile := new(bytes.Buffer)
  57. template.Must(template.New("").Parse(nginxDockerfile)).Execute(dockerfile, nil)
  58. files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
  59. composefile := new(bytes.Buffer)
  60. template.Must(template.New("").Parse(nginxComposefile)).Execute(composefile, map[string]interface{}{
  61. "Network": network,
  62. "Port": port,
  63. })
  64. files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
  65. // Upload the deployment files to the remote server (and clean up afterwards)
  66. if out, err := client.Upload(files); err != nil {
  67. return out, err
  68. }
  69. defer client.Run("rm -rf " + workdir)
  70. // Build and deploy the ethstats service
  71. return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build", workdir, network))
  72. }
  73. // nginxInfos is returned from an nginx reverse-proxy status check to allow
  74. // reporting various configuration parameters.
  75. type nginxInfos struct {
  76. port int
  77. }
  78. // String implements the stringer interface.
  79. func (info *nginxInfos) String() string {
  80. return fmt.Sprintf("port=%d", info.port)
  81. }
  82. // checkNginx does a health-check against an nginx reverse-proxy to verify whether
  83. // it's running, and if yes, gathering a collection of useful infos about it.
  84. func checkNginx(client *sshClient, network string) (*nginxInfos, error) {
  85. // Inspect a possible nginx container on the host
  86. infos, err := inspectContainer(client, fmt.Sprintf("%s_nginx_1", network))
  87. if err != nil {
  88. return nil, err
  89. }
  90. if !infos.running {
  91. return nil, ErrServiceOffline
  92. }
  93. // Container available, assemble and return the useful infos
  94. return &nginxInfos{
  95. port: infos.portmap["80/tcp"],
  96. }, nil
  97. }