一、安装docker与docker-compose
二、docker安装mysql8(可跳过)
注意:如果想用docker-compose一键部署mysql,可跳过这步。我没跳是因为我的mysql安装是在这之前就安装了,并进行了一些配置文件的修改
三、创建文件夹
mkdir -p /docker/jar /docker/redis/data /docker/redis/conf /docker/nginx/html
/docker/nginx/conf /docker/nginx/cert /docker/nginx/log
各个文件夹功能及用处:
/docker/jar:存放jar包与DockerFile文件
/docker/redis/data:redis 数据存放地方,用于挂载卷(由于redis启动把文件没得权限错误,所以我把redis文件夹、data文件夹、conf文件夹、redis.conf文件都提高了读写权限777)
/docker/redis/conf:redis 配置文件存放地方,用于启动时加载配置问文件,并挂载卷。
/docker/nginx/log:nginx 日志存放地方
/docker/nginx/html:编译后前端文件存放地方。
/docker/nginx/conf:nginx 配置文件存放地方(把/docker/nginx文件夹读写权限提高777。猜测上面redis其实可能只用把/docker/redis文件夹提高权限就可以了,不用每个都提高。没尝试,懒得搞)
/docker/nginx/cert:ssl证书存放地址,用于配置https访问(注意:这两个证书是服务集群启动成功后再申请的,你服务都没启动成功,不能用http访问,配置https也没卵用)
注意:如果还是因为各种权限问题,直接提高/docker文件夹权限
chmod -R 777 /docker
四、部署步骤
0、新建ruoyi-vue数据库、执行sql(因为我是先单独运行的数据库,没有用docker-compose一键启动,所以我可以先执行这一步,如果想一键启动的看后面的教程)
在navicat里执行下面sql,数据库基本数据就准备好了
1、执行打包命令 maven clean package,并把打包好的jar包上传至刚才新建的/docker/jar文件夹
(记得修改数据库配置,redis配置,redis密码要与下面配置文件里的密码相同)
2、编写ruoyi-vue的DockerFile文件,上传至/docker/jar文件夹
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER YH
RUN mkdir -p /ruoyi/server
RUN mkdir -p /ruoyi/server/logs
RUN mkdir -p /ruoyi/server/temp
WORKDIR /ruoyi/server
ENV SERVER_PORT=8080
EXPOSE ${SERVER_PORT}
ADD ./ruoyi-admin.jar ./app.jar
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Dserver.port=${SERVER_PORT}","-jar", "app.jar"]
3. 构建镜像,执行命令
cd /docker/jar // 先进入jar包目录
docker build -t ruoyi-server:4.3.0 . //构建镜像tag为ruoyi-server:4.3.0的镜像,因为DockerFile就在当前文件夹里,所以不用加 -f 指定DockerFile文件所在地址。注意,命令有个点,表示当前文件夹
镜像构建成功
4.编写redis.conf配置文件,并上传至/docker/redis/conf (注意:该配置文件设置了redis登录密码的,不需要的自行修改)
# redis 密码
requirepass ruoyi_123456
# key 监听器配置
# notify-keyspace-events Ex
# 配置持久化文件存储路径
dir /redis/data
# 配置rdb
# 15分钟内有至少1个key被更改则进行快照
save 900 1
# 5分钟内有至少10个key被更改则进行快照
save 300 10
# 1分钟内有至少10000个key被更改则进行快照
save 60 10000
# 开启压缩
rdbcompression yes
# rdb文件名 用默认的即可
dbfilename dump.rdb
# 开启aof
appendonly yes
# 文件名
appendfilename "appendonly.aof"
# 持久化策略,no:不同步,everysec:每秒一次,always:总是同步,速度比较慢
# appendfsync always
appendfsync everysec
# appendfsync no
5.编写nginx.conf配置文件,并上传至/docker/nginx/conf
该配置文件有以下几个注意点
(1)worker_processes 2; //因为我是买的2核云服务器,所以配置2,有多少核配置多少工作线程
(2)该配置文件已经配置了https访问,并设置了域名访问。还有ssl证书。直接把下面那个监听443端口的server全部删除就是了。等后面在购买了域名,并申请了证书再加下面那个配置
(3)443端口server里配置了拦截除get请求、/login、/logout请求外所有请求。(演示模式:所有对数据库有增删改的操作都拦截)
(4) 从配置可以看出启动了两个服务,一个8080,一个8081,采用轮询机制(也可采用ip_hash、weight权重)
user root;
worker_processes 2;
# worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 限制body大小
client_max_body_size 100m;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
upstream server {
# 是根据用户请求过来的ip,然后映射成hash值,然后分配到一个特定的服务器里面;
# ip_hash;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
upstream monitor-admin {
server 127.0.0.1:9090;
}
upstream xxljob-admin {
server 127.0.0.1:9100;
}
server {
listen 80;
server_name localhost;
# https配置参考 start
#listen 443 ssl;
# 证书直接存放 /docker/nginx/cert/ 目录下即可 更改证书名称即可 无需更改证书路径
#ssl on;
#ssl_certificate /etc/nginx/cert/xxx.local.crt; # /etc/nginx/cert/ 为docker映射路径 不允许更改
#ssl_certificate_key /etc/nginx/cert/xxx.local.key; # /etc/nginx/cert/ 为docker映射路径 不允许更改
#ssl_session_timeout 5m;
#ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_prefer_server_ciphers on;
# https配置参考 end
# 演示环境配置 拦截除 GET POST 之外的所有请求
# if ($request_method !~* GET|POST) {
# rewrite ^/(.*)$ /403;
# }
# location = /403 {
# default_type application/json;
# return 200 '{"msg":"演示模式,不允许操作","code":500}';
# }
# 限制外网访问内网 actuator 相关路径
location ~ ^(/[^/]*)?/actuator(/.*)?$ {
return 403;
}
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
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://server/;
}
# https 会拦截内链所有的 http 请求 造成功能无法使用
# 解决方案1 将 admin 服务 也配置成 https
# 解决方案2 将菜单配置为外链访问 走独立页面 http 访问
location /admin/ {
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://monitor-admin/admin/;
}
# https 会拦截内链所有的 http 请求 造成功能无法使用
# 解决方案1 将 xxljob 服务 也配置成 https
# 解决方案2 将菜单配置为外链访问 走独立页面 http 访问
location /xxl-job-admin/ {
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://xxljob-admin/xxl-job-admin/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# 当输入为http时自动传成https
return 301 https://$host$request_uri;
}
server {
# https配置参考 start
listen 443 ssl;
server_name xxxx.com www.xxxx.com;
# 证书直接存放 /docker/nginx/cert/ 目录下即可 更改证书名称即可 无需更改证书路径
ssl on;
ssl_certificate /etc/nginx/cert/xxxx.crt; # /etc/nginx/cert/ 为docker映射路径 不允许更改
ssl_certificate_key /etc/nginx/cert/xxxx.key; # /etc/nginx/cert/ 为docker映射路径 不允许更改
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
# https配置参考 end
# 演示环境配置 拦截除 GET POST 之外的所有请求(过滤login与)
set $flag 0;
if ($request_method !~* GET) {
set $flag "${flag}1";
}
if ($request_uri !~* "/login") {
set $flag "${flag}2";
}
if ($request_uri !~* "/logout") {
set $flag "${flag}3";
}
if ($flag = "0123") {
rewrite ^/(.*)$ /403;
}
# if (($request_method !~* GET) & ($request_uri !~* "/login/")) {
# rewrite ^/(.*)$ /403;
# }
location = /403 {
default_type application/json;
return 200 '{"msg":"演示模式,不允许操作","code":500}';
}
# 限制外网访问内网 actuator 相关路径
location ~ ^(/[^/]*)?/actuator(/.*)?$ {
return 403;
}
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
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://server/;
}
# https 会拦截内链所有的 http 请求 造成功能无法使用
# 解决方案1 将 admin 服务 也配置成 https
# 解决方案2 将菜单配置为外链访问 走独立页面 http 访问
location /admin/ {
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://monitor-admin/admin/;
}
# https 会拦截内链所有的 http 请求 造成功能无法使用
# 解决方案1 将 xxljob 服务 也配置成 https
# 解决方案2 将菜单配置为外链访问 走独立页面 http 访问
location /xxl-job-admin/ {
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://xxljob-admin/xxl-job-admin/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
5.编写docker-compose.yml文件
因为我的mysql前面已经单独起动了,我的线上docker-compose.yml文件就没得mysql这一段
version: '3'
services:
mysql:
image: mysql:8.0.29
container_name: mysql
environment:
# 时区上海
TZ: Asia/Shanghai
# root 密码
MYSQL_ROOT_PASSWORD: root
# 初始化数据库(后续的初始化sql会在这个库执行)
MYSQL_DATABASE: ry-vue
ports:
- "3306:3306"
volumes:
# 数据挂载
- /docker/mysql/data/:/var/lib/mysql/
# 配置挂载
- /docker/mysql/conf/:/etc/mysql/conf.d/
command:
# 将mysql8.0默认密码策略 修改为 原先 策略 (mysql8.0对其默认策略做了更改 会导致密码无法匹配)
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
privileged: true
network_mode: "host"
nginx-web:
image: nginx:1.21.6
container_name: nginx-web
environment:
# 时区上海
TZ: Asia/Shanghai
ports:
- "80:80"
- "443:443"
volumes:
# 证书映射
- /docker/nginx/cert:/etc/nginx/cert
# 配置文件映射
- /docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
# 页面目录
- /docker/nginx/html:/usr/share/nginx/html
# 日志目录
- /docker/nginx/log:/var/log/nginx
privileged: true
network_mode: "host"
redis:
image: redis:6.2.7
container_name: redis
ports:
- "6379:6379"
environment:
# 时区上海
TZ: Asia/Shanghai
volumes:
# 配置文件
- /docker/redis/conf:/redis/config:rw
# 数据文件
- /docker/redis/data/:/redis/data/:rw
command: "redis-server /redis/config/redis.conf"
privileged: true
network_mode: "host"
ruoyi-server1:
image: ruoyi-server:4.3.0
container_name: ruoyi-server1
environment:
# 时区上海
TZ: Asia/Shanghai
SERVER_PORT: 8080
volumes:
# 配置文件
- /docker/server1/logs/:/ruoyi/server/logs/
privileged: true
network_mode: "host"
ruoyi-server2:
image: ruoyi-server:4.3.0
container_name: ruoyi-server2
environment:
# 时区上海
TZ: Asia/Shanghai
SERVER_PORT: 8081
volumes:
# 配置文件
- /docker/server2/logs/:/ruoyi/server/logs/
privileged: true
network_mode: "host"
先批量启动基础服务redis,nginx,mysql
docker-compose up -d mysql nginx-web redis
然后执行命令docker ps -a 查看基础服务是否都成功启动
如果发现有容器状态status为exit,使用docker logs 【容器id】查看该容器的启动日志,查看是什么原因导致启动不成功
最后,启动两个若依服务,实现分布式部署
docker-compose up -d ruoyi-server1 ruoyi-server2
再次执行docker ps -a查看是否所有服务都启动成功
6.浏览器输入ip:80访问系统,查看两个服务里的日志,查看是否轮询成功。
7.腾讯云购买域名 (B站由腾讯云教程)
8.申请ssl证书
9.下载证书,并把那两个文件扔进/docker/nginx/cert,同时修改nginx.conf,开启监听443接口等相关配置。开启https服务。(腾讯云一开始可以用域名访问,隔一会就会被拦截,不能用域名访问这是正常的,因为需要工信部备案)
上面那张图第6步就是下载ssl证书
10.个人备案,备案成功就可https访问了。
上面那张图第7步就是备案