# 13 常用容器部署-Nginx-https

下面介绍一下常用容器的部署。可以先简单了解下,用到再来详细查看。

在 Docker 中部署 Nginx,通过挂载方式将 Nginx 的配置文件和站点目录挂载到宿主机上。

并配置https。

# 13.1 下载镜像

docker pull nginx
1

默认下载的就是最新的镜像文件。

# 13.2 创建挂载目录

在宿主机上创建挂载目录,自己自定义放在哪里。

# 配置文件目录
mkdir -p /home/doubi/docker_dir/nginx/conf
# 站点目录
mkdir -p /home/doubi/docker_dir/nginx/html
# nginx日志目录
mkdir -p /home/doubi/docker_dir/nginx/log
# 放https证书
mkdir -p /home/doubi/docker_dir/nginx/ssl

# 递归赋予文件夹读写执行权限
chmod -R 777 /home/doubi/docker_dir/nginx
1
2
3
4
5
6
7
8
9
10
11

# 13.3 复制配置文件

如果我们此时使用如下指令直接运行容器会存在一个问题。

docker run -d -p 8080:8080 --name nginx --restart=always \
	-v /home/doubi/docker_dir/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
	-v /home/doubi/docker_dir/nginx/conf/conf.d:/etc/nginx/conf.d \
	-v /home/doubi/docker_dir/nginx/log:/var/log/nginx \
	-v /home/doubi/docker_dir/nginx/html:/usr/share/nginx/html \
	nginx
1
2
3
4
5
6

宿主机不存在不存在 nginx.conf 文件,会把 /home/doubi/docker_dir/nginx/conf/nginx.conf 当成文件夹来处理,那么把宿主机的 /home/doubi/docker_dir/nginx/conf/nginx.conf 文件夹映射到容器的 /etc/nginx/nginx.conf 就会报错。


怎么处理呢?

我们首先通过 nginx 镜像运行一个简单的容器,将简单的容器中的配置文件复制到宿主机中,然后删除简单的容器,重新使用上面的命令运行我们的容器。

运行一个简单的容器

# 启动容器
docker run --name nginx -p 8080:80 -d nginx
1
2

复制配置文件到宿主机

# 将容器中nginx.conf文件复制到宿主机的挂载目录中
docker cp nginx:/etc/nginx/nginx.conf /home/doubi/docker_dir/nginx/conf/nginx.conf
# 将容器中conf.d文件夹下内容复制到宿主机的挂载目录中
docker cp nginx:/etc/nginx/conf.d /home/doubi/docker_dir/nginx/conf/conf.d
# 将容器中的html文件夹复制到宿主机的挂载目录中,后面没有html
docker cp nginx:/usr/share/nginx/html /home/doubi/docker_dir/nginx
1
2
3
4
5
6

删除简单的容器

docker rm -f nginx
1

# 13.4 生成证书

如果你已经有证书了,将证书放在挂载目录的 ssl 文件夹下,我上面是 /home/doubi/docker_dir/nginx/ssl

下面是生成本地证书,可以跳过。


下面针对的是生成本地运行的证书文件。

安装 OpenSSL(如果未安装)

如果你的系统中没有安装 OpenSSL,可以通过以下命令安装:

sudo apt-get update
sudo apt-get install openssl
1
2

生成自签名 SSL 证书和私钥

首先,生成私钥文件:

sudo openssl genpkey -algorithm RSA -out /home/doubi/docker_dir/nginx/ssl/server.key -aes256

# 去除密码,否则需要在nginx配置文件中配置密码
sudo openssl rsa -in /home/doubi/docker_dir/nginx/ssl/server.key -out /home/doubi/docker_dir/nginx/ssl/server.key.unsecure
1
2
3
4

这会在 /home/doubi/docker_dir/nginx/ssl/ 文件夹下生成一个加密的私钥文件 server.keyserver.key.unsecure

  • server.key 用来生成下面的 SSL 证书
  • server.key.unsecure 后面配置到 nginx 中,这样 nginx 中不用配置密码

然后,使用 server.key 生成自签名 SSL 证书:

sudo openssl req -new -x509 -key /home/doubi/docker_dir/nginx/ssl/server.key -out /home/doubi/docker_dir/nginx/ssl/server.crt -days 3650
1

这会在 /home/doubi/docker_dir/nginx/ssl 文件夹下生成一个自签名的证书文件 server.crt,有效期为 3650 天。

生成的过程需要填写一些信息,根据提示填写即可。

# 13.5 修改证书配置

修改 nginx 配置文件 default.config

server {
		listen 80;
    listen 443 ssl;
    server_name 192.168.xxx.xxx; 		# 本地证书这里配置服务器的IP地址,否则配置域名
    
    # HTTP 重定向到 HTTPS
    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }

    ssl_certificate /ssl/server.crt;								# SSL 证书的路径
    ssl_certificate_key /ssl/server.key.unsecure;		# 证书私钥路径
    
    ssl_session_cache 		shared:SSL:1m;		# 会话缓存大小为1M
		ssl_session_timeout 	5m;								# 会话超时时间为5分钟

    # 配置其他 SSL 选项
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    # ...其他配置
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

如果你是阿里云平台生成的 https 证书,下载 nginx 的证书,应该是一个 xxx.pemxxx.key 文件,配置到上面的路径即可。

# 13.6 运行容器

现在有配置文件了,可以运行容器,并进行挂载了:

docker run -d -p 80:80 -p 443:443 --name nginx --restart=always \
	-v /home/doubi/docker_dir/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
	-v /home/doubi/docker_dir/nginx/conf/conf.d:/etc/nginx/conf.d \
	-v /home/doubi/docker_dir/nginx/log:/var/log/nginx \
	-v /home/doubi/docker_dir/nginx/html:/usr/share/nginx/html \
	-v /home/doubi/docker_dir/nginx/ssl:/ssl \
	nginx
1
2
3
4
5
6
7

参数说明:

  • -d:后台运行
  • -p: 端口映射(宿主机端口:容器端口),nginx配置文件中默认使用的是80端口,所以容器的端口使用的是80,除非修改配置文件。
  • --name 创建容器的名称
  • --restart=always 容器停止后自动重启
  • -v 目录挂载(宿主机目录:容器目录)
  • 最后的nginx表示镜像的名称

# 13.7 访问首页

现在通过 https://IP 就可以访问了。

# 13.8 部署vue项目

首先将 vue 项目中打包生成 dist 文件夹中的内容,全部拷贝到与nginx的html相映射的文件夹中,然后重启docker内的 nginx。

或者将 dist 解压到 html 文件夹,然后修改 conf.d 文件夹中的 default.config 文件,修改根目录映射 html 下的 dist。

location / {
    root   /usr/share/nginx/html/dist;
    try_files  $uri $uri/ /index.html;
}
1
2
3
4