最近手里有一个go写的区块链工程,之前都是在本机上部署节点:写一个shell脚本,循环为每个节点go run启动
为了后续在真实分布式环境上的部署方便,所以在项目中加入docker来方便部署
基础:Go程序创建docker容器
这一步比较简单,在Dockerfile中把官方的Go容器拉过来,然后把代码放进去,下载必要的软件和依赖库,设置启动脚本为 entrypoint:
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
| FROM golang:1.23.4-alpine AS builder
WORKDIR /root/Chamael
COPY . .
ENV CGO_ENABLED=1
RUN echo "https://mirrors.aliyun.com/alpine/v3.21/main" > /etc/apk/repositories && \ echo "https://mirrors.aliyun.com/alpine/v3.21/community" >> /etc/apk/repositories && \ apk add --no-cache gcc musl-dev bash
ENV GOPROXY=https://goproxy.cn,direct
RUN go mod download
RUN chmod +x start_all.sh && chmod +x start_one.sh
ENTRYPOINT ["./start_all.sh"]
|
然后build镜像和运行就ok了:
1 2
| docker build -t chamael:latest . docker run -it --rm chamael:latest 4 3 1000 1
|
这样的代码跑起来和在本机跑也没有区别,仅仅是挪到了容器里面
进阶:Docker compose编排分布式容器
把所有节点挪到一个docker容器里面跑显然是无意义的,让一个节点运行在一个容器中,同时启动多个容器交互才是我们的最终目的,因此就需要用到Docker compose
首先是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
| version: '3' services: node0: build: . entrypoint: ['./start_one.sh', '0', '1000', '1', '1'] container_name: node0 ports: - 9233:9233 networks: - tcp_net
node1: build: . entrypoint: ['./start_one.sh', '1', '1000', '1', '1'] container_name: node1 ports: - 9234:9234 networks: - tcp_net ... networks: tcp_net: driver: bridge
|
写一个docker-compose.yml同时启动多个容器并不难,难在网络的配置:
一开始以为的方案是每个容器打开一个端口映射到主机的端口上,然后其他容器去连接的端口即可,经过查证这个方法是可行的,docker容器中主机的IP地址一般固定是172.17.0.1,不确定的话可以ifconfig看一下docker虚拟网卡的地址
然而这种方法老是出bug,最后发现docker compose会给容器创建一个内部网络,如果其他节点要去连接node0的话,只需要直接连接其container_name即可:net.Dial('tcp', 'node0:8080')
,这样一来就可以直接连接到其他容器,而不需要通过主机的端口映射了
写好compose文件以后 docker compose up
即可
注意,如果需要删掉节点镜像的话,需要先 docker compose down
关闭所有节点容器才可以删除
Author:
Boulevard H
Permalink:
https://blog.boulevard.asia/2025/02/25/docker-and-compose-net/
License:
Copyright (c) 2022 CC-BY-NC-4.0 LICENSE
Slogan:
OvO