[nginx] 基于Docker安装Nginx

0 序

  • 环境信息
  • OS : CENTOS 7.9
  • Docker : 25.0.4
  • Nginx : 1.24.0

1 安装步骤

Step0 安装 docker

略。可参见:

Step1 下载nginx镜像

  • 下载 nginx镜像
docker pull nginx:1.24.0

问题现象: 因法规政策原因,docker.io网站被禁用,导致拉取nginx的docker镜像失败,报:"Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)"错误。
解决方法:

  • step1 配置可用的镜像源 vim /etc/docker/daemon.json
{
	"registry-mirrors": [
		"https://mirror.iscas.ac.cn",
		"https://docker.jsdelivr.fyi",
		"https://dockertest.jsdelivr.fyi",
		"https://mirror.baidubce.com",
		"https://docker.m.daocloud.io"
	]
}
  • step2 重启 docker
systemctl daemon-reload
systemctl restart docker

参考文献: 解决docker: Error response from daemon: Get “https://registry-1.docker.io/v2/“: net/http: request canc - CSDN

  • 查看下载的镜像
docker images

Step2 基于宿主机创建Nginx配置文件

  • 创建挂载目录

启动前需要先创建Nginx外部挂载的配置文件( /data/nginx/conf/nginx.conf
之所以要先创建 , 是因为Nginx本身容器只存在 /etc/nginx 目录 , 本身就不创建 nginx.conf 文件
当服务器和容器都不存在 nginx.conf 文件时, 执行启动命令的时候 docker 会将 nginx.conf 作为目录创建 , 这并不是我们想要的结果 。

mkdir -p /data/nginx/
# [x] mkdir -p /data/nginx/conf
  注: /data/nginx/conf 目录,由下一步骤的 cp + mv 的方式创建
# [x] mkdir -p /data/nginx/conf/conf.d
  注: /data/nginx/conf/conf.d 目录,由下一步骤的 cp + mv 的方式创建
# [x] mkdir -p /data/nginx/html
  注: /data/nginx/html 目录,由下一步骤的 cp 的方式创建
# [x] mkdir -p /data/nginx/log
  注: /data/nginx/log 目录,由下一步骤的 cp + mv 的方式创建

  • 将样例容器中的nginx.conf文件和conf.d文件夹复制到宿主机
# 生成DEMO容器 (后面步骤中可删除之)
docker run --name demo-nginx -p 18080:80 -d nginx:1.24.0

# 将容器/etc/nginx下的文件
docker cp demo-nginx:/etc/nginx/ /data/nginx/
mv /data/nginx/nginx /data/nginx/conf 
### nginx.conf文件复制到宿主机
### [无需执行] docker cp demo-nginx:/etc/nginx/nginx.conf /data/nginx/conf/nginx.conf
### 将容器conf.d文件夹下内容复制到宿主机
### [无需执行] docker cp demo-nginx:/etc/nginx/conf.d /data/nginx/conf/conf.d
### 将容器mime.types文件下内容复制到宿主机
### [无需执行] docker cp demo-nginx:/etc/nginx/mime.types /data/nginx/conf/mime.types

# 将容器中的html文件夹复制到宿主机
docker cp demo-nginx:/usr/share/nginx/html /data/nginx/
 # 注: 目标目录 /data/nginx/html

# 将容器中的日志文件夹复制到宿主机
docker cp demo-nginx:/var/log/nginx /data/nginx/
mv /data/nginx/nginx /data/nginx/log 

# 停止 DEMO Nginx 容器
docker stop demo-nginx
# 删除  DEMO Nginx 容器
docker rm -f demo-nginx

Step3 创建Nginx容器、并运行

  • 创建、并启动 nginx 容器

docker run \
-p 80:80 \
-p 443:443 \
-p 81:81 \
--add-host host.docker.internal:host-gateway \
--name nginx \
-v /data/nginx/conf/:/etc/nginx/ \
-v /data/nginx/log:/var/log/nginx \
-v /data/nginx/html:/usr/share/nginx/html \
-d nginx:1.24.0
  • -p 80:80 : 第1个 80 端口:是指宿主机的映射端口 ; 第2个 80 端口:是指容器的被映射端口
  • -p 81:81 : 暴露多个端口的Demo。
  • -d : 后台运行
  • --add-host:host.docker.internal:host-gateway : 【可选参数】 标志启用主机的默认名称 host.docker.internal。使用此标志启动容器以公开主机字符串。 `

--add-host 标志向容器的 /etc/hosts 文件添加一个条目。上面显示的值将 host.docker.internal 映射到容器的主机网关,这与真实的 localhost 值相匹配。如果您愿意,可以用您的主机真实名称替换 host.docker.internal 。
此做法主要用于解决: 在 nginx 容器中访问/代理宿主机的Web服务:

upstream xxxx_api_server {
	ip_hash;
	# server 127.0.0.1:8770 weight=1;
	# host.docker.internal : docker 中代指 宿主机本机的IP
	server host.docker.internal:8770 weight=1;
	# server {{apiserver_host}}:{{apiserver_port}} weight=1;
}

location /xxxx/api {
    // ...
    proxy_pass http://xxxx_official_site_api_server/xxxx/api;
    // ...
}

docker logs nginx

docker ps -a
  • nginx 容器的基本使用与管理
# 查看容器进程、查找nginx对应的容器ID
docker ps -a

# 关闭该容器
docker stop nginx

# 删除该容器
docker rm nginx
 
# 删除正在运行的nginx容器
docker rm -f nginx

# 查看 nginx 容器的 运行日志
docker logs nginx

# 进入 nginx 容器内部
docker exec -it nginx bash
> ...

# 在 nginx 容器内部执行shell命令
docker exec -it nginx sh -c "ls -la /var/log/nginx"

Step4 测验:访问宿主机

curl http://127.0.0.1:80

使用浏览器打开 http://127.0.0.1:80 看到如下页面即表示部署成功:

2 卸载步骤

  • 停止运行容器
docker stop nginx
  • 删除该容器
docker rm nginx

3 附件:nginx container启用http协议/ssl认证(福利)

# 上传 SSL 证书
# mkdir -p /data/nginx/conf/cert
# unzip /www/packages/xxxx-web/12788873_xxxx.com.cn_nginx.zip -d /data/nginx/conf/cert/
#	// /data/nginx/conf/cert/xxxx.com.cn.pem
#	// /data/nginx/conf/cert/xxxx.com.cn.key


# 将 http/80 端口的所有流量重定向至 https/443 端口
vi /data/nginx/conf/conf.d/default.conf
	# [x] 1. 修改默认监听的 80 端口 为 81 端口
	# 2. 注释如下代码片段:
  # location / {
  #    root   /usr/share/nginx/html;
  #    index  index.html index.htm;
  #}
  # 3. 更新如下配置项:
  #server_name  localhost;
  #server_name www.example1.com example1.com;
  server_name xxxx.com.cn;
  # 4. 新增如下配置项:
  # Redirect all HTTP traffic to HTTPS
  return 301 https://$server_name$request_uri;

touch /data/nginx/conf/conf.d/xxxx.com.cn.conf

vi /data/nginx/conf/conf.d/xxxx.com.cn.conf

编辑内容如下:

server {
	listen       443 ssl;
	# listen       80;
	server_name  localhost;

	# ssl_certificate      /data/nginx/conf/cert/xxxx.com.cn.pem;
	# ssl_certificate_key  /data/nginx/conf/cert/xxxx.com.cn.key;
	ssl_certificate      /etc/nginx/cert/xxxx.com.cn.pem;
	ssl_certificate_key  /etc/nginx/cert/xxxx.com.cn.key;

	ssl_session_cache    shared:SSL:1m;
	ssl_session_timeout  5m;

	ssl_ciphers  HIGH:!aNULL:!MD5;
	ssl_prefer_server_ciphers  on;

	location / {
	    # root /www/nginx/html/yyyy-web/;
        root /usr/share/nginx/html;
		# root   /www/wwwroot/love_connect/;
		# index  index.html index.htm;
	}

	# 引入相关配置
	# include /data/nginx/conf/conf.d/xxxx.com.cn.locations/*.conf;
	include /etc/nginx/conf.d/xxxx.com.cn.locations/*.conf;
}

upstream yyyy_official_site_api_server {
	ip_hash;
	# server 127.0.0.1:8770 weight=1;
	# host.docker.internal : docker 中代指 宿主机本机的IP
	server host.docker.internal:8770 weight=1;
	# server {{apiserver_host}}:{{apiserver_port}} weight=1;
}
mkdir -p /data/nginx/conf/conf.d/xxxx.com.cn.locations/

touch /data/nginx/conf/conf.d/xxxx.com.cn.locations/

vi /data/nginx/conf/conf.d/xxxx.com.cn.locations/yyyy-official-site-api.conf

编辑内容如下:

#PROXY-START/
location /yyyy/api {
    proxy_pass http://yyyy_official_site_api_server/yyyy/api;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    #proxy_set_header Connection $connection_upgrade;
    proxy_http_version 1.1;
    # proxy_hide_header Upgrade;

    add_header X-Cache $upstream_cache_status;
    #Set Nginx Cache

    set $static_fileymjeWjlG 0;
    if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
    {
        set $static_fileymjeWjlG 1;
        expires 1m;
    }
    if ( $static_fileymjeWjlG = 0 )
    {
        add_header Cache-Control no-cache;
    }
}
#PROXY-END/
docker stop nginx

docker rm nginx

docker run \
-p 80:80 \
-p 443:443 \
--add-host host.docker.internal:host-gateway \
--name nginx \
-v /data/nginx/conf/:/etc/nginx/ \
-v /data/nginx/log:/var/log/nginx \
-v /data/nginx/html:/usr/share/nginx/html \
-d nginx:1.24.0

# docker start nginx

docker ps

docker logs -f --tail 20 nginx

4 附件:利用/rootHtml/index.html重定向至目标路径(福利)

/data/nginx/html/index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>xxxx</title>
        <style>
            html { color-scheme: light dark; }
        </style>
    </head>
<body>

</body>
<script type="text/javascript" charset="utf-8" >
  window.location.href = "https://xxxx.com.cn/xxxx";
</script>
</html>

5 附件:生成自签发的SSL证书

# 总思路: 生成自签发的SSL证书(私钥 server.key + 公钥 server.crt + 合成证书 server.pem )
mkdir -p /root/nginx-certs
cd /root/nginx-certs

## step1 创建一个名为server.key的2048位RSA私钥文件
openssl genrsa -out server.key 2048

## step2 生成证书签名请求(CSR) | 系统会提示你输入一些信息,如国家代码、地区、组织名称,密码等。这些信息将用于生成证书(也可不设置密码)
openssl req -new -key server.key -out server.csr

## step3 使用CSR文件和私钥文件生成自签名证书(server.crt) | 创建一个有效期为365天的自签名证书,并将其保存为server.crt
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt

## step4 直接将证书和私钥合并到server.pem
cat server.key server.crt > server.pem
  • server.key : 私钥文件,通常只包含服务器的私有密钥,需严格保护
  • server.pem : 通常包含服务器的公钥证书和私钥,有时甚至包括CA颁发的中间证书。这种格式的文件用于方便地在配置Web服务器(如Nginx或Apache)时一次性提供证书和私钥。
  • server.pem : 可以被看作是一个包含了server.crt(证书)和server.key(私钥)的合并文件。
  • server.crt : 通常是指一个公钥证书(Public Key Certificate),也称为SSL证书或数字证书。这个文件包含了服务器的公钥信息,以及由证书颁发机构(CA)签发的证书,它用于在SSL/TLS握手过程中验证服务器的身份,并确保服务器的公钥是可信的。

X 参考文献

  • docker
  • 历往教程
  • 其他
posted @ 2024-03-18 22:25  千千寰宇  阅读(636)  评论(0编辑  收藏  举报