Docker自动化部署和HTTPS认证
这篇文章主要记录一下如何实现项目的自动化集成部署,并且让docker容器支持HTTPS的访问。
解决哪些痛点问题
在个人开发项目的时候,我们希望自己写的项目网站能放到有公网IP的服务器上供每个人都可以浏览访问,但是服务器端通常会遇到一些问题:
端口问题:
比如A项目需要占用3000端口,B项目也需要,这个时候导致端口的冲突,就需要修改端口。而且记住端口也是一件很麻烦的事情,容易导致端口冲突问题。(本文只需要服务器开放80和443端口,通过ngixn代理其他docker容器,从而无需开启其他端口就可以访问到容器应用)
部署问题:
每次项目代码的小改动,都需要重新本地构建,连接服务器上传代码,这是非常麻烦的一件事情。(通过Jenkins自动化集成部署可以解决该问题)
HTTPS证书问题:
每个项目需要域名访问,比如api.admin.com对应的是api接口项目,front.admin.com对应前端项目,但是证书需要为每个域名单独申请,这就很费时费力了,而且每个证书都有时效性的,过期就需要手动更新,很麻烦(通过acme可以自动更新证书,并且是免费开源的)
碎片化:
服务器端存放的会比较碎片化,安装的软件会比较杂,容易导致软件之间的冲突,比如服务器安装的node环境是14,其中一个项目只能在node14才可以正常运行,另外一个则需要在node20环境才可以,或者一个项目放在微信云服务上,另外一个存放在某静态存放网站,这样有可能导致跨域问题,域名也无法统一。(使用一台服务器,利用Docker的隔离性恰好可以解决这个问题)
以上这些痛点问题,本文会搭建一个在服务端持续集成持续部署的环境,并使用Nginx代理支持https的访问。
服务端整体的架构与思路
先看一下服务端整体的架构图:

- 用户通过f
ront.example.com的域名访问服务 DNS会解析这个网址到指定的IP+80端口,也就是我们服务器公网的IPNginx接收到这个请求,通过conf配置文件,在内网里面找到这个Docker容器服务,并访问这个Docker容器(这个过程中,Nginx已经通过配置文件给链接加上https证书加密)Docker容器返回给Nginx,Nginx再通过443端口返回给用户。
准备
在开始之前,我们需要准备一下环境:
- 一台初始化的
centos7.8系统服务器(避免软件安装冲突) - 一个已经备案的域名(国内服务器域名需要备案)
服务器连接配置
开始前先配置一下服务器的连接方式:
修改默认端口:
连接服务器:
1 | ssh root@you ip |
修改端口,编辑sshd_config文件:
1 | vi /etc/ssh/sshd_config |
输入 i 编辑,把#去掉,把22改为想要的端口,最后:wq保存:
1 | Port 10024 |
然后需要执行这一句命令:(端口是刚才修改的端口)
1 | semanage port -a -t ssh_port_t -p tcp 10024 |
可能会得到一个错误,可以执行一下下面这句:
1 | yum whatprovides semanage |
1 | yum install -y policycoreutils-python |
最后再重新执行:
1 | semanage port -a -t ssh_port_t -p tcp 10024 |
查看SSH运行的端口:(不是必须执行)
1 | semanage port -l | grep ssh |
删除SSH端口:(不是必须执行)
1 | semanage port -d -t ssh_port_t -p tcp 22 |
重启SSH:
1 | service sshd restart |
重新连接服务器:(端口是刚才的端口)
1 | ssh -p 10024 root@your ip |
密钥方式连接服务器:
在本地电脑生成SSH Key,一直回车就可以:
1 | ssh-keygen |
在本地路径C:\Users\你的用户\.ssh下创建config文件:
1 | Host Test |
服务器cd ~/.ssh/目录,(一定要CD到这个目录,切勿直接在根目录直接使用下面命令,会导致这个文件不生效)编辑文件,到本地C:\Users\你的用户名\.ssh 找到公钥文件,把本地电脑的公钥文件id_rsa.pub复制进去,:wq保存:
1 | vi authorized_keys |
如果之前连接过服务器,格式化后再连接可能报错,可以先删除本地电脑这两个文件,这两个文件是历史连接的记录

