当前位置: 首页 > news >正文

基于 Docker 的 Nginx + OpenSSL 自签名证书启用 HTTPS

基于 Docker 的 Nginx + OpenSSL 自签名证书启用 HTTPS(按步骤、可直接复制)

目标:在没有域名的情况下,基于 Docker 部署 Nginx,使用 OpenSSL 生成自签名证书,启用 https://<你的公网IP> 访问。
适用:开发/测试或内部环境(生产请使用域名 + CA 证书)。


0. 前置条件(Prerequisites)

  • 一台可用的 Linux 服务器,已安装 Docker(和 docker compose / docker-compose 二选一)。
  • 服务器具备公网 IP(文档示例统一用 1.2.3.4,请替换为你的实际 IP)。
  • 宿主机有 openssl(若没有,文中也提供容器方式)。
  • 当前没有名为 nginx 的容器在运行(我们将先暂时创建一个 nginx-temp 来导出默认配置,然后删除它)。

1. 准备宿主机目录结构

在宿主机上创建挂载目录:

mkdir -p /data/nginx/{conf,conf.d,log,ssl,static}

目录说明:

/data/nginx/
├── conf/        # 全局 nginx.conf(将从临时容器拷出)
├── conf.d/      # 站点配置(将从临时容器拷出 default.conf,并新增 https-ip.conf)
├── log/         # 日志
├── ssl/         # 证书文件(稍后生成 server.key/server.crt,以及 ip.cnf)
└── static/      # 静态资源(先拷贝默认 index.html,便于验证)

2. 启动临时容器并拷贝默认文件(有容器才能 cp)

这一步只为获取官方默认的配置文件与首页,方便你基于其修改;完成后会删除临时容器。

# 启动临时 nginx 容器(名称:nginx-temp)
docker run -d --name nginx-temp nginx:latest# 从临时容器拷贝默认配置与首页到宿主机
docker cp nginx-temp:/etc/nginx/nginx.conf /data/nginx/conf/nginx.conf
docker cp nginx-temp:/etc/nginx/conf.d/default.conf /data/nginx/conf.d/default.conf
docker cp nginx-temp:/usr/share/nginx/html/index.html /data/nginx/static/index.html# 停止并删除临时容器
docker rm -f nginx-temp

如果你已经对 Nginx 很熟悉,也可以跳过拷贝,直接使用自定义模板。但由于你提出要使用 docker cp,这里按你的要求保留该流程。


3. 为 HTTPS 新增站点配置(conf.d/https-ip.conf)

我们将新建一个 https-ip.conf,让 80 端口跳转到 443,并在 443 上启用 SSL。

cat > /data/nginx/conf.d/https-ip.conf <<'EOF'
server {listen 80;server_name _;return 301 https://$host$request_uri;
}server {listen 443 ssl;server_name _;  # 或直接写你的公网 IP,例如 1.2.3.4ssl_certificate     /etc/nginx/ssl/server.crt;ssl_certificate_key /etc/nginx/ssl/server.key;ssl_protocols       TLSv1.2 TLSv1.3;ssl_ciphers         HIGH:!aNULL:!MD5;location / {root   /usr/share/nginx/html;index  index.html;}
}
EOF

🔎 如何正确退出 cat

执行 cat > ... <<'EOF' 之后:

  1. 粘贴或输入上面的内容;
  2. 在新的一行输入 EOF,再按回车
  3. cat自动结束并保存文件。

常见误区:EOFwq:wqvim 的用法,不是 cat 的用法。

⚠️ 提示:conf.d/default.conf 中通常也有一个 server { listen 80; ... },与我们新建的 https-ip.conf 会“重复”。若你只希望所有请求都跳转到 HTTPS,建议删除默认文件:

rm -f /data/nginx/conf.d/default.conf

4. 生成自签名证书(含 SAN)

现代浏览器要求证书包含 Subject Alternative Name (SAN)。先创建 OpenSSL 配置文件,再生成证书。

