Docker部署NGINX反向代理
🧑💻 User
我有一台云服务器A,IP地址为47.99.145.66。企业内部有一台算力服务器B,通过DDNS将本地3001端口转发到tsiliang.com:3001。我想在A中使用docker部署NGINX服务,实现用户访问ai.tsiliang.com,实际服务为B的3001端口服务,保护算力服务器的安全。
🤖 Assistant
已深度思考
我们想要实现的是:用户访问ai.tsiliang.com时,通过云服务器A上的Nginx反向代理到企业内部算力服务器B的3001端口服务(通过DDNS域名tsiliang.com:3001访问)。步骤:
1. 在云服务器A上使用Docker部署Nginx。
2. 配置Nginx,将对ai.tsiliang.com的请求转发到tsiliang.com:3001。
3. 确保云服务器A的Nginx配置正确,并且能够解析ai.tsiliang.com到云服务器A的IP。
注意:由于算力服务器B是通过DDNS将本地3001端口转发到tsiliang.com:3001,所以我们可以通过tsiliang.com:3001来访问B的服务。
我们需要做的是:
- 在云服务器A上,使用Docker运行Nginx,并配置一个反向代理服务器块(server block),将请求代理到tsiliang.com:3001。
- 同时,我们需要确保域名ai.tsiliang.com的DNS记录指向云服务器A的IP地址(47.99.145.66)。
下面我们来实现Docker部署Nginx并配置反向代理。
首先,在云服务器A上创建一个目录,用于存放Nginx配置文件和日志等。
例如,我们创建目录:/home/nginx/conf,并在其中创建nginx.conf文件。
但是,为了简单起见,我们可以先创建一个简单的nginx.conf,然后通过Docker卷挂载到容器中。
假设我们使用以下目录结构:
/home/nginx/
├── conf/
│ └── nginx.conf
├── logs/
└── html/
现在,我们编写nginx.conf文件,内容如下:
方案设计
1. 创建目录结构
# 在云服务器A上创建目录
mkdir -p ~/nginx-proxy/{conf,logs,html}
cd ~/nginx-proxy
2. 创建NGINX配置文件
创建 conf/nginx.conf
文件:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
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;
tcp_nopush on;
keepalive_timeout 65;
types_hash_max_size 2048;
# 上游服务器配置
upstream backend_server {
server tsiliang.com:3001;
keepalive 32;
}
# 主服务器配置
server {
listen 80;
server_name ai.tsiliang.com;
# 安全头部
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
# 反向代理配置
location / {
proxy_pass http://backend_server;
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 X-Forwarded-Proto $scheme;
# 超时设置
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# 缓冲区设置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
# 禁用代理缓存(适用于动态内容)
proxy_no_cache 1;
proxy_cache_bypass 1;
}
# 健康检查端点
location /nginx-health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 拒绝访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
}
3. 创建Docker Compose文件
创建 docker-compose.yml
:
version: '3.8'
services:
nginx-proxy:
image: nginx:alpine
container_name: nginx-proxy
restart: unless-stopped
ports:
- "80:80"
# 如果需要HTTPS,添加:"443:443"
volumes:
- ./conf/nginx.conf:/etc/nginx/nginx.conf:ro
- ./logs:/var/log/nginx
- ./html:/usr/share/nginx/html
environment:
- TZ=Asia/Shanghai
networks:
- nginx-network
networks:
nginx-network:
driver: bridge
4. 部署和启动
# 启动服务
docker-compose up -d
# 查看日志
docker-compose logs -f
# 检查服务状态
docker-compose ps
5. 增强安全配置(可选)
创建 conf/security.conf
用于额外的安全配置:
# 限制请求方法
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 405;
}
# 限制请求大小
client_max_body_size 10m;
# 隐藏Nginx版本号
server_tokens off;
# 限制连接频率
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 100;
6. 监控和日志(可选)
创建简单的监控脚本 monitor.sh
:
#!/bin/bash
# 监控NGINX状态
CONTAINER_NAME="nginx-proxy"
check_nginx() {
if docker exec $CONTAINER_NAME nginx -t > /dev/null 2>&1; then
echo "$(date): NGINX configuration is valid"
else
echo "$(date): ERROR - NGINX configuration is invalid"
fi
}
check_response() {
response=$(curl -s -o /dev/null -w "%{http_code}" http://ai.tsiliang.com/nginx-health)
if [ "$response" = "200" ]; then
echo "$(date): Service is healthy"
else
echo "$(date): ERROR - Service response: $response"
fi
}
# 执行检查
check_nginx
check_response
7. 域名解析配置
确保您的域名解析设置正确:
ai.tsiliang.com
A记录指向47.99.145.66
8. 验证配置
# 测试NGINX配置
docker exec nginx-proxy nginx -t
# 检查容器状态
docker ps | grep nginx-proxy
# 测试代理是否工作
curl -H "Host: ai.tsiliang.com" http://localhost
安全优势
- 隐藏后端服务器:用户只看到云服务器A,不知道后端算力服务器B的存在
- 访问控制:可以在NGINX层面实现IP白名单、速率限制等
- Docker隔离:服务运行在容器中,与宿主机隔离
- 日志记录:所有访问请求都有完整日志
- 易于维护:配置文件和证书更新方便
后续扩展
如果需要HTTPS支持,可以:
- 申请SSL证书
- 修改NGINX配置监听443端口
- 配置SSL证书路径
- 设置HTTP到HTTPS的重定向
这个方案既保护了您的算力服务器安全,又提供了良好的可维护性和扩展性。
🧑💻 User
不使用docker compose
🤖 Assistant
已深度思考
由于用户要求不使用docker compose,我们将直接使用docker run命令来部署nginx容器。同时,我们假设云服务器A上已经安装了docker。
步骤:
1. 在云服务器A上创建必要的目录和配置文件。
2. 使用docker run命令启动nginx容器,并挂载配置文件和日志目录。
注意:我们将使用之前创建的nginx配置文件,但需要稍作调整以适应直接使用docker run的情况。
我们先创建目录和配置文件:
在云服务器A上:
创建目录:~/nginx-proxy/conf, ~/nginx-proxy/logs, ~/nginx-proxy/html
将nginx.conf放在~/nginx-proxy/conf/下。
然后使用以下docker run命令:
但是注意,我们之前创建的nginx.conf中已经指定了上游服务器为tsiliang.com:3001,并且监听80端口,服务器名为ai.tsiliang.com。
由于我们使用docker运行,需要将容器的80端口映射到宿主机的80端口(如果宿主机80端口已被占用,可以映射到其他端口,但域名解析需要对应修改)。
假设我们使用宿主机的80端口,那么命令如下:
1. 创建目录结构
# 在云服务器A上创建目录
mkdir -p ~/nginx-proxy/{conf,logs,html}
cd ~/nginx-proxy
2. 创建NGINX配置文件
创建 conf/nginx.conf
文件:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
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;
tcp_nopush on;
keepalive_timeout 65;
types_hash_max_size 2048;
# 上游服务器配置
upstream backend_server {
server tsiliang.com:3001;
keepalive 32;
}
# 主服务器配置
server {
listen 80;
server_name ai.tsiliang.com;
# 安全头部
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# 反向代理配置
location / {
proxy_pass http://backend_server;
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 X-Forwarded-Proto $scheme;
# 超时设置
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# 缓冲区设置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
# 禁用代理缓存
proxy_no_cache 1;
proxy_cache_bypass 1;
}
# 健康检查端点
location /nginx-health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 拒绝访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
}
3. 使用 Docker 运行 NGINX
直接运行命令:
docker run -d \
--name nginx-proxy \
--restart unless-stopped \
-p 80:80 \
-v ~/nginx-proxy/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
-v ~/nginx-proxy/logs:/var/log/nginx \
-v ~/nginx-proxy/html:/usr/share/nginx/html \
-e TZ=Asia/Shanghai \
nginx:alpine
或者创建启动脚本
创建 start-nginx.sh
文件:
#!/bin/bash
# 停止并删除现有容器
docker stop nginx-proxy 2>/dev/null
docker rm nginx-proxy 2>/dev/null
# 启动新的NGINX容器
docker run -d \
--name nginx-proxy \
--restart unless-stopped \
-p 80:80 \
-v ~/nginx-proxy/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
-v ~/nginx-proxy/logs:/var/log/nginx \
-v ~/nginx-proxy/html:/usr/share/nginx/html \
-e TZ=Asia/Shanghai \
nginx:alpine
echo "NGINX proxy started successfully!"
echo "Container name: nginx-proxy"
给脚本执行权限并运行:
chmod +x start-nginx.sh
./start-nginx.sh
4. 管理命令
查看容器状态
docker ps -f name=nginx-proxy
查看容器日志
# 查看实时日志
docker logs -f nginx-proxy
# 查看最近100行日志
docker logs --tail 100 nginx-proxy
进入容器检查配置
# 进入容器
docker exec -it nginx-proxy sh
# 在容器内测试NGINX配置
nginx -t
# 查看NGINX进程
ps aux | grep nginx
# 退出容器
exit
重启容器
docker restart nginx-proxy
停止容器
docker stop nginx-proxy
删除容器
docker rm nginx-proxy
5. 验证部署
测试NGINX配置
docker exec nginx-proxy nginx -t
测试代理功能
# 测试健康检查
curl http://localhost/nginx-health
# 测试代理(需要在DNS解析生效后)
curl -H "Host: ai.tsiliang.com" http://localhost
检查端口监听
netstat -tulpn | grep :80
# 或使用
ss -tulpn | grep :80
6. 更新配置时的操作流程
当需要修改NGINX配置时:
# 1. 修改配置文件
vi ~/nginx-proxy/conf/nginx.conf
# 2. 测试配置文件语法
docker exec nginx-proxy nginx -t
# 3. 重载NGINX配置(不重启容器)
docker exec nginx-proxy nginx -s reload
# 或者重启容器
docker restart nginx-proxy
7. 备份和恢复
备份配置和日志
# 备份整个nginx-proxy目录
tar -czf nginx-backup-$(date +%Y%m%d).tar.gz ~/nginx-proxy
# 只备份配置
cp -r ~/nginx-proxy/conf ~/nginx-backup-conf
从备份恢复
# 停止当前容器
docker stop nginx-proxy
docker rm nginx-proxy
# 恢复配置文件
cp -r ~/nginx-backup-conf/* ~/nginx-proxy/conf/
# 重新启动
./start-nginx.sh
优势说明
这个纯Docker方案:
- 简单直接:不需要安装Docker Compose
- 易于管理:使用标准的Docker命令管理
- 资源友好:容器轻量,基于Alpine Linux
- 灵活性高:可以轻松修改配置和挂载卷
- 自动重启:配置了
--restart unless-stopped
确保服务高可用
这样就完成了不使用Docker Compose的NGINX反向代理部署,可以有效保护您的算力服务器安全。