docker - nginx - proxy_pass + proxy_redirect

本文介绍如何通过修改Nginx配置实现URL重写,将项目域名的访问路径从/index.php控制器/动作形式,调整为/project/控制器/动作的形式。文章详细记录了在Docker环境下,针对laradock配置的调整过程,包括正确设置proxy_pass的目标地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目的:使项目域名 www.foo.test(/index.php)/controller/action 变为 www.foo.test/project/controller/action,仍然可以正常访问。(非index.php二级目录的URL重写)

背景:

           Name                          Command              State                   Ports                 
------------------------------------------------------------------------------------------------------------
laradock_docker-in-docker_1   dockerd-entrypoint.sh           Up      2375/tcp                              
laradock_mysql_1              docker-entrypoint.sh mysqld     Up      0.0.0.0:3306->3306/tcp                
laradock_nginx_1              nginx                           Up      0.0.0.0:443->443/tcp,                 
                                                                      0.0.0.0:80->80/tcp                    
laradock_php-fpm_1            docker-php-entrypoint php-fpm   Up      9000/tcp                              
laradock_workspace_1          /sbin/my_init                   Up      0.0.0.0:2222->22/tcp 

foo.conf 配置为

server {

    listen 80;
    listen [::]:80;

    server_name www.foo.test;
    root /var/www/foo/web;
    index index.php index.html index.htm;

    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }
    
    location ~ \.php$ {
        #try_files $uri /index.php =404;
        fastcgi_pass php-upstream;
        fastcgi_index index.php;
        #fastcgi_buffers 16 16k;
        #fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        #fixes timeouts
        #fastcgi_read_timeout 600;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt/;
        log_not_found off;
    }

    error_log /var/log/nginx/laravel_error.log;
    access_log /var/log/nginx/laravel_access.log;
}

解决:

foo.conf 配置里添加