4.1 写入 OpenSSL 配置(ip.cnf)

cat > /data/nginx/ssl/ip.cnf <<'EOF'
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn[dn]
CN = 1.2.3.4[req_ext]
subjectAltName = @alt_names[alt_names]
IP.1 = 1.2.3.4
EOF

退出方法:同上,在新行单独输入 EOF + 回车。

请把 1.2.3.4 替换为你的公网 IP。不要在该文件里写中文注释,否则旧版本 OpenSSL 可能解析失败。

4.2 生成证书与私钥(宿主机执行)

cd /data/nginx/sslopenssl req -x509 -nodes -days 365 \-newkey rsa:2048 \-keyout server.key \-out server.crt \-config ip.cnf# 确认文件已生成
ls -l /data/nginx/ssl
# 应包含:server.key  server.crt  ip.cnf

可选:用容器生成(无 SAN,不推荐)

docker run --rm -v /data/nginx/ssl:/ssl alpine/openssl \sh -c "openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /ssl/server.key -out /ssl/server.crt -subj '/CN=1.2.3.4'"

该方式省事,但通常不含 SAN,某些浏览器会报名称不匹配,建议优先使用上面的 ip.cnf 方案。


5. 编写 docker-compose.yml 并启动正式容器

我们现在有了:配置文件(conf/nginx.conf、conf.d/.conf)以及证书(ssl/)。下一步创建 docker-compose.yml 并启动正式 nginx 容器(容器名:nginx)。

cat > /data/nginx/docker-compose.yml <<'EOF'
version: '3.9'services:nginx:image: nginx:latestcontainer_name: nginxrestart: alwaysports:- "80:80"- "443:443"volumes:- ./static:/usr/share/nginx/html- ./conf/nginx.conf:/etc/nginx/nginx.conf- ./conf.d:/etc/nginx/conf.d- ./log:/var/log/nginx- ./ssl:/etc/nginx/ssl
EOF

退出方法:同样在新行输入 EOF + 回车。

启动服务:

cd /data/nginx
docker compose up -d        # 如果是旧版,可用:docker-compose up -d

6. 验证与重载

docker exec -it nginx nginx -t
docker exec -it nginx nginx -s reload

如需查看日志:

docker logs nginx

7. 测试访问

浏览器打开:

https://1.2.3.4

第一次会出现 “证书不受信任” 的提示(因为是自签名证书),继续访问即可看到默认首页。

若你希望消除浏览器警告,可把 /data/nginx/ssl/server.crt 导入到你电脑系统/浏览器的受信任根证书中(不同系统导入方法略有差异)。


8. 常见问题(FAQ)

Q1:cannot load certificate "/etc/nginx/ssl/server.crt"
A:检查 compose 是否挂载了证书目录(./ssl:/etc/nginx/ssl),并确认 /data/nginx/ssl/server.crt 存在。进入容器查看:

docker exec -it nginx ls -l /etc/nginx/ssl

Q2:ip.cnf 报错 missing equal sign
A:确认每行均为 key = value 格式;不要写中文注释;严格按示例粘贴。

Q3:Here Document 结束写错
A:结束行必须单独EOF;不要写 EOFwq:wq

Q4:80 端口没有跳转到 443
A:确认 https-ip.conf 中包含 80 跳转 server;并避免与 default.conf 冲突(必要时删除 default.conf)。

Q5:我已经有自己的首页
A:直接把你的网站文件放到 /data/nginx/static/ 即可覆盖默认 index.html


9. 命令速查(一屏总结)

