docker部署
2023-06-15 20:09:52
技术
基本使用
编写 Dockerfile
在项目根目录下编写Dockerfile(默认使用名称就是Dockerfile
,不需要后缀)
FROM golang:alpine
# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64
# 移动到工作目录:/build
WORKDIR /build
# 将代码复制到容器中
COPY . .
# 将我们的代码编译成二进制可执行文件app
RUN go build -o app .
# 移动到用于存放生成的二进制文件的 /dist 目录
WORKDIR /dist
# 将二进制文件从 /build 目录复制到这里
RUN cp /build/app .
# 声明服务端口
EXPOSE 9000
# 启动容器时运行的命令
CMD ["/dist/app"]
构建 docker 镜像
项目根目录下执行,创建镜像并制定镜像名为 web_app
docker build . -t web_app
运行镜像
指定端口运行镜像
docker run -p 9000:9000 web_app
最佳实践
分阶段构建
Go 程序编译之后会得到一个可执行的二进制文件,在最终的镜像中是不需要 go 编译器的,但是以上的 dockerfile 会把 go 的编译环境也打包到镜像中。
分阶段构建的目的是仅打包需要打包的,尽可能地减小镜像的体积
###################
# 1. AS: 构建阶段作为一个镜像,命名为 builder
###################
FROM golang:alpine AS builder
# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64
# 移动到工作目录:/build
WORKDIR /build
# 将代码复制到容器中
COPY . .
# 将我们的代码编译成二进制可执行文件 app
RUN go build -o app .
###################
# 2. 创建一个小镜像,scratch 是 docker 中的最小镜像
###################
FROM scratch
# 从builder镜像中把/dist/app 拷贝到当前目录
COPY --from=builder /build/app /
# 需要运行的命令
ENTRYPOINT ["/app"]
将编译环境的部分给忽略掉,只把可执行文件的镜像拷贝到一个最小镜像中
拷贝其他文件
除了go还附带其他文件,比如网页的静态文件等等则需要拷贝,一起放在镜像中
...
FROM scratch
COPY ./templates /templates
COPY ./static /static
COPY ./conf /conf
...
不过这种是前后端放在一起部署,并非所谓的前后端分离,前后端分离一般会是使用 nginx 来部署,之后再介绍。
多容器
容器关联
在使用多个容器时会用到,比如在使用 MySQL 时是用的docker容器,容器名为MySQL123。那么在配置文件中修改host项为容器名,如:
host: mysql123
修改后重新构建镜像
docker build . -t web_app
运行应用容器并与容器mysql123
关联
docker run --link=mysql123:mysql123 -p 8888:8888 web_app_app
docker compose(容器编排)
参考于别处
- 使用Dockerfile定义你的应用环境以便可以在任何地方复制。
- 定义组成应用程序的服务,docker-compose.yml 以便它们可以在隔离的环境中一起运行。
- 执行 docker-compose up命令来启动并运行整个应用程序。
编写docker-compose.yml
文件名:docker-compose.yml
# yaml 配置
version: "3.7"
services:
# mysql容器
mysql8019:
image: "mysql:8.0.19"
ports:
- "33061:3306"
command: "--default-authentication-plugin=mysql_native_password --init-file /data/application/init.sql"
environment:
MYSQL_ROOT_PASSWORD: "mysql123"
MYSQL_DATABASE: "web_app"
MYSQL_PASSWORD: "mysql123"
volumes:
- ./init.sql:/data/application/init.sql # 数据库初始化
# redis容器, 参考mysql即可
redis:
image: ""
ports:
- ""
# 应用程序的容器
web_app:
build: .
command: sh -c "./wait-for.sh mysql8019:3306 redis:6379 -- ./web_app ./conf/config.ini"
depends_on:
- mysql8019
ports:
- "9000:9000"
容器的编排有先后顺序,以上述为例,必须先启动mysql与redis后才能启动应用程序。
编写Dockerfile
FROM golang:alpine AS builder
# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64
# 移动到工作目录:/build
WORKDIR /build
# 将代码复制到容器中
COPY . .
# 下载依赖信息
RUN go mod download
# 将我们的代码编译成二进制可执行文件 web_app
RUN go build -o web_app .
###################
# 接下来创建一个小镜像
###################
FROM debian:stretch-slim
# 从builder镜像中把脚本拷贝到当前目录
COPY ./wait-for.sh /
# 从builder镜像中把静态文件拷贝到当前目录
COPY ./templates /templates
COPY ./static /static
# 从builder镜像中把配置文件拷贝到当前目录
COPY ./conf /conf
# 从builder镜像中把/dist/app 拷贝到当前目录
COPY --from=builder /build/web_app /
RUN set -eux; \
apt-get update; \
apt-get install -y \
--no-install-recommends \
netcat; \
chmod 755 wait-for.sh
# 不在Dockerfile里运行
# ENTRYPOINT ["/web_app", "conf/config.ini"]
执行
docker-compose up