至此,完成服务器的端口修改和使用密钥登录的操作
旧版安装docker
这个办法适合境外服务器操作,因为2024年6月初的时候,Docker的镜像无法正常pull了,所以按照这个办法会出现报错等问题,不推荐;(有新版的安装方式下面介绍)
该内容步骤具体可以参考:https://www.toimc.com/docker%E5%85%A5%E9%97%A8%E4%B9%8B%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/
先删除旧的版本(如果没有可以跳过):
1
2
3
4
5
6
7
8sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine安装必须的依赖:
1
2
3sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2添加
stable的Docker-ce的源:1
2
3sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo安装
docker-ce:1
sudo yum install docker-ce docker-ce-cli containerd.io
启动服务:
1
sudo systemctl start docker
docker-compose安装:
Docker-Compose工具是一个批量工具,用于运行与管理多个docker容器。官方文档:Install Docker Compose
1 | # 下载docker-compose |
新版安装docker
由于不可抗力原因,截至目前,2024年6月27号,阿里云的服务器是无法正常拉取docker镜像的,以下是阿里云售后技术的回复:
您好,近期因为https://hub.docker.com/ 被污染(具体可以参考:https://boce.aliyun.com/home) timeout等现象, 关于解决方案
1、针对个人单docker环境客户
1.1 本地先pull下来(因为域名被污染,本地可能也无法拉取,可以考虑中国香港或者是海外的服务器pull下来)
1.2 使用docker save导出为
tar.gz文件,然后上传到自己的机器,使用docker load -i XXX.tar.gz解压出来使用 导出命令:docker save -o nginx.tar.gz nginx:latest导入命令:docker load -i nginx.tar.gz2、针对集群用户
2.1 本地先pull下来(因为域名被污染,本地可能也无法拉取,可以考虑中国香港或者是海外的服务器pull下来)
2.2 修改tag 命令(例如):
docker tag nginx:latest ceshi:latest 2.3然后上传到阿里云acr容器镜像仓库里面,yaml地址里面修改为您阿里云仓库的vpc地址,用私网拉取,比走海外公网的速率高以及稳定性强一点 注意:如果您的集群或者是ACR是大陆的,可能会存在链路问题导致镜像推送到ACR失败,建议导出镜像后导入镜像到您本地的大陆机器,然后push到您的ACR里边
所以现在安装Docker如果按照之前的方式会出现无法正常安装的情况,Docker也无法正常的pull镜像,这里有两种解决方法:(当然方法不止这两种)
- 使用境外的服务器,把镜像
pull到本地,然后再上传到服务器,优点是简单粗暴,原理简单。缺点是要下载镜像有限,只能先下载需要用到的镜像。(我采用的是这种方式) - 使用
cloudflare和这个开源项目https://github.com/cmliu/CF-Workers-docker.io/issues/8 ,原理就是使用cloudflare去代理dockerhub这个网站,这样就可以访问到dockerhub。配置起来很简单,具体可以看看这个UP主,讲解得比较简单明了:https://www.bilibili.com/video/BV1H442197oQ/
这里是centos7.8的安装步骤:
运行以下命令,下载
docker-ce的yum源。1
sudo wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
运行以下命令,安装Docker。
1
sudo yum -y install docker-ce
执行以下命令,检查Docker是否安装成功。
1
docker -v
如下图回显信息所示,表示Docker已安装成功。

