使用Docker Compose部署SpringCloud项目(详细)
服务器基础设置
这里使用的是Ubuntu 2核4G云服务器,服务器内存尽量在4g以上,不然docker能够负载的容器数量较低。使用xftp和xshell进行与服务器连接并传输文件。
(xftp和xshell下载地址家庭/学校免费 - NetSarang Website)
jdk>= 1.8 (推荐1.8版本)
从oracle官方网站上下载JDK,请注意jdk的版本一定要和要打包的后端服务版本保持一致,不然会报错。下载完成后,把文件通过WinSCP或者XFTP上传到服务器上。接着进行解压和配置环境变量。(jdk下载地址Java Downloads | Oracle)
下载后,使用xshell连接Ubuntu。新建目录
mkdir -p /data/tmp #传输的所有文件
mkdir -p /data/service #运行工具文件
xftp传输文件到刚刚新建的目录,进入安装包目录,解压。
cd /data/tmp
tar -zxvf jdk-8u441-linux-x64.tar.gz
如果xftp无法传输文件或者报错该目录Could not create folder,说明该文件没有写入的权限,需要开放该文件下所有读写权限。
sudo chmod -777 /data/tmp
解压后配置jdk环境变量
cd /data/tmp
mv jdk1.8.0_441 /data/service
#修改环境变量
vim /etc/profile#在profile文件中添加以下内容(如果没有写入权限同上操作该文件)
export JAVA_HOME=/data/service/jdk1.8.0_441
export PATH=$PATH:$JAVA_HOME/bin
#使环境变量生效
source /etc/profile
java -version
maven
从Maven官方网站上下载最新版的压缩包。(下载地址 https://maven.apache.org/download.cgi)
cd /data/tmp
tar -zxvf apache-maven-3.9.9-bin.tar.gz
mv apache-maven-3.9.9 /data/service/
#修改环境变量/etc/profile
export MAVEN_HOME=/data/service/apache-maven-3.9.9
export PATH=$PATH:$MAVEN_HOME/bin
#使环境变量生效
source /etc/profile
mvn -v
Docker与Docker Compose
docker容器化技术使我们免去了在服务器中配置数据库,环境等等复杂却不重要的操作,对于单体项目来说,docker容器完全够用,但如果我们开发的是springcloud集群项目,每一个子服务都需要进行一次docker打包和部署,如果手动去操作,是非常耗费时间的,如果有了compose只需要一个配置文件就可以帮我们搞定。通过以下代码进行doker和compose的部署。
#安装必要支持
sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release
#添加 Docker 官方 GPG key
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
#添加 apt 源:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
#安装docker 和docker compose
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
#验证是否安装成功
sudo systemctl status docker
由于Docker默认使用Docker Hub,但因为服务器在国外,国内用户下载镜像速度慢,拉取镜像速度更慢。接下来我们需要替换docker镜像源。
#新建该文件夹
sudo mkdir -p /etc/docker
#使用vim编辑该文件
sudo vim /etc/docker/daemon.json
#复制以下内容到该json文件下
{
"registry-mirrors" : ["https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc",
"https://do.nark.eu.org",
"https://dc.j8.work",
"https://dockerproxy.com",
"https://gst6rzl9.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"http://mirrors.ustc.edu.cn/",
"https://mirrors.tuna.tsinghua.edu.cn/",
"http://mirrors.sohu.com/",
"https://docker.1ms.run"
],
"insecure-registries" : [
"registry.docker-cn.com",
"docker.mirrors.ustc.edu.cn"
],
"debug": true,
"experimental": false
}
以上便完成了docker容器的配置,接下来我们验证是否换源成功
#重启服务
sudo systemctl daemon-reload && sudo systemctl restart docker
#测试
sudo docker pull hello-world
如果出现下图就代表着测试成功
SpringCloud项目打包
子服务信息
在开始项目打包之前,梳理所有的子服务信息,尤其是环境依赖的版本号。以下是我的项目信息。
服务名称 | 备注 | 端口号 | 版本号 | 服务类别 |
mysql | 数据库 | 3306 | v8 | 环境依赖 |
redis | 缓存 | 6379 | v6 | 环境依赖 |
nacos | 注册中心 | 8848 | v2.23 | 环境依赖 |
hrms_employee | 用户服务 | 8083 | 服务 | |
hrms_security | 认证服务 | 8080 | 服务 | |
hrms_gateway | 网关 | 88 | 服务 | |
hrms_oss | oss文件服务 | 8088 | 服务 | |
hrms_performance | 绩效服务 | 8091 | 服务 | |
hrms_recruitment | 招聘服务 | 8085 | 服务 | |
hrms_workflow | 工作流服务 | 8084 | 服务 |
pom.xml
对于父模块来说,pom.xml聚合所有子模块信息无任何需要改动的地方,删除所有内容只留下
org.springframework.boot
spring-boot-maven-plugin
repackage
repackage
Dockerfile
完成上述内容后,进行本地打包用来编写Dockerfile文件,该文件定义docker该如何初始化我们每一个服务的容器镜像。在maven的生命周期命令依次运行clean,package。对于每一个子服务target目录下生成本地jar包。随后在子服务的根目录下新建dockerfile文件。下面是项目结构。
Dockerfile的内容如下,请根据自己的子项目jar包名称进行相应的修改即可。
# 使用官方 Alpine 版本镜像
FROM openjdk:8-jdk-alpine
# 构建镜像时所需要执行的命令,这里在容器内部创建了一个工作目录
RUN mkdir "/home/app"
# 这里就是进入创建好的目录
WORKDIR "/home/app"
# 将打包后的jar包复制到指定目录(这里我是复制到了创建好的工作目录)下,并重命名
ADD target/hrms_workflow-0.0.1-SNAPSHOT.jar .
EXPOSE 8084
# 运行命令
CMD ["java","-jar","/home/app/hrms_workflow-0.0.1-SNAPSHOT.jar","--spring.prolfiles.active=prod"]
这里注意力惊人的小伙伴会发现,我定义的启动命令下使用的配置为prod,这是因为在服务上线后,相较于本地运行请求头不再是localhost而是服务器的公网ip,所以在本地调试的application.yml在线上环境是一定会报错的,我们需要为线上环境额外配置一份application-prod.yml文件。该文件与本地文件不同的地方如下:
也就是我们要将基础服务的请求头都换成mysql,nacos,redis这样的容器名称,去调用docker中相应的容器。
compose
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,可以使用 YML 文件来配置应用程序需要的所有服务。 在项目根目录下创建docker-compose.yml文件,其中内容定义构成应用程序的服务。
services:
# MySQL 服务
mysql:
image: mysql:8
container_name: mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "15312451532asdf"
MYSQL_DATABASE: hrms
volumes:
- mysql_data:/var/lib/mysql
- ./mysql-init:/docker-entrypoint-initdb.d
networks:
- app_network
# Redis 服务
redis:
image: redis:6
container_name: redis
ports:
- "6379:6379"
volumes:
- ./redis/conf/redis.conf:/data/HRMS/redis/redis.conf
- ./redis/data:/data/HRMS/redis/data
restart: always
command: redis-server /data/HRMS/redis/redis.conf
networks:
- app_network
# Nacos 服务
nacos:
image: nacos/nacos-server:v2.2.3-slim
container_name: nacos
ports:
- "8848:8848"
environment:
MODE: standalone
networks:
- app_network
# Spring Boot 服务组(通过 Dockerfile 构建)
# 这里只展示其中两个服务,其他服务请自行参考复制
hrms_employee:
build:
context: ./hrms_employee
dockerfile: DockerFile
container_name: hrms_employee
ports:
- "8083:8083"
environment:
SPRING_PROFILES_ACTIVE: prod
MYSQL_HOST: mysql
REDIS_HOST: redis
NACOS_HOST: nacos
depends_on:
- mysql
- redis
- nacos
networks:
- app_network
hrms_gateway:
build:
context: ./hrms_gateway
dockerfile: DockerFile
container_name: hrms_gateway
ports:
- "88:88"
environment:
SPRING_PROFILES_ACTIVE: prod
MYSQL_HOST: mysql
REDIS_HOST: redis
NACOS_HOST: nacos
depends_on:
- mysql
- redis
- nacos
networks:
- app_network
# 网络与卷定义
networks:
app_network:
driver: bridge
volumes:
mysql_data: # 声明命名卷
driver: local # 使用本地存储驱动(默认)
复制上述内容直接在服务器上运行docker compose命令会报错,需要一并修改如下内容。
redis
Redis 默认将 RDB 文件存储在 /etc/cron.d
或 /etc
目录,这些系统目录通常禁止写入。以及Linux 系统默认的 vm.overcommit_memory=0
限制了 Redis 的 fork()
操作,会导致 BGSAVE 失败。所以我们需要在服务器上修改vm.overcommit_memory=1.运行以下命令。
echo "vm.overcommit_memory=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
修正 RDB 存储路径,创建专用目录(推荐) ,在compose文件下添加redis挂载文件。(volumes中内容)。服务器上在redis-compose.yml文件所在路径下添加/redis/conf/redis.conf文件和/redis/data文件夹。
redis: image: redis:6 container_name: redis ports: - "6379:6379" volumes: - ./redis/conf/redis.conf:/data/HRMS/redis/redis.conf - ./redis/data:/data/HRMS/redis/data restart: always command: redis-server /data/HRMS/redis/redis.conf networks: - app_network
打开该文件redis.conf,将如下内容复制粘贴进去。
# 指定数据存储目录(必须与Docker Compose挂载目录一致)
dir /data
dbfilename dump.rdb
appendfilename "appendonly.aof"# 调整持久化策略(避免频繁生成文件)
save 3600 1
appendonly yes
mysql
在服务器上,数据本地持久化,避免容器停止或删除后数据丢失。需要修改dockerfiles文件mysql挂载。在项目根目录下添加mysql-init文件夹,放置sql文件。
mysql:
image: mysql:8
container_name: mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "密码"
MYSQL_DATABASE: hrms
volumes:
- mysql_data:/var/lib/mysql
- ./mysql-init:/docker-entrypoint-initdb.d
networks:
- app_network
项目上传
接下里进入idea开发环境进行项目打包上传至云服务器。按照如下步骤:
点击add添加,选择SFTP连接,输入连接名(随便)。进入如下界面
在SSH configuration点击添加新的连接,输入自己的服务器账号密码添加连接。
随后点击Mapping,添加本地项目和服务器上的文件映射,也就是希望项目上传至服务器哪个文件中。至此配置完毕。我们可以选择打包后上传,也可以直接上传项目文件在服务器上打包。我这里选择上传项目文件,在服务器上打包。先进行maven clean。右键根目录xxx->Deployment ->Upload to XXX, 将项目上传至服务器。
项目部署
接下来就到了最激动人心的项目部署了。进入到项目目录,运行package进行项目打包部署。
cd /data/HRMS
#跳过单元测试直接打包
mvn package -DskipTests
#项目部署
sudo docker compose deocker-compose.yml up -d
deocker-compose.yml为在项目根目录下编写的composeyml文件的文件名称, -d为后台运行。deocker-compose也支持只部署其中一个服务
#部署其中一个服务,xxx为服务名称
sudo docker compose deocker-compose.yml up xxx -d
运行成功后,可以使用sudo docker logs xxx,查看该服务的打印结果看其是否正常启动。sudo docker stop xxx,停止该服务,sudo docker rm xxx,删除服务。以上就是全部的项目打包部署流程了。