前言
博主在日常折腾时,经常会使用到nginx
来测试网站,或者反代容器等需求.所以整理了一套方便在docker
上使用nginx
的方案.本文并不是详细的使用教程,而是一篇快速部署和迁移的准备工作,适用以下场景:
- 快速部署
通过下文的前期准备,可以实现在任何服务器上快速部署环境.用完即删,保持服务器干净. - 快速迁移
各云服务商都会提供了免费试用的服务器,性能低,安装环境太慢,更换服务器后无需频繁安装环境,实现快速迁移.
创建目录
为方便持久化存储和快速迁移,提前规划好相关文件的存放目录.
例如在/root
下创建nginx
目录,用于集中存放配置文件,证书及网页文件.
mkdir -p ~/nginx/conf
mkdir -p ~/nginx/vhost
mkdir -p ~/nginx/ssl
mkdir -p ~/nginx/html
~/nginx/conf
用于存放nginx 主配置
文件~/nginx/vhost
用于存放各站点conf配置
文件~/nginx/ssl
用于存放证书
文件~/nginx/html
用于存放网页
文件
配置环境
获取原始 nginx.conf
拉取官方nginx
镜像
docker pull nginx
首次直接后台运行,以方便拷贝原始nginx.conf
配置文件.
docker run -d --name=nginx nginx
将原始nginx.conf
配置文件拷贝至~/nginx/conf
docker cp nginx:/etc/nginx/nginx.conf ~/nginx/conf
停止并删除容器
docker stop nginx
docker rm nginx
修改原始 nginx.conf
编辑原始nginx.conf
vi ~/nginx/conf/nginx.conf
新增include
使得vhost
目录下的任何conf
配置文件都能被nginx
读取.
# 查找到
include /etc/nginx/conf.d/*.conf;
# 新增一行
include /etc/nginx/conf.d/vhost/*.conf;
完成准备工作
- 将常用的域名证书上传至
~/nginx/ssl
- 将网站的
域名conf
或者常用样本conf
上传至~/nginx/vhost
- 将网页文件以各域名命名的文件夹上传至
~/nginx/html
- 将整个
nginx
目录打包存档,上传至网盘,对象存储或者GitHub中.
常规 Nginx 样本
server
{
listen 80;
#listen [::]:80;
server_name www.yourdomain.com ;
index index.html index.htm index.php default.html default.htm default.php;
root /usr/share/nginx/html/www.yourdomain.com;
# return 301 https://www.yourdomain.com$request_uri;
#error_page 404 /404.html;
# Deny access to PHP files in specific directory
#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /.well-known {
allow all;
}
location ~ /\.
{
deny all;
}
access_log off;
}
server
{
listen 443 ssl http2;
#listen [::]:443 ssl http2;
server_name www.yourdomain.com ;
index index.html index.htm index.php default.html default.htm default.php;
root /usr/share/nginx/html/www.yourdomain.com;
# if ($host = 'yourdomain.com') {
# return 301 https://www.yourdomain.com$request_uri;
# }
ssl_certificate /etc/nginx/ssl/yourdomain.com.cer;
ssl_certificate_key /etc/nginx/ssl/yourdomain.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
ssl_session_cache builtin:1000 shared:SSL:10m;
# openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
# ssl_dhparam /usr/local/nginx/conf/ssl/dhparam.pem;
#error_page 404 /404.html;
# Deny access to PHP files in specific directory
#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /.well-known {
allow all;
}
location ~ /\.
{
deny all;
}
access_log off;
}
Nginx 反向代理其他容器样本
upstream dockername {
server 127.0.0.1:8080; # 端口改为docker容器提供的端口
}
server {
listen 80;
server_name www.domain.com;
return 301 https://www.domain.com$request_uri;
}
server {
listen 443 ssl;
server_name www.domain.com;
gzip on;
ssl_certificate /etc/nginx/ssl/www.domain.com.cer;
ssl_certificate_key /etc/nginx/ssl/www.domain.com.key;
# access_log /var/log/nginx/dockername_access.log combined;
# error_log /var/log/nginx/dockername_error.log;
location / {
proxy_redirect off;
proxy_pass http://dockername;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
client_max_body_size 100m;
client_body_buffer_size 128k;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
- 证书路径
/etc/nginx/ssl/www.yourdomain.com.cer(key)
- 网站 root 路径
/usr/share/nginx/html/www.yourdomain.com
快速部署
在新环境需要使用时,直接通过wget
或git clone
将nginx目录
拉取到服务器的/root
下,执行以下命令启动容器,即可快速部署网站.使用过程中新增网站仅需上传网页文件和新建站点conf
文件并重启容器.
docker run -d --name=nginx --restart=always \
--network host \
-v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v ~/nginx/vhost:/etc/nginx/conf.d/vhost \
-v ~/nginx/ssl:/etc/nginx/ssl \
-v ~/nginx/html:/usr/share/nginx/html \
nginx
使用 --network host
使用--network host
参数是让nginx
直接使用宿主机服务器的的网络,也就无需映射80/443
端口.其目的是当有其他容器需要被nginx
反向代理时,conf
配置文件中的反代地址127.0.0.1
能正确的被识别为宿主机.
不使用 --network host
如果不使用 --network host
,而单独映射80/443
端口到宿主机,当反向代理到127.0.0.1:XXXX
的其他容器时是无法成功的.因为此时的127.0.0.1
实际上是nginx
这个容器自身的内网IP,并非宿主机的内网IP.
当然可以使用ifconfig -a
命令查询宿主机的内网IP,替换掉127.0.0.1
也能够解决.还有可以使用host.docker.internal
来使容器识别宿主机IP,但是都相对麻烦,也不利于快速部署和迁移.大家可根据自己实际情况选择使用.
特殊需求
如果遇到环境中80/443
端口被占用,临时需要使用nginx
,同样可以使用以下映射端口的命令来启动,只是切记在反代时使用宿主机的内网IP.
docker run -d --name=nginx --restart=always \
-p 8080:80 \
-p 4443:443 \
-v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v ~/nginx/vhost:/etc/nginx/conf.d/vhost \
-v ~/nginx/ssl:/etc/nginx/ssl \
-v ~/nginx/html:/usr/share/nginx/html \
nginx
结语
更进阶的玩法还可以将nginx
,php
,mysql
整合成docker compose
的方式来快速部署,网上已有成熟的方案,博主也在使用.推荐给大家:
4 条评论
大佬,请教下。
我用群辉的DOCKER部署了halo博客和nginx。http协议用域名加端口的方式能访问,但是https协议,却不能访问。
我现在想实现http,https都可以访问(不一定非要用80和443的端口),并实现http自动跳转https访问。
你这不是一个简单的问题,你要会用 nginx 配置文件才行.
upstream halo {
server 127.0.0.1:8090;
}
server {
listen 80;
listen [::]:80;
server_name www.yourdomain.com;
client_max_body_size 1024m;
location / {
}
}
这是官方给的配置