location /project {
        proxy_pass http://127.0.0.1/;
        proxy_redirect http://127.0.0.1/ /project;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

访问 www.foo.test/project/controller/action,成功。

总结:

一开始,同事给我发了一份测试服务器上的配置,

location /project {
         proxy_pass http://127.0.0.1:9000/;
         proxy_redirect http://127.0.0.1:9000/ /project;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

可我按这个配置写入我本的 nginx 的配置时,死活不行。后还想到,我自己用的docker环境(测试环境上不是),那么 127.0.0.1 根本不是我的 php-fpm容器地址。如果要连接,需要用到php-fpm的容器名称。

所以实际上,nginx容器本地地址 127.0.0.1:80 其实就是 php-fpm9000端口。

最后,删除了 proxy_pass http://127.0.0.1:9000/; 中的 9000后配置成功了。

nginx: image: nginx:latest restart: always volumes: - ./nginx/nginx.conf.template:/etc/nginx/nginx.conf.template - ./nginx/proxy.conf.template:/etc/nginx/proxy.conf.template - ./nginx/https.conf.template:/etc/nginx/https.conf.template - ./nginx/conf.d:/etc/nginx/conf.d - ./nginx/docker-entrypoint.sh:/docker-entrypoint-mount.sh - ./nginx/ssl:/etc/ssl # cert dir (legacy) - ./volumes/certbot/conf/live:/etc/letsencrypt/live # cert dir (with certbot container) - ./volumes/certbot/conf:/etc/letsencrypt - ./volumes/certbot/www:/var/www/html entrypoint: [ 'sh', '-c', "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ] environment: NGINX_SERVER_NAME: ${NGINX_SERVER_NAME:-_} NGINX_HTTPS_ENABLED: ${NGINX_HTTPS_ENABLED:-false} NGINX_SSL_PORT: ${NGINX_SSL_PORT:-443} NGINX_PORT: ${NGINX_PORT:-80} # You're required to add your own SSL certificates/keys to the `./nginx/ssl` directory # and modify the env vars below in .env if HTTPS_ENABLED is true. NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt} NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key} NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.1 TLSv1.2 TLSv1.3} NGINX_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto} NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-100M} NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65} NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s} NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s} NGINX_ENABLE_CERTBOT_CHALLENGE: ${NGINX_ENABLE_CERTBOT_CHALLENGE:-false} CERTBOT_DOMAIN: ${CERTBOT_DOMAIN:-} depends_on: - api - web ports: - '${EXPOSE_NGINX_PORT:-80}:${NGINX_PORT:-80}' - '${EXPOSE_NGINX_SSL_PORT:-443}:${NGINX_SSL_PORT:-443}'
最新发布
08-14
<think>我们正在配置Nginx以绑定域名并启用HTTPS,使用Let's Encrypt证书。根据引用[1]和[2],Let's Encrypt提供免费SSL证书,有效期为90天,支持自动续期。以下是具体步骤: ### 步骤1:安装Certbot工具 根据引用[1],在CentOS 9上安装Certbot: ```bash sudo dnf install certbot python3-certbot-nginx ``` ### 步骤2:获取Let's Encrypt证书 运行以下命令获取证书(替换`example.com`为你的域名): ```bash sudo certbot certonly --nginx -d example.com -d www.example.com ``` - 此命令会验证域名所有权并签发证书,证书保存在`/etc/letsencrypt/live/example.com/`目录下[^1]。 ### 步骤3:配置Nginx HTTPS代理 编辑Nginx配置文件(通常位于`/etc/nginx/conf.d/example.com.conf`),添加以下内容: ```nginx server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; # 强制跳转HTTPS[^2] } server { listen 443 ssl; server_name example.com www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; # 启用安全协议[^1] # 配置代理到Dify(假设Dify运行在localhost:8080) location / { proxy_pass http://127.0.0.1:8080; # 绑定到本地Dify服务 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; } } ``` ### 步骤4:重启Nginx并验证 ```bash sudo nginx -t # 测试配置 sudo systemctl restart nginx ``` 访问`https://example.com`,确认HTTPS生效且能正确代理到Dify服务。 ### 步骤5:设置证书自动续期 Let's Encrypt证书有效期为90天,设置自动续期: ```bash # 编辑crontab sudo crontab -e ``` 添加以下行(每周日凌晨2点续期): ```bash 0 2 * * 0 /usr/bin/certbot renew --quiet && systemctl reload nginx ``` ### 安全加固(可选) 1. **启用HSTS**(强制浏览器使用HTTPS): ```nginx add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; ``` 2. **使用强加密套件**: ```nginx ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; ``` ### 数学表示证书续期周期 Let's Encrypt证书有效期$T=90$天,续期周期$T_r$应满足: $$ T_r < T \quad \Rightarrow \quad T_r \in (0, 90) \text{天} $$ 推荐设置$T_r=7$天(每周检查一次),避免续期失败导致证书过期[^1]。 ### 相关问题 1. 如何为多个域名配置HTTPS代理? 2. Nginx如何配置HTTP/2提升性能? 3. 如何验证SSL证书的安装是否正确? 4. 证书续期失败如何排查? [^1]: Let‘s Encrypt免费安全证书的步骤及使用-基于centos9 [^2]: 全民https时代,Let's Encrypt免费SSL证书的申请及使用(Tomcat版)</think>### 配置Nginx绑定域名并启用HTTPS(使用Let's Encrypt证书) #### 完整配置流程 ##### 步骤1:安装Certbot工具 ```bash # 基于CentOS/RHEL sudo yum install epel-release sudo yum install certbot python3-certbot-nginx # 基于Ubuntu/Debian sudo apt update sudo apt install certbot python3-certbot-nginx ``` ##### 步骤2:获取Let's Encrypt证书 ```bash sudo certbot certonly --nginx -d yourdomain.com -d www.yourdomain.com ``` - 证书将保存在`/etc/letsencrypt/live/yourdomain.com/`目录 - 自动验证域名所有权(需确保域名已解析到服务器)[^1] ##### 步骤3:配置Nginx HTTPS代理 编辑`/etc/nginx/conf.d/dify.conf`: ```nginx # HTTP重定向到HTTPS server { listen 80; server_name yourdomain.com www.yourdomain.com; return 301 https://$host$request_uri; # 强制HTTPS跳转[^2] } # HTTPS主配置 server { listen 443 ssl http2; server_name yourdomain.com www.yourdomain.com; # SSL证书配置 ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; # 安全协议配置 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; # 代理配置到Dify location / { proxy_pass http://127.0.0.1:8080; # 指向本地Dify服务 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_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # 安全响应头 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options nosniff; add_header X-Frame-Options DENY; } ``` ##### 步骤4:验证并重载配置 ```bash sudo nginx -t # 测试配置语法 sudo systemctl reload nginx # 应用新配置 ``` ##### 步骤5:设置证书自动续期 ```bash # 测试续期命令 sudo certbot renew --dry-run # 添加定时任务(每周日凌晨2点续期) (crontab -l ; echo "0 2 * * 0 /usr/bin/certbot renew --quiet && systemctl reload nginx") | crontab - ``` #### 关键配置说明 1. **证书路径**: Let's Encrypt自动管理的证书路径为: $$ \text{证书} \rightarrow \frac{\text{/etc/letsencrypt/live/yourdomain.com/}}{\begin{cases} \text{fullchain.pem} \\ \text{privkey.pem} \end{cases}} $$ 2. **HTTPS重定向原理**: 通过HTTP 301重定向实现强制HTTPS: $$ \text{HTTP请求} \xrightarrow{\text{301重定向}} \text{HTTPS终结点} $$ 3. **代理安全配置**: ```nginx proxy_set_header X-Forwarded-Proto $scheme; # 传递原始协议 add_header Strict-Transport-Security "max-age=31536000"; # 启用HSTS[^1] ``` #### 验证方法 ```bash # 检查HTTPS连接 curl -I https://yourdomain.com # 应返回:HTTP/2 200 # 检查证书有效期 openssl x509 -enddate -noout -in /etc/letsencrypt/live/yourdomain.com/cert.pem # 输出:notAfter=Sep 30 12:00:00 2023 GMT (90天有效期) ``` #### 常见问题解决 1. **证书申请失败**: - 确认域名解析已生效(`dig yourdomain.com`) - 开放防火墙端口:`sudo firewall-cmd --add-service={http,https} --permanent` 2. **混合内容警告**: - 在Dify配置中设置`APP_URL=https://yourdomain.com` - 确保所有资源使用相对路径或HTTPS URL 3. **性能优化**: ```nginx ssl_session_tickets off; # 减少TLS握手开销 ssl_buffer_size 4k; # 优化小数据包传输 ``` [^1]: Let‘s Encrypt免费安全证书的步骤及使用-基于centos9 [^2]: 全民https时代,Let's Encrypt免费SSL证书的申请及使用(Tomcat版) --- ### 相关问题 1. 如何为多个子域名配置HTTPS代理? 2. Nginx如何实现HTTP/3(QUIC)支持? 3. Let's Encrypt证书续期失败如何排查? 4. 如何配置Nginx的OCSP装订提升HTTPS性能? 5. 企业级证书与Let's Encrypt有何区别?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值