# 目录
mkdir -p /data/nginx/{conf,conf.d,log,ssl,static}# 临时容器 -> 拷贝默认配置与首页 -> 清理
docker run -d --name nginx-temp nginx:latest
docker cp nginx-temp:/etc/nginx/nginx.conf /data/nginx/conf/nginx.conf
docker cp nginx-temp:/etc/nginx/conf.d/default.conf /data/nginx/conf.d/default.conf
docker cp nginx-temp:/usr/share/nginx/html/index.html /data/nginx/static/index.html
docker stop nginx-temp && docker rm nginx-temp
rm -f /data/nginx/conf.d/default.conf   # 如只需 HTTPS 跳转,建议删掉默认站点# 新建 HTTPS 站点配置(80 跳 443)
cat > /data/nginx/conf.d/https-ip.conf <<'EOF'
server {listen 80;server_name _;return 301 https://$host$request_uri;
}
server {listen 443 ssl;server_name _;ssl_certificate     /etc/nginx/ssl/server.crt;ssl_certificate_key /etc/nginx/ssl/server.key;ssl_protocols       TLSv1.2 TLSv1.3;ssl_ciphers         HIGH:!aNULL:!MD5;location / { root /usr/share/nginx/html; index index.html; }
}
EOF# 生成证书(含 SAN)
cat > /data/nginx/ssl/ip.cnf <<'EOF'
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[dn]
CN = 1.2.3.4
[req_ext]
subjectAltName = @alt_names
[alt_names]
IP.1 = 1.2.3.4
EOFcd /data/nginx/ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt -config ip.cnf# docker-compose.yml
cat > /data/nginx/docker-compose.yml <<'EOF'
version: '3.9'
services:nginx:image: nginx:latestcontainer_name: nginxrestart: alwaysports:- "80:80"- "443:443"volumes:- ./static:/usr/share/nginx/html- ./conf/nginx.conf:/etc/nginx/nginx.conf- ./conf.d:/etc/nginx/conf.d- ./log:/var/log/nginx- ./ssl:/etc/nginx/ssl
EOF# 启动与验证
cd /data/nginx
docker compose up -d
docker exec -it nginx nginx -t
docker exec -it nginx nginx -s reload
echo "Open https://1.2.3.4 in your browser"

完成! 以上步骤保证顺序清晰:先有临时容器用于 docker cp,再写 HTTPS 站点与证书,最后用 compose 启动正式容器。祝你部署顺利!

http://www.hskmm.com/?act=detail&tid=17815

相关文章:

  • 基于STM32的正弦波逆变器设计
  • 高校固定资产管理高效的系统——Java EE毕业设计资源包
  • ======================================分割线======================================
  • 标准卷积和空洞卷积--适应不同尺寸的输入--ASPP模块
  • 游戏在高负载场景下,整机功耗控制在多少
  • 打印机状态错误,怎么恢复正常打印?
  • 使用Ollama 0.12.2本地部署大模型,友好界面对话,开启飞行模式数据完全存在本地
  • 牛客刷题-Day5
  • 用标准版平板干翻上代Pro,小米又想学苹果了?
  • VonaJS多租户同时支持共享模式和独立模式
  • 记录一下第一次为Dify贡献插件的经历
  • 物联网字节校验常用方法
  • STM32H743-ARM例程2-UART命令控制LED - 实践
  • 完整教程:Zookeeper与Kafka:分布式系统中的协调与消息队列
  • vite-vue3 项目优化首屏加载速度
  • 12_TCP和UDP实现服务端和客户端的通信
  • 各种软件的官方文档和安装包下载地址记录
  • 基于导频的OFDM系统的信道估计(使用LS估计算法)
  • Day22super详解
  • 外发图纸如何控制的最佳实践与注意事项
  • Gitee:中国开发者生态的数字底座正在重构技术格局
  • 快递100
  • 文件同步软件是什么?主要有哪几种类型?
  • “铸网2025”山东省工业和互联网CTF竞赛-web
  • 领嵌iLeadE-588网关AI边缘计算盒子一键部署二次开发
  • 2025年值得选的文件摆渡系统品牌解析
  • 全球知名的Java Web开发平台Vaadin上线慧都网!
  • C#实现与欧姆龙PLC通信
  • linux docker 配置外网拉镜像
  • 什么是跨网文件摆渡系统?IT运维效率提升300%的秘密武器