执行以下命令,启动Docker服务,并设置开机自启动。
1
2sudo systemctl start docker
sudo systemctl enable docker执行以下命令,查看Docker是否启动。
1
sudo systemctl status docker
安装docker-compose:(centos7.8不推荐使用,在一些场景会报错,推荐适用老版本的安装方式)
运行以下命令,安装
setuptools。1
sudo pip3 install -U pip setuptools
运行以下命令,安装
docker-compose。
1
sudo pip3 install docker-compose
- 运行以下命令,验证
docker-compose是否安装成功。(这里会提示一个警告,可以忽略,大概意思就是python版本太低,)
1
docker-compose --version
docker的安装具体参考阿里云:https://help.aliyun.com/zh/ecs/use-cases/install-and-use-docker-on-a-linux-ecs-instance
安装acme
首先确认您域名使用的DNS服务商,不同的DNS服务商对应的命令是不同的。比如这里使用的腾讯云的DNSPro解析域名服务。
acme官网Github:https://github.com/acmesh-official/acme.sh
安装:(这里一定要带上自己的邮箱,否则后面会报错,会由记录报错,需要多试几次)
1 | curl https://get.acme.sh | sh -s email="[email protected]" |
这个命令安装acme并且创建了一个 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.
注意:安装好之后建议重新连接服务期,如果这个时候直接使用
acme.sh可能有问题
示例
下面是示例的讲解:
生成证书:(这里我们使用DNSAPi的高阶用法生成证书)
更高阶的用法:https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
DNS APi:https://github.com/acmesh-official/acme.sh/wiki/dnsapi
以下是cloudflare的生成证书方式:(cloudflare的DNS有个坑,后面简介)
1 | export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" |
以下是DNSPro的生成证书方式:(注意申请的是DNSPro的令牌不是腾讯云的令牌)
1 | export DP_Id="XXXX" |
至此,证书签发完成。
安装Nginx容器
流程梳理
创建home/keys文件夹,存放Https证书文件->创建随机的密钥->创建容器的局域网段->创建/home/keys/nginx/conf.d文件夹,存放nginx的配置文件->创建nginx.conf文件,并上传到服务器home/nginx文件夹下->通过docker-cpmpose文件安装Nginx->exportDNS服务商的令牌->最后执行acme.sh命令
把所有的配置文件都放在home文件夹下,方便以后管理,目录使用英文并具有一定意义
具体实现
安装之前,我们需要把https证书放到一个可以让nginx容器访问到的地方,这是一个官方的示例:
1 | acme.sh --install-cert -d example.top \ |
(一个小提醒, 这里用的是 service nginx force-reload, 不是 service nginx reload, 据测试, reload 并不会重新加载证书, 所以用的 force-reload)
因为我们使用的是Docker的方式安装Nginx,所以我们需要修改一下,把目录都放到home目录的key文件夹下(记得域名改为自己的)
1 | acme.sh --install-cert -d example.top \ |
这句命令主要为域名创建了两个证书文件,并放在key指定文件夹下,最后重启some-nginx容器
先不使用安装命令,先完成以下步骤:
创建文件夹:
mkdir /home/keys,存放Https证书文件创建随机的
https证书密钥:1
openssl dhparam -out /home/keys/dhparam.pem 2048
创建容器的局域网段:
1 | docker network create https |
创建文件夹:
1
2mkdir /home/nginx
mkdir /home/nginx/conf.d配置
nginx.conf文件,并上传到服务器home/nginx文件夹下,这是一个通用的文件配置1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53user nginx;
worker_processes auto;
pid /run/nginx.pid;
worker_rlimit_nofile 65535;
events {
# 设置事件驱动模型,是内核2.6以上支持
use epoll;
worker_connections 65535;
accept_mutex off;
multi_accept off;
}
http {
# Basic Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
send_timeout 120;
keepalive_timeout 300;
client_body_timeout 300;
client_header_timeout 120;
proxy_read_timeout 300;
proxy_send_timeout 300;
#tcp_nopush on;
types_hash_max_size 4096;
client_header_buffer_size 16m;
client_max_body_size 4096m;
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
# include /usr/share/nginx/modules/*.conf;
default_type application/octet-stream;
# Logging Settings
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 开启gzip
gzip on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png font/ttf font/otf image/svg+xml;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
}接下来是
Nginx容器安装,编写docker-compose文件:
1 | version: "3" |
解释:创建了一个some-nginx的容器,把容器文件nginx.conf、conf.d和keys文件夹挂载出来。暴露端口是80和443;把容器加入到https的网段里面,让这个网段里面的容器可以被nginx容器代理到。
编写好后就可以直接使用一下命令安装:
1 | docker-compose up -d |
最后我们就可以运行之前acem的安装命令:
1 | acme.sh --install-cert -d example.top \ |
正常的话,这里运行着一个nginx容器了,这里的步骤稍微复杂但是细心一点还是没有难度的,特别需要注意的是域名、文件夹和文件名这些内容不要写错。
TIP:这里在使用
docker-compos安装前,需要把Nginx的文件夹先创建好,给目录777权限,nginx.conf是文件,conf.d是文件夹
最佳实践
静态博客站简单部署
cd到/home/nginx/conf.d目录,然后编写文件blog.conf文件,然后放到home目录的nginx的conf.d文件夹下(记得替换域名)
blog.conf文件:
1 | # listen on HTTP2/SSL |
在home目录下的blog放静态资源,然后DNS服务商把www网站解析到服务器即可以访问
安装Jenkins
使用docker-compose方式安装:
创建一个名字叫docker-compose.yml的文件:
1 | version: '3' |
创建了一个
jenkins的最新版本镜像,并创建运行一个叫jenkins容器端口可以挂载也可以不挂载,因为使用的是域名访问,没有影响。
需要给文件夹赋予权限:
1 | chmod 777 /home/jenkins/data |
这里我们可以使用ftp工具上传到服务器上的home目录下的jenkins,推荐使用FileZilla Client。
然后cd到docker-compose的目录下,使用一下命令安装:
1 | docker-compose up -d |
安装好之后我们需要得到一串密钥文件,输入命令:
1 | docker logs -f jenkins |
可以得到一个密钥,等会安装需要,可以先记录下来,不先安装,先让nginx能代理jenkins容器再来安装。同样的操作的:
jenkins.conf文件:
1 | upstream target-server { |
注意容器是8080端口的,域名改为自己的。target-server这个根据个人修改,每个应用不能重复
接下来就是打开域名,访问Jenkins,把刚才的密钥复制粘贴,安装插件,创建用户
然后需要Jenkins下载下面3个插件:
- Build With Parameters 输入框式的参数
- Persistent Parameter 下拉框式的参数
Gitee
最后再配置Gitee的用户名密码,能然后的项目部署访问到。
补充:这里后面涉及到项目需要在jengkins使用docker-compos的命令,这里写一下:
1 | 进入 Jenkins 容器 |
jenkins_container_name是自己jenkins的容器名称。
自动化部署Hexo博客
hexo上传代码需要以下插件:
1 | npm install hexo-deployer-git --save |
需要改动hexo配置文件:
1 | deploy: |
上传git代码还需要配置ssh的密钥,同时还需要配置本地的账户名和邮箱
本地生成SSH密钥
1 | ssh-keygen |
配置git本地的账户名和邮箱
1 | git config --global user.name "Git用户名" |
本地编写DockerFile
1 | FROM node:20 as build-stage |
gitee和jenkins联调
- 创建一个自由风格的项目;
- 然后选择参数化构建过程,有4个参数,分别是写container_name、port、image_name、tag,类型写String;
- 源码管理Git填写代码仓库地址。(注意要配置好Gitee的凭据);
- 勾选
Gitee webhook触发构建,生成Gitee WebHooks密码,然后在·仓库的·那里填写这个url和密码,其他可以保持默认; - 最后构建过程选择执行shell。
shell脚本:
1 | !/bin/bash |
这样基本就搭建完成,本店只要通过hexo g命令上传代码,jenkins就可以自动构建部署了,因为没有使用docker-compose文件所以这里需要shell脚本,后面使用docker-compose就不需要这么复杂的shell脚本
nginx的配置文件与jenkins一样,需要修改域名,target-server和注意容器的端口
自动化部署Vue前端项目
项目根目录本地编写DockerFile和docker-compose文件
DockerFile文件
1 | FROM node:20 as build-stage |
docker-compose文件
1 | version: '3' |
gitee和jenkins联调
与自动化部署Hexo博客一样,但是去除掉参数化和改shell脚本:
1 | docker-compose up -d |
nginx的配置文件与jenkins一样,需要修改域名,target-server和注意容器的端口
自动化部署NodeJS项目
本地编写DockerFile和docker-compose文件
项目根目录本地编写DockerFile和docker-compose文件
DockerFile文件
1 | FROM node:20 |
docker-compose文件
1 | version: '3' |
gitee和jenkins联调
与自动化部署Hexo博客一样,但是去除掉参数化和改shell脚本:
1 | docker-compose up -d |
nginx的配置文件与jenkins一样,需要修改域名,target-server和注意容器的端口
可能用到的工具
这里列举了我常用的开发工具和连接服务器工具链接
- VsCode:https://code.visualstudio.com/
- Git:https://git-scm.com/
- PicGo:https://picgo.github.io/PicGo-Doc/zh/
- Snipaste:https://zh.snipaste.com/
- FileZilla Client: https://www.filezilla.cn/
一些踩过的坑!!
在部署的时候遇到一个巨坑,因为使用的是cloudflare进行·解析,但是有一个断到断的加密过程,看下面图片就知道了,用户访问会被cloudflare先代理,走https,但是cloudflare跟服务器也要走https,不能走http,不然就会出现前端重定向问题!这里一般选择完全的SSL加密

总结
服务器端密钥登录
Docker和
DockerCompose的安装acme的安装过程
Nginx安装和acme的配置不同的方式安装docker容器项目,实现自动化部署集成并支持
https访问
