DockerCompose部署项目(以若依为例)_若依docker
大家好,我是爪哇小小怪,热爱Java后端开发者,两年多JAVA开发经验(工作以来一直从事Java全栈开发),一个想要与大家共同进步的码农。
前言
23年7月我发布了一篇若依前后端分离项目部署文章,当时写文章时,部署这个项目的技术采用的是Docker技术进行部署的。
通过文章中展示的部署过程,我们可以发现部署若依前后端其实只需要配置3个容器:MySQL、Redis 和 Nginx,这三个容器完成了所有的部署工作。但是,文章中展示的部署过程都是手动逐一进行操作的,干过开发的朋友们心中应该明白真实的企业项目开发中,稍微复杂一点的单体式项目还需要其它的各种各样的中间件,比如MQ,Kafka,MyCat等等,需要部署的软件环境远不止3个,如果还像我去年写的这篇文章一样逐一的部署,那不是太麻烦了?所以这篇文章给大家聊一下docker-compose。
1. docker-compose介绍
定义:Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过 Docker Compose,用户可以使用 YAML 文件来定义应用服务的配置,并通过单一命令启动所有相关的容器,使得在开发、测试和生产环境中管理 Docker 容器变得更加高效和便捷。
1.1 docker-compose的基本概念
docker-compose核心概念如下:
- 服务(Services):服务是一个 Docker 容器的抽象,定义了容器的具体配置,比如镜像、环境变量、端口映射等。Compose 文件中的每个服务都会对应一个 Docker 容器
- 应用(App):一个完整的应用通常由多个服务组成(例如数据库服务、应用服务、缓存服务等),这些服务通过 Compose 文件进行配置。
- 网络(Networks):Compose 默认会为容器创建一个自定义的网络,容器可以通过该网络互相通信。
- 卷(Volumes):Docker Compose 支持卷挂载,允许容器之间共享数据,或在容器停止后持久化数据。
1.2 docker-compose的工作原理
docker-compose主要通过一个名为docker-compose.yml的YAML文件来定义多个容器的配置。在该文件中,你可以配置:
- 使用的Docker镜像
- 启动的容器数目
- 容器之间的依赖关系
- 容器间的网络连接
- 数据卷的挂载
- 服务的环境变量等
当你运行 docker compose up命令时,docker-compose会读取docker-compose.yml文件中的配置,自动创建所有需要的容器、网络、数据卷等资源,并将它们连接在一起,完成整个应用的部署。
2. docker-compose安装步骤
**注:**首先在这里说明一下在Windows/Mac 系统中只需要成功安装Docker Desktop即可正常使用docker-compose,Docker Desktop已经包含了docker-compose,博主之前开发项目时,因为需要运行chirpstack,所以安装过Docker Desktop。在Windows或Mac系统上 如何安装Docker Desktop就不说是怎么装的了,想要在Windows/Mac上安装Docker Desktop的博友们,可以去自己百度查询安装的方法。
2.1 官方文档推荐安装方式
(1)下载docker-compose
执行下方的命令进行下载
curl -L \"https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose
如果下载的速度很慢,可以使用如下的命令
curl -L \"https://mirror.ghproxy.com/https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose
(2)修改目录权限
chmod +x /usr/local/bin/docker-compose
(3)创建软连接
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
说明
ln
: 这是 Linux 中用于创建硬链接或符号链接的命令。-s
: 这个选项表示创建的是符号链接(软链接),而不是硬链接。符号链接类似于 Windows 系统中的快捷方式,指向另一个文件或目录。/usr/local/bin/docker-compose
: 这是源文件路径,即你希望链接到的实际docker-compose
可执行文件的位置。/usr/bin/docker-compose
: 这是目标路径,即在系统路径中更靠前的位置创建一个指向docker-compose
的链接。
为什么需要这样做?
在 Linux 系统中,/usr/bin
通常在 PATH
环境变量的优先级上高于 /usr/local/bin
。因此,将 /usr/local/bin/docker-compose
创建一个符号链接到 /usr/bin/docker-compose
可以确保当你运行 docker-compose
命令时,系统会优先使用 /usr/local/bin
下的版本,而不是可能存在旧版本的 /usr/bin
下的版本。
(4)验证安装是否完成
执行如下命令,如果能够正常显示出版本号,则表示已经完成
docker-compose --version
上述是在线安装的步骤,也可以去github下载docker-compose进行离线安装,地址:https://github.com/docker/compose/releases?page=1 , 离线安装的第1步就是下载好的docker-compose-linux-x86_64 文件上传到/usr/local/bin/目录,然后安装上面的第(2) (3) (4)步操作即可
2.2 使用pip install方式进行安装
因为docker-compose是使用python语言开发的,因此可以通过pip install的方式进行安装
(1)首先需要确保pip已经安装完成,如果没有安装python,可以通过 yum install -y python3命令进行安装,CentOS7默认的yum仓库中包含Python 3.6,如下图所示:运行yum install -y python3命令安装完成后的版本的是3.6.8,如果想要安装比yum仓库中更新的Python版本,可以从源码编译安装。
(2)升级pip版本
python3 -m pip install --upgrade pip
(3)安装docker-compose
pip3 install docker-compose
(4)安装完成后,验证是否安装成功
docker-compose --version
注:2.1和2.2 描述的两种安装方式任选一种即可
3. 使用docker-compose部署若依前后端
3.1 基本语法
例:使用docker部署MySQL的命令如下:
docker run -d \\ --name mysql \\ --restart always \\ -p 23306:3306 \\ -e MYSQL_DATABASE=ry-vue \\ -e MYSQL_ROOT_PASSWORD=root \\ -e MYSQL_ROOT_HOST=% \\ -e TZ=Asia/Shanghai \\ -v $(pwd)/mysql/data:/var/lib/mysql \\ --network ruoyi \\ mysql:8.0.27 \\ --lower_case_table_names=1
上述命令的相关解释
-
-d
: 后台运行容器。 -
--name mysql
: 为容器指定名称为mysql
。 -
--restart always
: 设置容器在退出时总是重启。 -
-p 33306:3306
: 将主机的33306
端口映射到容器的3306
端口。 -
-e MYSQL_DATABASE=ry-vue
: 设置环境变量MYSQL_DATABASE
为ry-vue
。 -
-e MYSQL_ROOT_PASSWORD=root
: 设置环境变量MYSQL_ROOT_PASSWORD
为root
。 -
-e MYSQL_ROOT_HOST=%
: 设置环境变量MYSQL_ROOT_HOST
为%
,允许所有主机连接。 -
-e TZ=Asia/Shanghai
: 设置时区为Asia/Shanghai
。 -
-v $(pwd)/mysql/data:/var/lib/mysql
: 将当前目录下的mysql/data
目录挂载到容器的/var/lib/mysql
目录,用于持久化数据。 -
--network ruoyi
将容器连接到名为ruoyi的自定义网络。如果该网络不存在,需要先创建它:docker network create ruoyi
-
mysql:8.0.27
: 使用mysql
镜像的8.0.27
版本。 -
--lower_case_table_names=1
: 这是传递给 MySQL 启动命令的参数,用于设置表名不区分大小写。
如果使用docker-compose.yml文件来定义,如下所示:
version: \"3\"services: mysql: container_name: mysql image: mysql:8.0.27 restart: always ports: - \"23306:3306\" command: --lower_case_table_names=1 environment: MYSQL_DATABASE: ry-vue MYSQL_ROOT_PASSWORD: root MYSQL_ROOT_HOST: \'%\' TZ: Asia/Shanghai volumes: - ./mysql/data:/var/lib/mysql networks: - ruoyinetworks: ruoyi: name: ruoyi
对比效果:
理解了对应的关系,就可以知道这个docker-compose.yml文件应该如何写了。
在编写docker-compose.yml
前,先准备好redis-dockerfile、mysql-dockerfile、nginx-dockerfile、ruoyi-dockerfile
redis-dockerfile
# 基础镜像FROM redis:5.0.14# 挂载目录VOLUME /home/ruoyi/redis# 创建目录RUN mkdir -p /home/ruoyi/redis# 指定路径WORKDIR /home/ruoyi/redis# 复制conf文件到路径COPY ./conf/redis.conf /home/ruoyi/redis/redis.conf
mysql-dockerfile
# 基础镜像FROM mysql:8.0.27# 执行sql脚本ADD ./db/*.sql /docker-entrypoint-initdb.d# 注意:MySQL 容器在首次启动时会自动执行 /docker-entrypoint-initdb.d/ 目录下的 SQL 脚本,但在后续启动时不会重复执行这些脚本。这是因为 MySQL 容器在首次启动并执行完初始化脚本后,会将数据库的状态保存到数据卷(通常是绑定挂载的主机目录或 Docker 卷)中。在后续启动时,容器会检测到数据库已经存在,并跳过初始化步骤。
nginx-dockerfile
# 基础镜像FROM nginx:1.22.0# 挂载目录VOLUME /home/ruoyi/web/ruoyi-ui# 创建目录RUN mkdir -p /home/ruoyi/web/ruoyi-ui# 指定路径WORKDIR /home/ruoyi/web/ruoyi-ui# 复制conf文件到路径COPY ./conf/nginx.conf /etc/nginx/nginx.conf# 复制html文件到路径COPY ./html/dist /home/ruoyi/web/ruoyi-ui
相关解释
使用nginx:1.22.0作为基础镜像。
VOLUME /home/ruoyi/web/ruoyi-ui
:这是创建一个挂载点,将主机的目录 /home/ruoyi/web/ruoyi-ui
与容器内的目录进行挂载,实现主机和容器之间的文件共享。
RUN mkdir -p /home/ruoyi/web/ruoyi-ui
:这是在容器内创建一个目录 /home/ruoyi/web/ruoyi-ui
。使用 -p
参数可以递归创建目录,如果目录已存在则不会报错。
WORKDIR /home/ruoyi/web/ruoyi-ui
:这是指定容器的工作目录为 /home/ruoyi/web/ruoyi-ui
,后续的指令都会在该目录下执行。
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
:这是将主机当前目录的 ./conf/nginx.conf
文件复制到容器内的 /etc/nginx/nginx.conf
路径下。这样做是为了将主机上的 Nginx 配置文件复制到容器内,以便在容器中使用自定义的 Nginx 配置。
COPY ./html/dist /home/ruoyi/web/ruoyi-ui
:这是将主机当前目录的 ./html/dist
目录复制到容器内的 /home/ruoyi/web/ruoyi-ui
路径下。这样做是为了将主机上的静态 HTML 文件复制到容器内,以供 Nginx 服务器提供静态网页服务。
这样,使用该镜像创建的容器就可以运行 Nginx 服务器,并提供指定的配置和静态网页。
ruoyi-dockerfile
# 基础镜像FROM openjdk:8-jre# 挂载目录VOLUME /home/ruoyi# 创建目录RUN mkdir -p /home/ruoyi# 指定路径WORKDIR /home/ruoyi# 复制jar文件到路径COPY ./jar/*.jar /home/ruoyi/ruoyi-admin.jar# 启动应用ENTRYPOINT [\"java\",\"-jar\",\"ruoyi-admin.jar\"]
docker-compose.yml
version: \'3\'services: ruoyi-redis: container_name: ruoyi-redis restart: always build: context: . dockerfile: redis-dockerfile ports: - \"26379:6379\" volumes: - ./conf/redis.conf:/home/ruoyi/redis/redis.conf - ./redis/data:/data command: redis-server /home/ruoyi/redis/redis.conf ruoyi-mysql: container_name: ruoyi-mysql restart: always build: context: . dockerfile: mysql-dockerfile ports: - \"23306:3306\" command: [ \'mysqld\', \'--innodb-buffer-pool-size=80M\', \'--character-set-server=utf8\', \'--collation-server=utf8_general_ci\', \'--default-time-zone=+8:00\', \'--lower_case_table_names=1\' ] environment: MYSQL_DATABASE: \'ry-vue\' MYSQL_ROOT_PASSWORD: root MYSQL_ROOT_HOST: \'%\' TZ: Asia/Shanghai volumes: - ./mysql/conf:/etc/mysql/conf.d - ./mysql/logs:/logs - ./mysql/data:/var/lib/mysql ruoyi-server: container_name: ruoyi-server restart: always build: context: . dockerfile: ruoyi-dockerfile volumes: - ./ruoyi/logs:/home/ruoyi/logs - ./ruoyi/uploadPath:/home/ruoyi/uploadPath ports: - \"28080:8080\" depends_on: - ruoyi-redis - ruoyi-mysql ruoyi-nginx: container_name: ruoyi-nginx restart: always build: context: . dockerfile: nginx-dockerfile ports: - \"286:86\" volumes: #- ./html/dist:/home/ruoyi/web/ruoyi-ui - ./conf/nginx.conf:/etc/nginx/nginx.conf - ./nginx/logs:/var/log/nginx #- ./nginx/conf.d:/etc/nginx/conf. depends_on: - ruoyi-server
注:compose与docker的兼容性
3.2 基础命令
编写好docker-compose.yml文件,就可以部署了。语法如下:
docker compose [OPTIONS] [COMMAND]
其中,OPTIONS和COMMAND都是可选参数,比较常见的有:
3.3 部署演示
3.3.1 前端打包上传
(1)修改前端项目ruoyi-ui的vue.config.js中的devServer: 下的代理部分的host为docker-compose.yml中的前端服务名称,修改了target对应的IP为docker-compose.yml中的后端服务名称。
注意: 写成服务名称的好处:以后如果迁移到别的服务器上,只要使用docker compose运行,就可以运行起来
(2)打包前端项目:进入 ruoyi-ui 目录,运行npm run build:prod命令或者通过WebStorm打开这个项目前端并找到package.json文件 点击\"build:prod\"左侧的绿色小箭头来打包前端项目。这将生成一个 dist 目录,其中包含了打包后的前端静态文件。
(3) 将打包好的dist 打包成zip文件 上传到服务器的指定目录即可(比如博主将这个dist上传到了/home/dxl/docker-compose-ruoyi/html
目录下),然后运行unzip dist.zip命令解压文件,如果运行后出现-bash: unzip: command not found
这个错误则表示需要安装unzip,安装的命令是yum install unzip(如果是在非root账户下操作需要在 yum 前面需要加上sudo )
3.3.2 后端打包上传
(1)找到ruoyi-admin包下的两个配置文件,文件路径如下所示:
(2)修改application.yml文件,把redis的host改成docker-compose.yml中定义的redis服务名称
(3)修改application-druid.yml文件,把原本的localhost改成docker-compose.yml中定义的mysql服务名称
(4)对文件进行打包,在本地打包后端完成,target目录下会出现一个jar包,如下所示: 然后将jar包上传到服务器的目录。博主上传到了 /home/dxl/docker-compose-ruoyi/jar目录下
3.3.3 数据库文件上传
(1)将若依项目中sql文件夹下提供的两个sql脚本文件上传到服务器,博主上传到了 /home/dxl/docker-compose-ruoyi/db目录下
(2)上传完成后,分别在两个SQL脚本文件添加 SET NAMES \'utf8\'
, 防止导入SQL脚本后出现中文乱码的情况。
3.3.4 在 conf文件夹下添加nginx.conf和redis.conf文件
nginx.conf
#user nobody;worker_processes 1;#error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info;#pid logs/nginx.pid;events { worker_connections 1024;}http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 86; server_name localhost; client_max_body_size 10m; location / { root /home/ruoyi/web/ruoyi-ui; index index.html index.htm; try_files $uri $uri/ /index.html; } location /prod-api/ {proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://ruoyi-server:8080/; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }}
redis.conf
# requirepass 123456
这两个conf 前面已经说明了 是将主机当前目录下的conf 目录复制到容器内的路径下
3.3.5 运行命令创建并启动所有service容器
(1)相关命令如下:
docker-compose up -d
(2)执行完成后,使用docker ps -a
命令查看 容器是否已经全部启动,如果状态全部为up则表示启动成功
(3)启动成功后,会生成4个文件夹,如下图所示:
(4)然后通过浏览器访问部署完成的项目,如果成功访问则表示部署成功。如下图所示:系统可以正常登录访问、正常的发出请求和接收响应数据。