使用Docker加Nginx配置HTTPS

本文将介绍如何将网站HTTP协议升级为HTTPS。部署的网站是Hexo。

前置

  • 服务器已经安装Docker
  • 已经拉取了Nginx镜像
  • 云服务器有安全组的已开放80和443端口
  • 拥有SSL证书并下载了Nginx版本

部署

  • 本文中Nginx使用的版本为1.21.6

部署总共分为以下几个部分

  1. 设置挂载目录
  2. 将SSL证书上传到服务器的挂载目录
  3. 配置Nginx
  4. 启动Nginx镜像

设置挂载目录

设置挂载目录的目的在于将Docker的虚拟机目录映射到物理机上,例如使用-v /a:/b配合之后,虚拟机访问目录b的资源时,不会直接从b中获取,而是从物理机的a目录下去获取需要访问的资源,读写操作同样。设置挂载目录是在最后启动Nginx镜像执行的

这里我们设置了四个挂载目录:

  • /etc/localtime:作用是将虚拟机的时间与物理机同步,这个设置在很多应用中都要开启,虚拟机时间不一致可能会导致服务不可用,后台服务的时间与Redis缓存服务的时间不一致,会导致用户频繁掉线。
  • /etc/nginx:将Nginx的配置文件映射到物理机中,方便修改配置。**设置这个挂载前要将容器中同目录下的其他文件复制到物理机中没有复制的话会导致Nginx无法加载到配置文件而无法启动,可以使用命令docker cp 容器ID:容器内目录 物理机目录**。
  • /usr/share/nginx/html:这是Nginx默认的网站文件路径
  • /var/log/nginx:Nginx的日志

本文设置的挂载目录:

1
2
3
4
-v /etc/localtime:/etc/localtime 
-v /gmfan/conf/nginx:/etc/nginx
-v /gmfan/dist:/usr/share/nginx/html
-v /gmfan/log/nginx:/var/log/nginx

将证书上传到挂载目录中

由于本文以及将物理机下的/gmfan/conf/nginx映射到了/etc/nginx中,所以我在物理机下的这个目录创建了一个cert目录用于存放证书。

1
2
3
4
[root@gmfan cert]# pwd
/gmfan/conf/nginx/cert
[root@gmfan cert]# ls
7395890_www.gmfan.cn.key 7395890_www.gmfan.cn.pem

配置Nginx

由于我已经将容器内的配置文件复制到了物理机上了,所以只需要修改物理机上对应的配置文件既可以,一下就是nginx.conf的配置。需要特别注意的是nginx.conf文件需要放到/etc/nginx目录下而不是conf.d下,因为work_processes指令要在/etc/nginx目录下否则将报(”worker_processes” directive is not allowed here in /etc/nginx/conf.d/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
53
54
55
56
57
58
59
60
61
62
63
# 设置线程数
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

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;

keepalive_timeout 65;

#gzip on;

#ssl on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

include /etc/nginx/conf.d/*.conf;

server {
listen 443 ssl;
#证书绑定域名
server_name www.gmfan.cn;
#证书
ssl_certificate /etc/nginx/cert/1_www.gmfan.cn.pem;
#私钥
ssl_certificate_key /etc/nginx/cert/1_www.gmfan.cn.key;
ssl_session_timeout 5m;
#按照以下协议配置
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;

root /usr/share/nginx/html;

location / {

}
}
#设置重定向,HTTP重定向到HTTPS
server{
listen 80;
# 需要重定向的域名
server_name www.gmfan.cn gmfan.cn;
return 301 https://$host$request_uri;
}

}

其中证书的路径是相对于容器内的,由于我已经将证书上传到/gmfan/conf/nginx/cert这个目录下并且设置了容器目录/etc/nginx映射到/gmfan/conf/nginx此目录上,所以我的证书对应的容器目录为/etc/nginx/cert/1_www.gmfan.cn.pem私钥同理。

最后启动Nginx容器

由于HTTPS的默认端口为443,HTTP的默认端口为80故需要将物理机的端口映射到容器上使用命令**-p 物理机端口号:实体机端口号**。本文的启动命令为:

1
2
3
4
5
6
7
8
9
docker run \
-p 80:80 \
-p 443:443 \
--name nginx \
-v /etc/localtime:/etc/localtime \
-v /gmfan/conf/nginx:/etc/nginx \
-v /gmfan/dist:/usr/share/nginx/html \
-v /gmfan/log/nginx:/var/log/nginx \
-d nginx

-d的意思是后台执行。

最后推荐一个好用且免费的SSH与SFTP工具MobaXterm。

参考资料