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

news/2025/9/26 11:39:49/文章来源:https://www.cnblogs.com/liubaojing/p/19113185

基于 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 stop nginx-temp && docker rm 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.mzph.cn/news/918199.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PolarFire Soc System Services

PolarFire Soc System ServicesPolarFire Family System Services User Guide1、读取 序列号 16 个字节 status = MSS_SYS_get_serial_number(data_buffer, MSS_SYS_MAILBOX_DATA_OFFSET);xprintf_hex( "devic…

抄袭的网站wordpress 授权插件

引言&#xff1a;中小企业推进数字化转型的背景是多重因素叠加的结果&#xff0c;包括市场竞争压力、信息技术发展及普及、各级政府政策支持及引导、企业经营发展需求和人才结构变化等。这些因素共同推动了中小企业加快数字化转型的步伐&#xff0c;以应对日益复杂多变的市场环…

网站建设视频下载哈尔滨seo优化专注

文章目录 前言一、MyBatis 与 Hibernate 有哪些不同&#xff1f;二、MyBatis 的好处是什么&#xff1f;三、简述 Mybatis 的 Xml 映射文件和 Mybatis 内部数据结构之间的映射关系&#xff1f;四、什么是 MyBatis 的接口绑定,有什么好处&#xff1f;五、接口绑定有几种实现方式,…

基于STM32的正弦波逆变器设计

一、系统架构设计 graph TD A[输入电源] --> B[输入滤波电路] B --> C[DC-DC升压模块] C --> D[SPWM生成模块] D --> E[全桥逆变电路] E --> F[LC滤波电路] F --> G[输出保护电路] G --> H[负载]…

深入解析:SDL2视频渲染

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

高校固定资产管理高效的系统——Java EE毕业设计资源包

高校固定资产管理高效的系统——Java EE毕业设计资源包pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&q…

======================================分割线======================================

======================================分割线====================================== ======================================分割线====================================== ===================================…

OpenLayers地图交互 -- 章节六:范围交互详解 - 实践

OpenLayers地图交互 -- 章节六:范围交互详解 - 实践2025-09-26 11:34 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; dis…

互联网公司网站源码优设网专利

Kubernates容器化JVM调优笔记&#xff08;内存篇&#xff09; 先说结论背景思路方案 先说结论 1、首先如果是JDK8&#xff0c;需要使用JDK8_191版本以上&#xff0c;才支持容器化环境和以下参数&#xff0c;否则就更新到JDK10以上&#xff0c;选择对应的镜像构建就行了 2、在容…

标准卷积和空洞卷积--适应不同尺寸的输入--ASPP模块

https://zhuanlan.zhihu.com/p/50369448 重要的是感受野 多尺度特征提取:通过不同空洞率的卷积层捕获不同范围的特征 保持空间分辨率:采用适当的padding策略,确保输出特征图尺寸与输入一致 全局上下文信息:通过全局…

游戏在高负载场景下,整机功耗控制在多少

1)游戏在高负载场景下,整机功耗控制在多少合理2)什么是MALLOC_SMALL和MALLOC_NANO,如何优化3)Spine堆内存占用高怎么办这是第446篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技…

打印机状态错误,怎么恢复正常打印?

众所周知,打印机这家伙时不时就会莫名出点毛病,什么打印一团乱麻,喷墨或是直接无法使用,有时候对着它来上几次爱的抚摸就能解决问题,但大部分时候还是要挨个排查问题,很是麻烦。其实这类问题大多和驱动异常、服务…

使用Ollama 0.12.2本地部署大模型,友好界面对话,开启飞行模式数据完全存在本地

之前写过一篇Ollama的介绍C#使用OllamaSharp调用Llama 3、Phi 3等大语言模型。那个时候Ollama还是没有界面对话的。需要再命令行下载需要的大模型,对话输出的内容也是在命令行显示,格式比较单一。 最新的0.12.2安装包…

7timer.info 免费天气预报对接记录

import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.web.client.RestTemplate;import java.time.*; import java.time.format.DateTi…

招聘网站开发程序员做国外订单的网站

环境 Python3&#xff0c; gensim&#xff0c;jieba&#xff0c;numpy &#xff0c;pandas 原理&#xff1a;文章转成向量&#xff0c;然后在计算两个向量的余弦值。 Gensim gensim是一个python的自然语言处理库&#xff0c;能够将文档根据TF-IDF, LDA, LSI 等模型转化成向量模…

牛客刷题-Day5

动态规划1:线性dp、背包问题,区间 https://ac.nowcoder.com/acm/contest/24213?from=acdiscussn牛客刷题-Day5 今日刷题:\(1021-1025\) 1021 失衡天平 题目描述 终于 \(Alice\) 走出了大魔王的陷阱,可是现在傻傻的…

详细介绍:四大金刚之计算机网络

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

用标准版平板干翻上代Pro,小米又想学苹果了?

9月20日,小米合伙人卢伟冰在直播中揭晓了小米平板8系列的完整配置。 从整体配置到系列产品来看,小米平板8的发布再次印证了小米的产品策略:用标准版打上代Pro。 这熟悉的配方,熟悉的味道,不禁让人想起了大洋彼岸的…

VonaJS多租户同时支持共享模式和独立模式

VonaJS 通过多实例的概念来支持多租户 SAAS 系统的开发。只需启动一个后端服务,即可支持多个实例同时运行。同时支持共享模式和独立模式。多实例/多租户 VonaJS 通过多实例的概念来支持多租户 SAAS 系统的开发。只需启…

记录一下第一次为Dify贡献插件的经历

最近Dify上线了一个新功能——知识管道(Knowledge Pipeline)。知识管道可以像乐高一样编排你的信息,以数据源(Data Source)作为起始节点,以知识库节点作为结束节点。其一般步骤为:从数据源导入文档 -> 使用抽…