拉取镜像
$ docker pull nginx
默认会拉取仓库名为nginx,tag为latest的镜像。
挂载nginx.conf文件
首次启动nginx容器
考虑到后面维护nginx配置文件nginx.conf的成本,这里采用docker 数据卷的技术,即将docker中的nginx.conf配置文件挂载到宿主机当中,后续只需要修改宿主机中的配置文件,就可以实现修改容器中nginx配置文件的目的。这里就是简单讲述了一下数据卷的作用。
那么这里面我为什么只强调了需要挂载配置文件,难道其他的比方html,logs文件夹数据不需要挂载吗?答案是当然需要,但这里我们只需要对于单独的文件挂载做一下特殊处理即可,对于文件夹的挂载,我们并不需要新建文件夹,再进行cp的操作,docker可以实现对文件夹的完美挂载(即容器中有html文件夹,但是宿主机没有,这样是没关系的直接执行挂载命令,docker会在宿主机创建对应的文件夹以及文件夹下面的文件)。
启动一个nginx容器
$ docker run --name mynginx -d -p 80:80 nginx
在宿主机中新建nginx.conf文件存放目录
$ mkdir -p /app/nginx/conf
拷贝docker容器nginx配置文件到宿主机目录下
$ docker cp mynginx:/etc/nginx/nginx.conf /app/nginx/conf
Preparing to copy...
Successfully copied 3.584kB to /app/nginx/conf
删除容器
$ docker rm -f mynginx
非首次启动nginx容器
找到正在运行的或者是退出状态的容器。
从【首次启动nginx容器】的目录下面的第二点开始操作即可。
启动容器
docker run --name mynginx -p 80:80 -p 443:443 \
-v /app/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /app/nginx/html/:/usr/share/nginx/html \
-v /app/nginx/certs:/etc/nginx/certs \
-d --privileged=true nginx
注释版
docker run --name mynginx -p 80:80 -p 443:443 \ # 同时开始80和443端口
-v /app/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \ # 挂载容器nginx.conf文件到宿主机
-v /app/nginx/html/:/usr/share/nginx/html \ # 挂载容器html文件夹到宿主机,没有则会自动新建
-v /app/nginx/certs:/etc/nginx/certs \ # 挂载容器certs文件夹到宿主机,没有则会自动新建
-d --privileged=true nginx
配置SSL访问
找到自己域名服务商,并申请免费的SSL证书,下载对应nginx版本的证书,一共是两个文件,一个以pem结尾一个以key结尾。
将xxx.pem和xxx.key放在宿主机目录/app/nginx/certs下面,放置后,会自动挂载到容器内的对应目录下面去。
编辑/app/nginx/conf/nginx.config,在http模块下添加SSL配置
http {
server {
listen 443 ssl; #监听端口,ssl默认443端口。如果需要配置多个端口,可以继续添加server,用不同的端口就行
server_name www.lucfzy.com; #服务器域名,需要和申请的证书匹配
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_certificate /etc/nginx/certs/xxx.pem; #证书路径
ssl_certificate_key /etc/nginx/certs/xxx.key; #请求认证 key 的路径
location / {
root /usr/share/nginx/html; #网站根目录,和容器创建时指定的位置一致
index login;
}
}
}
重启docker nginx服务(使用热部署方式)
$ docker exec mynginx nginx -s reload
2023/03/11 10:23:55 [notice] 99#99: signal process started
访问域名

配置80端口强制跳转到443端口
修改80监听端口的配置
server {
listen 80;
server_name lucfzy.com www.lucfzy.com;
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
此时浏览器访问http的普通链接就可以强制转跳到443的https的安全链接。
常见问题
warn警告:the "ssl" directive is deprecated, use the "listen ... ssl" directive。
完整内容如下
2023/03/11 09:21:40 [warn] 37#37: the "ssl" directive is deprecated, use the "listen ... ssl" directive instead in /etc/nginx/nginx.conf:34
nginx: [warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive instead in /etc/nginx/nginx.conf:34
解决:在nginx 1.15及以后的版本,不需要再写 ssl on; 的配置了,直接在listen 443中填写即可。
即将
listen 443;
修改为
listen 443 ssl;

server模块代理动态资源proxy_pass接口转发502 bad gateway!
问题写法1

该写法的问题是ngxin找到的是docker容器内部的localhost,而不是宿主机,所以无法找到8090端口进行请求的正常转发,正确的方式应该使用域名或者公网ip地址。当然这里更推荐的是公网ip地址, 因为公网ip一般是不会变的,域名可能会申请多个,映射到同一台服务器上面。
问题写法2

这个写法的问题在于,指定了https本身就是443端口,然后又指定了8090相当于矛盾了,正确用法参考错误示例1中所说。
正确写法

热更新nginx容器
$ docker exec mynginx nginx -s reload