Docker 部署 Nginx HTTPS 服务详细步骤
1. 准备工作
1.1 创建项目目录结构
mkdir -p nginx-https/{conf,cert,html,logs}
cd nginx-https
1.2 生成 SSL 证书(自签名证书用于测试)
# 生成私钥
openssl genrsa -out cert/nginx.key 2048
# 生成证书签名请求
openssl req -new -key cert/nginx.key -out cert/nginx.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Test/OU=Test/CN=localhost"
# 生成自签名证书(有效期365天)
openssl x509 -req -days 365 -in cert/nginx.csr -signkey cert/nginx.key -out cert/nginx.crt
2. 配置 Nginx
2.1 创建 Nginx 配置文件
创建 conf/nginx.conf:
# 主配置文件
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
# HTTPS 服务器配置
server {
listen 443 ssl http2;
server_name localhost;
# SSL 证书配置
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
# SSL 优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
# 启用 SSL 会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS 头(生产环境建议开启)
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 根目录配置
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# 健康检查端点
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name localhost;
# 重定向所有 HTTP 请求到 HTTPS
return 301 https://$server_name$request_uri;
# 或者提供不同的响应
# location / {
# rewrite ^ https://$server_name$request_uri permanent;
# }
}
}
2.2 创建默认首页
创建 html/index.html:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Nginx HTTPS 服务</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
text-align: center;
}
.success {
color: green;
font-size: 24px;
margin: 20px 0;
}
.info {
background-color: #f5f5f5;
padding: 15px;
border-radius: 5px;
margin: 20px 0;
}
</style>
</head>
<body>
<h1>Nginx HTTPS 服务已成功部署!</h1>
<div class="success">🔒 HTTPS 连接正常</div>
<div class="info">
<p>服务器时间: <span id="time"></span></p>
<p>协议: <span id="protocol"></span></p>
</div>
<script>
document.getElementById('time').textContent = new Date().toLocaleString();
document.getElementById('protocol').textContent = window.location.protocol;
</script>
</body>
</html>
3. Docker 部署
3.1 创建 Dockerfile
创建 Dockerfile:
# 使用官方 Nginx 镜像
FROM nginx:alpine
# 安装必要工具(可选)
RUN apk add --no-cache bash curl
# 复制配置文件
COPY conf/nginx.conf /etc/nginx/nginx.conf
# 复制 SSL 证书
COPY cert/nginx.crt /etc/nginx/ssl/nginx.crt
COPY cert/nginx.key /etc/nginx/ssl/nginx.key
# 复制网站文件
COPY html/ /usr/share/nginx/html/
# 设置目录权限
RUN chmod 644 /etc/nginx/ssl/nginx.crt && \
chmod 600 /etc/nginx/ssl/nginx.key && \
chown -R nginx:nginx /usr/share/nginx/html
# 暴露端口
EXPOSE 80 443
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f https://localhost/health || exit 1
# 使用非 root 用户运行
USER nginx
# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]
3.2 创建 docker-compose.yml
创建 docker-compose.yml:
version: '3.8'
services:
nginx-https:
build: .
container_name: nginx-https
ports:
- "80:80" # HTTP 端口
- "443:443" # HTTPS 端口
volumes:
# 配置文件挂载(开发时方便修改)
- ./conf/nginx.conf:/etc/nginx/nginx.conf:ro
- ./cert:/etc/nginx/ssl:ro
- ./html:/usr/share/nginx/html:ro
# 日志持久化
- ./logs:/var/log/nginx
restart: unless-stopped
networks:
- nginx-network
networks:
nginx-network:
driver: bridge
3.3 构建和运行容器
方式一:使用 Docker Compose(推荐)
# 构建并启动服务
docker-compose up -d --build
# 查看运行状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 停止服务
docker-compose down
方式二:使用 Docker 命令
# 构建镜像
docker build -t nginx-https .
# 运行容器
docker run -d \
--name nginx-https \
-p 80:80 \
-p 443:443 \
-v $(pwd)/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
-v $(pwd)/cert:/etc/nginx/ssl:ro \
-v $(pwd)/html:/usr/share/nginx/html:ro \
-v $(pwd)/logs:/var/log/nginx \
--restart unless-stopped \
nginx-https
# 查看运行状态
docker ps
# 查看日志
docker logs -f nginx-https
# 进入容器
docker exec -it nginx-https sh
# 停止容器
docker stop nginx-https
docker rm nginx-https
4. 验证部署
4.1 测试 HTTPS 连接
# 使用 curl 测试
curl -k https://localhost
# 或详细测试
curl -v -k https://localhost
# 检查 SSL 证书信息
openssl s_client -connect localhost:443 -servername localhost < /dev/null 2>/dev/null | openssl x509 -noout -dates
4.2 测试 HTTP 重定向
# 应该被重定向到 HTTPS
curl -v http://localhost
4.3 健康检查
curl https://localhost/health
5. 生产环境优化
5.1 使用 Let's Encrypt 证书(自动续期)
创建 docker-compose-prod.yml:
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: nginx-prod
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./html:/usr/share/nginx/html:ro
- ./certbot/www:/var/www/certbot:ro
- ./certbot/conf:/etc/letsencrypt:ro
networks:
- web-network
restart: unless-stopped
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./certbot/www:/var/www/certbot
- ./certbot/conf:/etc/letsencrypt
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
networks:
- web-network
networks:
web-network:
driver: bridge
5.2 使用配置文件模板
创建 conf/nginx.conf.template:
# 使用环境变量
server {
listen ${NGINX_PORT} ssl;
server_name ${NGINX_HOST};
ssl_certificate ${SSL_CERT_PATH};
ssl_certificate_key ${SSL_KEY_PATH};
# ... 其他配置
}
6. 常用命令和脚本
6.1 一键部署脚本
创建 deploy.sh:
#!/bin/bash
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
echo -e "${GREEN}开始部署 Nginx HTTPS 服务...${NC}"
# 1. 检查目录结构
echo "检查目录结构..."
for dir in conf cert html logs; do
if [ ! -d "$dir" ]; then
mkdir -p "$dir"
echo "创建目录: $dir"
fi
done
# 2. 生成证书(如果不存在)
if [ ! -f "cert/nginx.crt" ] || [ ! -f "cert/nginx.key" ]; then
echo "生成 SSL 证书..."
openssl genrsa -out cert/nginx.key 2048
openssl req -new -key cert/nginx.key -out cert/nginx.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Test/OU=Test/CN=localhost"
openssl x509 -req -days 365 -in cert/nginx.csr \
-signkey cert/nginx.key -out cert/nginx.crt
rm cert/nginx.csr
fi
# 3. 构建镜像
echo "构建 Docker 镜像..."
docker-compose build
# 4. 启动服务
echo "启动服务..."
docker-compose up -d
# 5. 验证部署
echo "验证服务..."
sleep 3
if curl -k -s https://localhost > /dev/null; then
echo -e "${GREEN}✅ Nginx HTTPS 服务部署成功!${NC}"
echo -e "访问地址: ${GREEN}https://localhost${NC}"
else
echo -e "${RED}❌ 服务启动失败,请检查日志${NC}"
docker-compose logs nginx-https
fi
6.2 备份和恢复脚本
创建 backup.sh:
#!/bin/bash
# 备份配置和证书
BACKUP_DIR="backup_$(date +%Y%m%d_%H%M%S)"
mkdir -p $BACKUP_DIR
cp -r conf cert html $BACKUP_DIR/
tar -czf $BACKUP_DIR.tar.gz $BACKUP_DIR
echo "备份完成: $BACKUP_DIR.tar.gz"
7. 故障排查
常见问题解决:
端口冲突
# 查看占用端口的进程
lsof -i :80
lsof -i :443
# 或使用
netstat -tlnp | grep :80
证书问题
# 检查证书格式
openssl x509 -in cert/nginx.crt -text -noout
# 验证证书链
openssl verify -CAfile cert/nginx.crt cert/nginx.crt
查看 Nginx 配置语法
docker exec nginx-https nginx -t
查看容器日志
docker logs nginx-https
docker-compose logs
项目结构
nginx-https/
├── Dockerfile
├── docker-compose.yml
├── deploy.sh
├── backup.sh
├── conf/
│ └── nginx.conf
├── cert/
│ ├── nginx.key
│ └── nginx.crt
├── html/
│ └── index.html
└── logs/
├── access.log
└── error.log
这样你就完成了一个完整的 Docker 化 Nginx HTTPS 服务部署方案,包含开发和生产环境配置、自动化脚本和故障排查指南。