module_nginx.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. restart: always
  42. `
  43. // deployNginx deploys a new nginx reverse-proxy container to expose one or more
  44. // HTTP services running on a single host. If an instance with the specified
  45. // network name already exists there, it will be overwritten!
  46. func deployNginx(client *sshClient, network string, port int) ([]byte, error) {
  47. log.Info("Deploying nginx reverse-proxy", "server", client.server, "port", port)
  48. // Generate the content to upload to the server
  49. workdir := fmt.Sprintf("%d", rand.Int63())
  50. files := make(map[string][]byte)
  51. dockerfile := new(bytes.Buffer)
  52. template.Must(template.New("").Parse(nginxDockerfile)).Execute(dockerfile, nil)
  53. files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
  54. composefile := new(bytes.Buffer)
  55. template.Must(template.New("").Parse(nginxComposefile)).Execute(composefile, map[string]interface{}{
  56. "Network": network,
  57. "Port": port,
  58. })
  59. files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
  60. // Upload the deployment files to the remote server (and clean up afterwards)
  61. if out, err := client.Upload(files); err != nil {
  62. return out, err
  63. }
  64. defer client.Run("rm -rf " + workdir)
  65. // Build and deploy the ethstats service
  66. return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build", workdir, network))
  67. }
  68. // nginxInfos is returned from an nginx reverse-proxy status check to allow
  69. // reporting various configuration parameters.
  70. type nginxInfos struct {
  71. port int
  72. }
  73. // String implements the stringer interface.
  74. func (info *nginxInfos) String() string {
  75. return fmt.Sprintf("port=%d", info.port)
  76. }
  77. // checkNginx does a health-check against an nginx reverse-proxy to verify whether
  78. // it's running, and if yes, gathering a collection of useful infos about it.
  79. func checkNginx(client *sshClient, network string) (*nginxInfos, error) {
  80. // Inspect a possible nginx container on the host
  81. infos, err := inspectContainer(client, fmt.Sprintf("%s_nginx_1", network))
  82. if err != nil {
  83. return nil, err
  84. }
  85. if !infos.running {
  86. return nil, ErrServiceOffline
  87. }
  88. // Container available, assemble and return the useful infos
  89. return &nginxInfos{
  90. port: infos.portmap["80/tcp"],
  91. }, nil
  92. }