使用docker-compose编排golang

Posted by Ethan Blog on February 26, 2021

演示如何使用docker-compose来编排运行golang web服务,容器包括nginx,golang,redis,访问nginx暴露的9999端口,由nginx代理到web服务的8888端口中。

代码演示

1、docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
version: '3'
services:
  nginx:  #nginx服务
    restart: always
    image: nginx
    ports:
      - "9999:9999"  # 向外部暴露9999端口
    volumes:
      #配置文件,其实就是用proxy_pass把9999转发给web服务的8888
      - ./nginx/site.conf:/etc/nginx/conf.d/default.conf 
  redis: #redis服务
    restart: always
    image: redis
    container_name: redis
    command: redis-server
    ports:
     - "6379:6379"
  websvr: #golang的web服务
    container_name: go_web
    image: "golang:alpine"
    working_dir: /data/src   #指定工作目目录
    environment:
      - GOPATH=/data/  #指定gopath
      - GO111MODULE=on   
      - GOPROXY=https://goproxy.cn
    volumes:
      - .:/data/src  
    command:
      go run /data/src/main.go

该配置文件中并没有使用link来链接,其实是因为docker-compose在编译的时候已经把每个容器hosts文件中都写好了ip与service名的映射关系。需要注意的是我们在golang的web服务器中,需要链接其他容器的服务,是不用写服务的ip地址 ,而是写服务的service名称(一下以链接redis为例)

2、golang web服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package main

import (
	"github.com/go-redis/redis"
	"net/http"
)

var redisClient *redis.Client

func init(){
	//启用redis
	redisClient = redis.NewClient(&redis.Options{
		Addr:     "redis:6379",  //这里需要填写docker-compose.yml中redis的service名称,而不是ip地址
		Password: "",
		DB:       0,
	})
}

func main() {
	//直接访问
	http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
		_, _ = w.Write([]byte("hello go"))
	})

	//测试redis
	http.HandleFunc("/redis",  func(w http.ResponseWriter, _ *http.Request){
		//写redis
		if err := redisClient.Set("hello","来自redis的内容",0).Err();err!=nil{
			_, _ = w.Write([]byte("redis set err!,"+err.Error()))
		}
		
		//读取redis
		val , err :=redisClient.Get("hello").Result()
		if err!=nil{
			_, _ = w.Write([]byte("redis get err!,"+err.Error()))
		}
		_, _ = w.Write([]byte(val))
	})
	
	//启动web服务
	server := &http.Server{
		Addr: ":8888",  //web服务监听8888端口
	}
	_ = server.ListenAndServe()

}
3、nginx配置
1
2
3
4
5
6
7
8
server {
    listen 9999;
    server_name  localhost;
    index  index.html index.htm;
    location / {
        proxy_pass  http://websvr:8888;
    }
}

nginx也是一样转发的地址并不是ip而是docker-compose.yml中配置的service名称