github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/cmd/puppeth/module_nginx.go (about) 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 17 package main 18 19 import ( 20 "bytes" 21 "fmt" 22 "html/template" 23 "math/rand" 24 "path/filepath" 25 26 "github.com/ethereum/go-ethereum/log" 27 ) 28 29 // nginxDockerfile is theis the Dockerfile required to build an nginx reverse- 30 // proxy. 31 var nginxDockerfile = `FROM jwilder/nginx-proxy` 32 33 // nginxComposefile is the docker-compose.yml file required to deploy and maintain 34 // an nginx reverse-proxy. The proxy is responsible for exposing one or more HTTP 35 // services running on a single host. 36 var nginxComposefile = ` 37 version: '2' 38 services: 39 nginx: 40 build: . 41 image: {{.Network}}/nginx 42 ports: 43 - "{{.Port}}:80" 44 volumes: 45 - /var/run/docker.sock:/tmp/docker.sock:ro 46 restart: always 47 ` 48 49 // deployNginx deploys a new nginx reverse-proxy container to expose one or more 50 // HTTP services running on a single host. If an instance with the specified 51 // network name already exists there, it will be overwritten! 52 func deployNginx(client *sshClient, network string, port int) ([]byte, error) { 53 log.Info("Deploying nginx reverse-proxy", "server", client.server, "port", port) 54 55 // Generate the content to upload to the server 56 workdir := fmt.Sprintf("%d", rand.Int63()) 57 files := make(map[string][]byte) 58 59 dockerfile := new(bytes.Buffer) 60 template.Must(template.New("").Parse(nginxDockerfile)).Execute(dockerfile, nil) 61 files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes() 62 63 composefile := new(bytes.Buffer) 64 template.Must(template.New("").Parse(nginxComposefile)).Execute(composefile, map[string]interface{}{ 65 "Network": network, 66 "Port": port, 67 }) 68 files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes() 69 70 // Upload the deployment files to the remote server (and clean up afterwards) 71 if out, err := client.Upload(files); err != nil { 72 return out, err 73 } 74 defer client.Run("rm -rf " + workdir) 75 76 // Build and deploy the ethstats service 77 return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build", workdir, network)) 78 } 79 80 // nginxInfos is returned from an nginx reverse-proxy status check to allow 81 // reporting various configuration parameters. 82 type nginxInfos struct { 83 port int 84 } 85 86 // String implements the stringer interface. 87 func (info *nginxInfos) String() string { 88 return fmt.Sprintf("port=%d", info.port) 89 } 90 91 // checkNginx does a health-check against an nginx reverse-proxy to verify whether 92 // it's running, and if yes, gathering a collection of useful infos about it. 93 func checkNginx(client *sshClient, network string) (*nginxInfos, error) { 94 // Inspect a possible nginx container on the host 95 infos, err := inspectContainer(client, fmt.Sprintf("%s_nginx_1", network)) 96 if err != nil { 97 return nil, err 98 } 99 if !infos.running { 100 return nil, ErrServiceOffline 101 } 102 // Container available, assemble and return the useful infos 103 return &nginxInfos{ 104 port: infos.portmap["80/tcp"], 105 }, nil 106 }