使用 docker 在 centos8 下部署一个 springboot+vue 应用程序,使用的容器有 springboot、mysql、redis、nginx。包含 springboot 镜像构建 Dockerfile、bridge 容器互联、目录映射等内容。
基础环境#
- 开启 centos 防火墙端口转发
firewall-cmd --add-masquerade --permanent
- 重启防火墙
firewall-cmd --reload
-
创建目录
根目录下创建 /data 文件夹,用于统一保存挂载到容器内的文件
- /data/redis/data:[目录] 保存 redis 持久化数据
-
/data/redis/redis.conf:[文件] redis 配置文件
- /data/nginx/html:[目录] nginx html 文件目录
-
/data/nginx/log:[目录] 日志
- /data/nginx/nginx/nginx.conf:[文件] nginx 配置文件
网络#
- 创建 docker 子网
docker network create --subnet 192.168.0.0/16 --gateway 192.168.0.1 docker-net
192.168.0.0/16:子网范围
192.168.0.1:网关地址
docker-net:子网名称
- 创建后查看
docker network inspect docker-net
[
{
"Name": "docker-net",
"Id": "1fc4884e63c593800fbbf263d10c09a8dadb52307096d57a5b2e80f84574ab90",
"Created": "2023-01-11T19:18:32.691672677+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
-
加入网络
-
在 docker 启动参数中加入
--net docker-net
-
容器启动之后,使用命令
docker network connect docker-net <容器ID/NAME>
-
redis#
- 下载 redis docker 镜像
docker pull redis
- 创建 redis 配置文件
vi redis.conf
- redis.conf 文件中写入
requirepass <你的redis密码>
- 启动 redis
docker run -d -p 6379:6379 --name docker-redis --restart always -v /data/redis:/etc/redis -v /data/redis/data:/data --net docker-net redis redis-server /etc/redis/redis.conf
-d:后台运行
-p:端口映射,宿主机 6379 端口映射到容器 6379 端口
--name:容器启动后的名字
--restart always:容器自动重启
-v:文件挂载将容器内目录挂载到宿主机,左边是宿主机地址,右边是容器内地址
--net docker-net:加入 docker 子网
- 启动后使用
docker ps -a
查看容器是否正常启动
MySQL#
- 获取镜像
docker pull mysql:8.0.25
":" 用于指定 MySQL 版本
- 启动 mysql 容器
docker run -d -p 3306:3306 --name d-mysql --net docker-net --restart always -e MYSQL_ROOT_PASSWORD=mysqlpwd -e MYSQL_USER=violet -e MYSQL_PASSWORD=Dd112211 mysql:8.0.25
-e MYSQL_ROOT_PASSWORD=mysqlpwd:-e 表示自定义参数,root 用户密码
-e MYSQL_USER=violet:容器启动时创建一个用户
-e MYSQL_PASSWORD=Dd112211:该用户的密码
其他参数可以在docker hub mysql查看
- 设置用户权限
可以为容器启动时创建的用户赋予权限,或者让 root 用户可以远程登录
进入容器内
docker exec -it d-mysql /bin/bash
进入 mysql-client
mysql -uroot -p
设置 root 可以远程登录
grant all privileges on *.* to 'root'@'%';
刷新权限
FLUSH PRIVILEGES;
- 退出 mysql-client,退出 docker 容器
exit
- mysql 数据库数据导入 docker mysql
在 mysql-client 中执行
mysqldump -uroot -p --databases arrogant javawebsql my_blog springcloud vote_sys >/data/mysql/data-backup.sql
使用 mysqldump 来下载数据,保存在可执行的 sql 文件中
/data/mysql/data-backup.sql:目录及最后生成 sql 文件名字
--databases 和 目录之间的是需要转储的数据库名
将 sql 文件复制到 mysql 容器内
docker cp /data/mysql/data-backup.sql d-mysql:/home/
进入 mysql 容器,进入 mysql-client,执行命令,将数据写入,必须在 sql 文件目录下进入
source data-backup.sql
构建 springboot 镜像#
- application.yml 设置
数据库地址设置为 d-mysql,即 mysql docker 容器 name
url: jdbc:mysql://d-mysql:3306/my_blog?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
redis 地址设置为 d-redis
host: d-redis
- 在 src 目录下创建文件 Dockerfile
FROM openjdk:8
LABEL maintainer=lnbiuc
COPY ./*.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
- 上传文件
将 Dockerfile 和 jar 包放到同一个目录下
- 构建镜像
docker build -t api:8.8 .
-t:表示 tag 这里,这里指镜像版本,api 是镜像名字
.:点非常重要,表示在当前目录下构建
- 构建完成,查看镜像
docker images
- 启动容器
docker run -d -p 8888:8888 -v /data/api:/log --name api --net docker-net --restart always api:8.8.3
这里将 log 文件夹挂载出来方便查看,jar 包根目录,所以 log 文件夹也在同级的根目录下
Nginx#
- 拉取镜像
docker pull nginx
- 获取 springboot 访问地址
docker network inspect docker-net
输出
[
{
"Name": "docker-net",
"Id": "1fc4884e63c593800fbbf263d10c09a8dadb52307096d57a5b2e80f84574ab90",
"Created": "2023-01-11T19:18:32.691672677+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"00729e5b41d6ddcec195722869e57d1baf7bd754793cac7f986d452032b6810d": {
"Name": "d-redis",
"EndpointID": "2ea0446903341146ccc741aac0431ae3f3e0e6acc8972763f024136a3499a0ae",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"0682772aaec9f7d6bb435cf0d38e478c5298fa577783a226d086867d71bcf4b3": {
"Name": "d-nginx",
"EndpointID": "97dde4d3e0b8fff81722518b3b62094af5f0c1b1b484ef112c7db3490fb89ee7",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"27325e2b869eb28534e5a3e65de5eb8a650fa8488ded994de46cbb271af40a17": {
"Name": "d-gitea",
"EndpointID": "1a9ab8e968041b4df12ebaacecb74a166f23438cbba9b5345878c6fa672d982d",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
"bf2d1cf717fbc3a39c06068bba9638ad6ce49d407b3a6e28c196803188597038": {
"Name": "api",
"EndpointID": "34a832756b3c9c051d67e096f27448a80165407579de0a25877fe4d4e9f6e5d3",
"MacAddress": "02:42:c0:a8:00:05",
"IPv4Address": "192.168.0.5/16",
"IPv6Address": ""
},
"ebb72c81a769e9e8385cdbf910a5845ae3f53d8cd8e4d3d317046dd726b74947": {
"Name": "d-mysql",
"EndpointID": "c86a7becc085a4f47a35a8488b81bef771e0ae9f6eadd7e41d0db2beae3a8862",
"MacAddress": "02:42:c0:a8:00:06",
"IPv4Address": "192.168.0.6/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
其中 name 为 api 下的 IPv4Address 即使 nginx 需要反向代理的地址
- 准备好 ssl 证书和 nginx.conf 文件,放到 /data/nginx/nginx 目录下
我的 nginx.conf
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
# include enable-cors.conf
events {
worker_connections 1024;
}
http {
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
gzip on;
gzip_static on;
gzip_min_length 1k;
gzip_comp_level 7;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;
server {
listen *:80;
listen [::]:80;
server_name beyondhorizon.top;
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
server {
listen *:80;
listen [::]:80;
server_name www.beyondhorizon.top;
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
server {
listen *:443 ssl http2;
listen [::]:443 ssl http2;
server_name beyondhorizon.top www.beyondhorizon.top;
ssl on;
ssl_certificate beyondhorizon.top_bundle.crt;
ssl_certificate_key beyondhorizon.top.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
client_max_body_size 10m;
keepalive_timeout 70;
include /etc/nginx/default.d/*.conf;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location ~ /api/ {
add_header Cache-Control max-age=3600;
proxy_pass http://192.168.0.5:8888;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
- 上传 html 文件到 /data/nginx/html 下
- 启动 nginx
docker run -d -p 80:80 -p 443:443 -v /data/nginx/html:/usr/share/nginx/html -v /data/nginx/nginx:/etc/nginx -v /data/nginx/log:/var/log/nginx --name d-nginx --restart always --net docker-net nginx
- 后续如果修改了 nginx 配置文件,使用命令重启容器即可
docker restart d-nginx
此时全部容器都应该已经启动了,并且网站也可以正常访问啦