介绍
Docker Compose是一个用于定义和运行多个Docker容器的工具。它使用YAML文件来配置应用程序的服务、网络和卷等方面的设置。通过编写一个docker-compose.yml文件,可以定义多个容器之间的关系、环境变量、端口映射等。然后,使用docker-compose命令可以轻松地启动、停止和管理这些容器。
Docker Compose简化了多容器应用程序的部署和管理过程,使得开发人员可以更方便地定义和管理复杂的应用程序堆栈,非常适合部署中小型项目。第一次部署项目时步骤会稍多一些,但当你熟悉整个流程后,再次部署完整的前后端分离项目便只是几分钟的事!这将大大提高我们维护项目和重新部署的效率。
一、环境准备
1.操作系统
本次部署服务器使用 Linux + Centos7
2.文件准备
①数据库的SQL文件
②Spring Boot项目打包产物
③Vue项目打包产物
本次部署的项目名称:reggie
由于本人不习惯在黑窗口编辑较长的配置文件,所以,我一般都把配置文件(docker-compose.yml、nginx.conf 等)用vscode编辑好,然后再用FTP传输工具(本人用的是filezilla)上传到到对应的文件目录,新手也可以像我这样干😂
二、软件安装
1.安装 docker
参考教程:Centos7安装Docker_centos8安装docker_玩物丧志的快乐的博客-CSDN博客
2.安装 docker-compose
①下载,在终端输入命令:
curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
②给docker-compose执行权限
chmod +x /usr/local/bin/docker-compose
③检查版本并查看是否安装成功
docker-compose -v
如上图,输出版本号,即安装成功!
三、创建数据卷(volume)
作用:将容器内的数据与宿主机进行持久化存储和共享。数据卷可以在容器之间共享数据,也可以在容器被删除后保留数据。通过使用数据卷,可以实现容器的数据持久化,使得容器可以在不同的主机之间迁移而不丢失数据。
1.在/usr/local目录下新建一个目录projects,以后把我们的项目文件都存放在这里
mkdir /usr/local/projects
2.创建数据卷
docker volume create projects_volume \
-d local \
-o type=none \
-o o=bind \
-o device=/usr/local/projects
具体参数的含义如下:
-
"-d local":指定使用本地驱动程序来创建数据卷。
-
"-o type=none":指定数据卷类型为"none",即不使用特定的存储后端。
-
"-o o=bind":指定数据卷的挂载选项为"bind",表示将数据卷与宿主机目录进行绑定。
-
"-o device=/usr/local/projects":指定数据卷绑定的宿主机目录为"/usr/local/projects"。
我创建了一个名为"projects_volume"的数据卷,并将它与宿主机上的"/usr/local/projects"目录进行绑定。这样,在运行容器时,可以将该数据卷挂载到容器内的指定路径,实现数据的持久化和共享。
查看Docker中的所有数据卷
docker volume ls
四、创建共享网络(network)
作用:为容器提供网络连接和通信的功能。Docker网络允许容器之间进行通信,以及与外部网络进行交互。本次项目,后端需要连接数据库,前端需要请求后端接口,由于都分别部署在不同的容器中互相隔离,需要用 network 进行容器之间通信。而实现只需要把这三个容器同时接入同一个网络即可,但需要修改Spring Boot项目的生产配置文件以及Nginx的配置文件,后面会细说。
输入创建共享网络命令:
docker network create reggie_network
我创建了一个新的Docker网络,名称为"reggie_network"。接下来我会把分别部署了MySQL、Spring Boot 、Nginx的三个容器连接到这个网络,以便它们可以在同一网络中进行通信。
查看Docker中的所有网络
docker network ls
五、修改配置文件
1.修改 Spring Boot项目的生产配置并重新打包
① 修改application-prod.yml
因为MySQL数据库和Spring Boot项目分别部署在不同的容器中,因此需要通过网络连接来进行通信。在Docker容器中,可以使用容器名称作为主机名来进行网络通信。mysql-container
在这里是指MySQL容器的名称(该容器目前尚未创建,后面会通过docker-compose创建),Spring Boot容器将使用这个名称来连接到MySQL容器。
注意:容器名称不要带有_(下划线),因为容器在通信时会把mysql-container当成域名解析!在域名中使用下划线是非法的!可以使用 - 进行分隔,本人已踩坑。
② 重新打包
2.准备一个Nginx配置文件(nginx.conf),并修改
查看前端Vue项目生产配置(.env.production)请求的baseUrl如下图所示:
在nginx.conf 中对server模块进行以下修改:
nginx.conf 完整配置如下:
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 开启GZIP压缩
gzip on;
gzip_buffers 32 4K;
gzip_comp_level 6;
gzip_min_length 100;
gzip_types application/javascript text/css text/xml;
#配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
gzip_disable "MSIE [1-6]\.";
gzip_vary on;
server {
listen 80;
server_name reggie;
location / {
# Vue项目文件的存的路径
root /usr/local/projects/reggie/reggie_vue/dist;
try_files $uri $uri/ /index.html;
# index index.html index.htm;
}
# 配置反向代理 后端接口
location ^~/api/ {
# reggieboot-container 为Spring Boot项目的容器名称
proxy_pass http://reggieboot-container:8080/;
}
# 配置反向代理 图片资源
location ^~/reggie_images/ {
# reggieboot-container 为Spring Boot项目的容器名称
proxy_pass http://reggieboot-container:8080/reggie_images/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
六、项目部署
1.在/usr/local/projects(前面已创建数据卷与宿主机该文件夹进行关联)文件夹下创建一个新文件夹reggie用来存放本次项目的文件
mkdir /usr/local/projects/reggie
随后在reggie文件夹中创建四个文件夹存放对应的项目文件 ,我这里直接用FTP工具创建。
2.使用FTP工具上传Vue项目打包产物dist到 reggie_vue目录中
3. 使用FTP工具上传Spring Boot项目打包产物reggie_boot-0.0.1-SNAPSHOT.jar到 reggie_boot目录中
4.在reggie_boot目录中上传或编写构建Srping Boot项目镜像的Dockerfile文件,我这里命名为reggieboot_dockerfile
# 使用基础镜像为Java 8
FROM java:8
# 添加作者信息
LABEL maintainer Huangbr <hbr1174234009@163.com>
# 将本地的reggie_boot-0.0.1-SNAPSHOT.jar文件复制到镜像中,并重命名为reggie_boot.jar
ADD reggie_boot-0.0.1-SNAPSHOT.jar reggie_boot.jar
# 定义容器启动时要执行的命令,运行Java应用程序reggie_boot.jar
CMD java -jar reggie_boot.jar
5.在root目录下创建docker-compose文件夹并进入
mkdir /root/docker-compose
cd /root/docker-compose
6.在docker-compose目录下,创建一个新文件夹reggie用来存放本次项目的文件配置,并进入文件夹
mkdir reggie
cd reggie
7.在reggie目录中上传或编写docker-compose.yml(不能改文件名)
详细配置如下:
version: '3'
services:
# MySQL容器配置
mysql-container:
image: mysql:5.7
restart: always
ports:
- 3307:3306
environment:
# 设置MySQL的root用户密码
MYSQL_ROOT_PASSWORD: 123456
# 设置时区为亚洲/上海
TZ: Asia/Shanghai
# 创建名为reggie的数据库
MYSQL_DATABASE: reggie
# 设置MySQL字符集为utf8mb4
MYSQL_CHARSET: utf8mb4
# 设置MySQL排序规则为utf8mb4_unicode_ci
MYSQL_COLLATION: utf8mb4_unicode_ci
volumes:
# 将MySQL数据目录挂载到主机的/root/docker-compose/mysql/reggie_data目录
- /root/docker-compose/mysql/reggie_data:/var/lib/mysql
networks:
# 将容器连接到名为reggie_network的网络
- reggie_network
# Reggie Boot容器配置
reggieboot-container:
build:
# 指定构建上下文为/usr/local/projects/reggie/reggie_boot目录
context: /usr/local/projects/reggie/reggie_boot
# 指定Dockerfile为reggieboot_dockerfile
dockerfile: reggieboot_dockerfile
restart: always
ports:
# 将主机的9090端口映射到容器的8080端口
- 9090:8080
volumes:
# 将主机的projects_volume卷挂载到容器的/usr/local/projects目录
- projects_volume:/usr/local/projects
networks:
# 将容器连接到名为reggie_network的网络
- reggie_network
depends_on:
# 依赖于mysql-container容器
- mysql-container
# Reggie Vue容器配置
reggievue-container:
image: nginx:latest
restart: always
ports:
# 将主机的80端口映射到容器的80端口
- 80:80
volumes:
# 将主机的projects_volume卷挂载到容器的/usr/local/projects目录
- projects_volume:/usr/local/projects
# 将主机的./nginx.conf文件挂载到容器的/etc/nginx/nginx.conf文件
- ./nginx.conf:/etc/nginx/nginx.conf
networks:
# 将容器连接到名为reggie_network的网络
- reggie_network
depends_on:
# 依赖于reggieboot-container容器
- reggieboot-container
networks:
# 定义名为reggie_network的网络
reggie_network:
volumes:
# 定义名为projects_volume的卷
projects_volume:
# 使用外部卷
external: true
这里我故意改了MySQL和Sring Boot的端口,用来测试端口的对应关系,各位可以根据实际情况自行修改,别忘记防火墙要开放对应端口,使用云服务器的话还要配置安全组。
8.上传第五章节中修改过后的nginx.conf 到/root/docker-compose目录下
9.至此,所有文件准备完毕
最后检查一次所有文件:
10.启动容器
cd /root/docker-compose/reggie
# 启动容器 -d表示后台运行,第一次测试部署时可以先不加,用以查看日志
docker-compose up -d
当你运行docker-compose up -d
命令时,docker-compose
会解析你的docker-compose.yml文件,并根据其中的定义创建和启动容器。容器将在后台运行,并且你可以继续使用终端进行其他操作,而不会被容器的输出所干扰。
请注意,你需要在包含docker-compose.yml文件的目录中运行该命令!
由控制台输出日志来看,一切正常,容器已经启动。
查看容器和镜像列表:
docker ps -a
docker images
可以看到新增启动了三个名称以 reggie 开头的容器,还有以reggie开头的镜像!
10.连接MySQL(这里我用Navicat连接主机的3307端口),在数据库reggie中导入SQL文件数据
如下图所示,可以看到/root/docker-compose目录中多了个mysql文件夹
点开文件夹,其中就有reggie项目的数据,如下图所示
七、打开浏览器测试项目
在浏览器输入服务器的ip地址,默认80端口,打开已经看到登陆页面,说明Nginx部署成功!
登录成功!说明Mysql 和 Spring Boot 的容器也正常工作了!接下来我们测试一个包含上传图片的修改功能!
可以看到,经过测试,功能没有问题。而且查看主机目录也能看到上传的图片文件,说明容器内部已经通过数据卷与宿主机的文件夹成功关联,大功告成!
八、项目维护与重新部署
当我们的项目修复Bug、增加、修改功能后,需要进行重新部署。此时只需要分别把前后端项目的打包产物通过FTP传输工具进行替换,数据库如果需要修改就修改,然后通过下面的命令即可直接完成部署。
cd /root/docker-compose/reggie
# 停止所有容器并移除所有容器
docker-compose down
# 构建、创建、启动容器并在后台运行
docker-compose up -d
是不是非常简单快捷?!😎
九、部署多个项目
用docker-compose部署多个项目其实非常简单,只需要每个项目准备好一个docker-compose.yml文件以及其它用到的配置文件,最后在每个项目中分别运行启动容器的命令就可以了。
在本章节,我将示范用docker-compose再部署一个名为hello的项目,启动一个Nginx容器,让用户访问其中的网页,步骤如下:
1.在/usr/local/projects目录下新建一个hello的项目文件夹并进入
cd /usr/local/projects
mkdir hello
cd hello
2.写一个简单的index.html,并上传到该目录中
3.在/root/docker-compose目录下新建一个hello文件夹并进入
cd /root/docker-compose
mkdir hello
cd hello
4.上传或编写hello项目的配置文件(nginx.conf 和 docker-compose.yml)
nginx.conf 配置如下:
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name hello;
location / {
# 前端页面访问路径
root /usr/local/projects/hello;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
docker-compose.yml 配置如下:
version: '3'
services:
hello-container:
image: nginx:latest
restart: always
ports:
- 3030:80
volumes:
- projects_volume:/usr/local/projects
- ./nginx.conf:/etc/nginx/nginx.conf
volumes:
projects_volume:
external: true
5.启动项目
docker-compose up -d
如图所示,启动成功!
查看容器列表:
docker ps -a
可以看到多了个名称以hello开头的容器,并且映射到宿主机的3030端口
6.开放防火墙端口
由于我的服务器没有开放3030端口,访问网页需要先开放该端口允许外界访问
# 开放3030端口
firewall-cmd --zone=public --add-port=3030/tcp --permanent
# 重新加载配置
firewall-cmd --reload
# 查看所有开放的端口
firewall-cmd --list-ports
设置成功!
7.访问hello项目的网页
打开浏览器输入主机IP地址加3030端口,可以看到页面,说明部署成功!
8.停止hello项目的容器
docker-compose down
查看容器列表:
docker ps -a
从上图中可以看到名称以hello项目的容器已经消失了,而reggie项目的容器还一直在运行中,说明不同项目的容器在启动和停止是互不影响的,可以说非常方便且易于维护。
十、常用docker-compose命令
docker-compose up [-d]:构建、创建并启动容器,-d 可选参数,表示后台启动
docker-compose down:停止并删除容器、网络和卷
docker-compose start:启动已创建的容器
docker-compose stop:停止已创建的容器
docker-compose restart:重启已创建的容器
docker-compose pause:暂停容器中的所有进程
docker-compose unpause:取消暂停容器中的所有进程
docker-compose ps:列出正在运行的容器
docker-compose logs:查看容器的日志输出
docker-compose exec:在容器中执行命令
docker-compose build:构建服务的镜像
docker-compose pull:拉取服务的镜像
docker-compose config:验证和查看 Compose 文件的配置
总结
使用docker compose部署的好处如下:
-
简化部署:Docker Compose 可以将多个容器组合在一起,通过一条命令快速部署整个应用程序。
-
管理容器:Docker Compose 可以方便地管理多个容器,包括启动、停止、删除等操作。
-
统一配置:Docker Compose 可以使用一个 YAML 文件来定义整个应用程序的配置,包括容器、网络、数据卷等。
-
灵活性:Docker Compose 可以根据需要启动、停止或重新部署单个容器,而不影响整个应用程序的运行。
-
可维护性:Docker Compose 可以帮助维护者更好地管理和维护应用程序,包括快速升级容器、改变配置、复制环境等。
总的来说,使用 Docker Compose 部署应用程序可以极大地简化管理和维护工作,提高工作效率和可维护性,同时也带来更好的可靠性和安全性。
创作不易,请小伙伴们帮我点个👍吧!!!