1. Docker Compose简介
Docker Compose 是一个用于定义和运行多容器应用程序的工具。Docker Compose通过YAML 配置文件中轻松管理服务、网络和卷。然后,使用单个命令,您可以从配置文件创建并启动所有服务。
2. 讲解例子
这里以安装V5Notes云笔记服务端为例来讲解Docker Compose安装多个Docker服务。如MySQL、Redis、V5Notes服务端和V5Notes前端页面Nginx服务。
2.1 MySQL
先看代码
mysql:
container_name: v5notes-mysql
image: mysql:8.4.0
environment:
# 时区上海
TZ: Asia/Shanghai
# root123# 密码
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
# 初始化数据库(后续的初始化sql会在这个库执行)
MYSQL_DATABASE: ${MYSQL_DATABASE}
# MYSQL_ROOT_HOST: '%'
volumes:
- ./mysql/conf/:/etc/mysql/conf.d/
- ./mysql/logs/:/var/log/mysql/
- ./mysql/data/:/var/lib/mysql/
# 1. 初始化表结构
- ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
# 2. 把所有初始化脚本挂载到Docker容器内
- ../v5notes/script/sql/ry_vue_5.X.sql:/mnt/sql/ry_vue_5.X.sql:ro
- ../v5notes/script/sql/basics_file.sql:/mnt/sql/basics_file.sql:ro
- ../v5notes/script/sql/notes.sql:/mnt/sql/notes.sql:ro
ports:
- "3306:3306"
# on-failure 若容器的退出状态非0,则docker自动重启容器,还可以指定重启次数,若超过指定次数未能启动容器则放弃
restart: on-failure:5
privileged: true
这里主要要说的是创建一个初始化数据库,并且初始化V5Notes云笔记数据库表。
从上面Yaml文件可以看到把需要执行SQL文件挂载到 /docker-entrypoint-initdb.d/
目录下,容器创建后就可以执行。但从上面Yaml代码可以看到,第一步把 init.sql
挂载到 /docker-entrypoint-initdb.d/
目录,其他脚本只是挂载到 /mnt/sql/
目录下。这是因为初始化SQL脚本是有执行顺序要求的,如果全部挂载到 /docker-entrypoint-initdb.d/
目录,它在执行时不能按照要求顺序执行的。那如何按照顺序执行呢。查看 init.sql
文件
use v5notes-prod;
SET NAMES utf8mb4;
source /mnt/sql/ry_vue_5.X.sql
source /mnt/sql/basics_file.sql
source /mnt/sql/notes.sql
按照上面的写法就可以按照顺序执行脚本了。
${MYSQL_DATABASE}
这些内容是保存在独立的配置文件中,在docker compose执行时指定配置文件就可以了。
2.2 Redis
Redis的服务配置就比较简单了,看代码
redis:
container_name: v5notes-redis
image: redis:7.4.1
volumes:
- ./redis/data:/data
# 自定义redis配置,如果不需要特殊要求,可以不添加
- ./redis/redis.conf:/etc/redis/redis.conf
ports:
- "6379:6379"
restart: on-failure:5
privileged: true
2.3 V5Note服务
这部分主要是项目打包后如何动态修改配置信息,如数据库,Redis等,需要根据实际情况修改的配置信息。这需要在Dockrfile文件配置一个传参变量。
FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
LABEL maintainer="Lion Li"
RUN mkdir -p /ruoyi/server/logs \
/ruoyi/server/temp \
/ruoyi/skywalking/agent
WORKDIR /ruoyi/server
ENV SERVER_PORT=8080 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
## 应用参数 https://github.com/polovyivan/docker-pass-configs-to-container
ENV ARGS=""
EXPOSE ${SERVER_PORT}
ADD ./target/ruoyi-admin.jar ./app.jar
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
# 应用名称 如果想区分集群节点监控 改成不同的名称即可
#-Dskywalking.agent.service_name=ruoyi-server \
#-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \
-XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \
-jar app.jar $ARGS
在Dockerfile中定义一个ARGS变量,在执行java时传入$ARGS。
这样Docker Compose的文件中就可以这样写了
v5notes:
container_name: v5notes-server
image: registry.cn-hangzhou.aliyuncs.com/zywlxh/ruoyi-server:1.0.4
ports:
- "8080:8080"
volumes:
- ./ruoyi/logs:/ruoyi/server/logs
- ./uploadfile:/mnt/uploadfile
restart: on-failure:5
environment:
# https://github.com/polovyivan/docker-pass-configs-to-container
TZ: Asia/Shanghai
SPRING_PROFILES_ACTIVE: prod
ARGS:
--spring.datasource.dynamic.datasource.master.url=${MASTER_DATASOURCE_URL:-jdbc:mysql://yudao-mysql:3306/v5notes-prod?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true}
--spring.datasource.dynamic.datasource.master.username=${MASTER_DATASOURCE_USERNAME:-root}
--spring.datasource.dynamic.datasource.master.password=${MASTER_DATASOURCE_PASSWORD:-root123#}
--spring.datasource.dynamic.datasource.slave.url=${SLAVE_DATASOURCE_URL:-jdbc:mysql://v5notes-mysql:3306/v5notes-prod?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true}
--spring.datasource.dynamic.datasource.slave.username=${SLAVE_DATASOURCE_USERNAME:-root}
--spring.datasource.dynamic.datasource.slave.password=${SLAVE_DATASOURCE_PASSWORD:-root123#}
--spring.data.redis.host=${REDIS_HOST:-v5notes-redis}
depends_on:
- mysql
- redis
在yaml文件中就可以像上面那样按照实际情况修改配置文件了。
2.3 前端代码Nginx
这部分主要是讲的把前端代码打包进入Docker容器内的情况。然后就是通过修改Nginx配置文件的情况了。
首先需要在前端创建 nginx.template
和 Dockerfile
代码如下:
worker_processes 2;
events {
worker_connections 10240;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
underscores_in_headers on;
keepalive_timeout 65;
gzip on; # 启用gzip压缩,默认是off,不启用
# 对js、css、jpg、png、gif格式的文件启用gzip压缩功能
gzip_types application/javascript text/css image/jpeg image/png image/gif;
gzip_min_length 1024; # 所压缩文件的最小值,小于这个的不会压缩
gzip_buffers 4 1k; # 设置压缩响应的缓冲块的大小和个数,默认是内存一个页的大小
gzip_comp_level 1; # 压缩水平,默认1。取值范围1-9,取值越大压缩比率越大,但越耗cpu时
upstream ruoyiadmin{
# 读取环境变量中的内容,使用envsubst完成环境变量替换,可以查看Dockerfile文件
server ${V5NOTES_SERVER_HOST}:${V5NOTES_SERVER_PORT};
}
server {
listen 8988;
location / {
root /mnt/ruoyi-web;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location /prod-api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://ruoyiadmin/;
proxy_connect_timeout 600;
proxy_read_timeout 600;
client_max_body_size 10000m;
}
}
}
server ${V5NOTES_SERVER_HOST}:${V5NOTES_SERVER_PORT};
这部分代码就是需要动态修改的nginx.conf代码。
# 设置 nginx 作为静态资源服务器
# 指定基础镜像nginx:alpine
FROM nginx:alpine
# 将我们自定义的网站静态文件复制到容器中
COPY dist/ /mnt/ruoyi-web/
# 将我们自定义的nginx配置文件复制到容器中/etc/nginx/nginx.conf
COPY nginx.template /etc/nginx/
# 3. 切换工作目录
WORKDIR /etc/nginx
# 4. 添加环境变量的写入
ENTRYPOINT envsubst '$V5NOTES_SERVER_HOST $V5NOTES_SERVER_PORT' < nginx.template > nginx.conf && nginx -g 'daemon off;'
# 暴露8988端口
EXPOSE 8988
上面第四步执行nginx配置文件动态替换。
这样在可以Docker Compose自定需要替换的内容。
v5notes-admin:
container_name: v5notes-admin
image: registry.cn-hangzhou.aliyuncs.com/zywlxh/v5notes-admin:1.0.0
ports:
- "8988:8988"
environment:
- V5NOTES_SERVER_HOST=v5notes-server
# 容器内端口,而不是映射出来的端口
- V5NOTES_SERVER_PORT=8080
volumes:
- ./nginx/logs:/var/log/nginx
# - ./nginx.conf:/etc/nginx/nginx.conf
restart: on-failure:5
tty: true
privileged: true
depends_on:
- v5notes
按照上面的配置就可以一键按照全部所需的服务了。
执行Docker Compose命令
docker compose --env-file ./env/v5notes.env up -d
3. 结束
希望上面的文章对你平时开发工作有所帮助。谢谢!
评论区