nginx 如何使用Docker在HTTPS(SSL连接)上部署Next.js应用程序?

tjvv9vkg  于 2023-03-01  发布在  Nginx
关注(0)|答案(1)|浏览(303)

我按照Next.js文档中的说明使用Docker启动服务器:www.example.comhttps://nextjs.org/docs/deployment#docker-image
使用http加载站点可以工作,但https返回SSL协议错误。
我做的细节:
1.在我的DigitalOcean Ubuntu 22.4服务器上配置了NGINX和cerbot(请注意,本指南是针对Ubuntu 20的)https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal
1.将Dockerfile.dockerignore从文档中链接的示例项目复制到我的项目:https://github.com/vercel/next.js/tree/canary/examples/with-docker
1.已创建映像并将其上载到服务器。
1.已在服务器上启动映像:docker run -p 80:3000 -p 443:3000 my_image
HTTP工作完美(https://mysite.mydomain)。使用HTTPS时,我会收到错误,例如Chrome上的ERR_SSL_PROTOCOL_ERROR和Firefox上的SSL_ERROR_RX_RECORD_TOO_LONG
有什么想法吗?

idfiyjo8

idfiyjo81#

以下步骤解释了如何设置多容器Docker Compose环境,其中NGINX用作Next.js应用程序前面的反向代理,以处理SSL连接(并提供HTTPS URI)。

步骤1-停靠Next.js应用程序

幸运的是,这是Next.js官方文档本身的一部分,关键步骤是将this Dockerfile复制到您正在处理的Next.js repo中。
陷阱:

  • 最好也复制.dockerignore
  • next.config.js中设置output: 'standalone'(类似于this
  • 我们将在Next.js应用程序前面放置一个反向代理,这样Dockerfile中的端口(默认为3000)就不会对外公开;没有必要公开该端口
  • 确保映像构建:docker build -t nextjs:latest -f Dockerfile .
步骤2-设置Docker编写环境

Docker合成环境将有两个正在运行的容器:Next.js应用程序和NGINX。
NGINX图像可以通过添加第二个Dockerfile来创建:

# nginx/Dockerfile

FROM nginx:1.23.3-alpine

COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80
EXPOSE 443

使用docker build -t nginx:latest -f nginx/Dockerfile nginx从项目根目录构建映像。
然后,我们可以创建一个docker-compose.yml文件:

version: "3.9"
services:
  nextjs:
    image: nextjs:latest
    container_name: nextjs
    ports:
      - "3000:3000"
    restart: always
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /etc/ssl:/etc/nginx/ssl:ro
    restart: always

陷阱:

  • 现在可以添加一个空的nginx.conf,它将在下一步中进行配置
  • 端口80(HTTP)和443(HTTPS)将公开,因此需要将其打开
  • SSL证书和密钥通过Docker卷提供。假设它们存在于主机中的/etc/ssl下。另一种方法是将它们打包到NGINX映像中(例如,将COPY my_ssl_cert.crt /etc/nginx/ssl/my_ssl_cert.crt添加到Dockerfile,密钥同上)
步骤3-将NGINX配置为反向代理

示例nginx.conf

# nginx/nginx.conf

events {
}

http {
    upstream nextjs {
        server nextjs:3000;
    }
    server {
        # Redirect HTTP requests to HTTPS.
        listen 80;
        server_name localhost;
        root /srv/public;
        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl;

        server_name localhost;
        root /srv/public;
        server_tokens off;

        ssl_certificate /etc/nginx/ssl/my_ssl_cert.crt;
        ssl_certificate_key /etc/nginx/ssl/my_ssl_key.key;

        location / {
            try_files $uri $uri/ @nextjs;
        }

        location @nextjs {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Forwarded-Ssl on;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://nextjs;
            proxy_cookie_path / "/; HTTPOnly; Secure";
        }
    }
}

陷阱:

  • 我们可以通过Next.js应用的默认主机名nextjs来引用它,因为 * 默认情况下,Compose会为您的应用设置一个网络 *(docs
步骤4-展开

1.构建两个Docker映像
1.将Docker映像、SSL文件和docker-compose.yml发送到服务器
1.在服务器中,运行docker compose up
1.如果需要,使用docker logs [container_name]调试任何问题;curl http://localhost:80curl --insecure https://localhost:443也可以提供帮助

相关问题