next.js 在Docker容器内运行时,NodeJS HTTPS服务器通过HTTP而不是HTTPS提供服务

rdlzhqv9  于 2022-12-03  发布在  Docker
关注(0)|答案(1)|浏览(208)

bounty将在6天后过期。回答此问题可获得+100的声望奖励。Kenzoid希望吸引更多人关注此问题:想提请大家多注意这个问题。

我使用NextJS和Docker创建了一个网站,这样我就可以轻松地部署它。我使用npx-create-next-app初始化它,并使用this Dockerfile(稍微修改了一下)将它容器化。由于我想在我的服务器上使用SSL,而不必经历设置代理的麻烦,所以我使用this article,并设置了自定义服务器。
当我在Docker容器外运行它时,它运行得很好,并按预期运行,通过HTTPS提供服务。但是当我将它容器化,并试图通过HTTPS打开网页时,我得到了SSL_ERROR_RX_RECORD_TOO_LONG,但我只能使用HTTP打开页面(这是我在容器外运行时做不到的)。一些谷歌搜索把我引到了X1 E4 F1 X,从中我得出结论,当在Docker容器外运行时,自定义服务器如预期的那样通过HTTPS运行服务器,但是当我将其容器化时,它开始运行HTTP,即使没有更改任何代码。
我希望在本地运行或容器化运行时的行为是相同的。
一开始我以为这是由于httpsOptions中的keycert值无效,但是我找不到任何使它们无效的东西,我不知道这是如何导致这种奇怪的行为的。我尝试将Docker运行环境从node:alpine-16更改为node:latest,以查看它是否与父映像有关。但毫无结果。
我遇到的另一个小问题是console.log由于某种原因似乎没有输出到容器的日志中,我试着在谷歌上搜索这个,但是没有找到与它相关的任何东西。这使得调试变得更加困难,因为我不能真正输出任何调试数据。当我在容器中运行时得到的唯一日志是Listening on port 3000 url: http://localhost:3000,我假设它是某个库/包输出,因为它不在我的代码中。
下面是我的自定义服务器代码,如果它会有帮助:

const https = require('https');
const fs = require('fs');
const { parse } = require('url');
const next = require('next');

const dev = process.env.NODE_ENV !== 'production';
const hostname = "127.0.0.1";
const port = process.env.PORT || 3000
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()

const httpsOptions = {
    key: fs.readFileSync('./cert/privkey.pem'),
    cert: fs.readFileSync('./cert/fullchain.pem')
};

app.prepare().then(() => {
    https.createServer(httpsOptions, async (req, res) => { // When running on docker this creates an HTTP server instead of HTTPS
        const parsedUrl = parse(req.url, true)
        const { pathname, query } = parsedUrl

        await handle(req, res, parsedUrl)
    }).listen(port, (err) => {
        if(err) throw err
        console.log(`Ready on https://localhost:${port}`)
    })
})
qij5mzcb

qij5mzcb1#

It sounds like you have successfully set up a NextJS server that serves over HTTPS when running outside of a Docker container. You have also containerized the server using Docker, but when you try to access the server over HTTPS from inside the container, you receive the error SSL_ERROR_RX_RECORD_TOO_LONG.
This error typically indicates that the server is not configured to use HTTPS. In your code, you create a server using the https module and pass in your httpsOptions object, which contains the key and cert files. However, when running inside the Docker container, it appears that the server is being created using the http module instead of https.
One potential cause of this issue could be that the https module is not installed in the Docker container. This could happen if the https module is not listed in the dependencies section of your package.json file. If that is the case, you can fix the issue by adding the https module to your dependencies and rebuilding the Docker container.
Alternatively, it could be that the https module is installed in the Docker container, but the code is not executing the https.createServer() line. This could be due to a syntax error or some other issue in the code. In that case, you can try adding some logging statements to your code to help diagnose the problem. For example, you could try adding a log statement before the https.createServer() line to print the value of the https module. This can help you determine whether the https module is being loaded correctly.
As for your second issue, the fact that console.log() statements are not appearing in the container logs, this could be due to the way that Docker is configured. By default, Docker will only show logs for a container if it is running in the foreground. If the container is running in the background, you will need to use the docker logs command to view the logs. You can also use the -f flag with docker logs to follow the logs in real-time.
In summary, it sounds like your NextJS server is not serving over HTTPS when running inside the Docker container because the https module is not installed or is not being used correctly. To fix this issue, you can try the following steps:

  1. Check that the https module is listed in the dependencies section of your package.json file. If it is not, add it and rebuild the Docker container.
  2. Add some logging statements to your code to help diagnose the problem. For example, you can try logging the value of the https module before the https.createServer() line.
  3. Make sure that the container is running in the foreground, or use the docker logs command to view the logs. You can use the -f flag with docker logs to follow the logs in real-time.

相关问题