docker - 有没有办法在 docker 和 nginx 中使用 nextjs

标签 docker nginx next.js

我有一个希望使用 Docker 和 nginx 运行的 nextjs 项目。
我希望使用在幕后连接到 nextjs 的 nginx(只有 nginx 可以与 nextjs 对话,用户需要与 nginx 对话才能与 nextjs 对话)。
假设它是标准的 nextjs 项目结构和 dockerfile 内容(下面提供),有没有办法在 docker 中使用 nginx 和 nextjs?
我知道我可以使用 Docker-compose。但我想把它放在一个 docker 镜像下。因为我打算将图像推送到 heroku 网络托管。
注意:我正在使用服务器端渲染
文件

# Base on offical Node.js Alpine image
FROM node:latest as builder

# Set working directory
WORKDIR /usr/app

# install node-prune (https://github.com/tj/node-prune)
RUN curl -sfL https://install.goreleaser.com/github.com/tj/node-prune.sh | bash -s -- -b /usr/local/bin

# Copy package.json and package-lock.json before other files
# Utilise Docker cache to save re-installing dependencies if unchanged
COPY package.json ./
COPY yarn.lock ./

# Install dependencies
RUN yarn install --frozen-lockfile

# Copy all files
COPY ./ ./

# Build app
RUN yarn build

# remove development dependencies
RUN yarn install --production

# run node prune. Reduce node_modules size
RUN /usr/local/bin/node-prune

####################################################### 

FROM node:alpine

WORKDIR /usr/app

# COPY package.json next.config.js .env* ./
# COPY --from=builder /usr/app/public ./public
COPY --from=builder /usr/app/.next ./.next
COPY --from=builder /usr/app/node_modules ./node_modules

EXPOSE 3000

CMD ["node_modules/.bin/next", "start"]
dockerfile 灵感来自 https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile.multistage
编辑:nginx default.conf
upstream nextjs_upstream {
  server nextjs:3000;

  # We could add additional servers here for load-balancing
}

server {
  listen 80 default_server;

  server_name _;

  server_tokens off;

  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
  proxy_set_header Host $host;
  proxy_cache_bypass $http_upgrade;

  location / {
    proxy_pass http://nextjs_upstream;
  }
}

最佳答案

为了能够在单个 Docker 容器中一起使用 Nginx 和 NextJS 没有 使用 Docker-Compose,你需要使用 Supervisord

Supervisor is a client/server system that allows its users to control a number of processes on UNIX-like operating systems.


问题不在于 nginx 配置或 dockerfile。启动容器时,它同时运行 nginx 和 nextjs。由于我找不到同时运行两者的方法,因此使用 主管 是我需要的工具。
需要以下内容才能工作
Dockerfile
# Base on offical Node.js Alpine image
FROM node:latest as builder

# Set working directory
WORKDIR /usr/app

# Copy package.json and package-lock.json before other files
# Utilise Docker cache to save re-installing dependencies if unchanged
COPY package.json ./
COPY yarn.lock ./

# Install dependencies
RUN yarn install --frozen-lockfile

# Copy all files
COPY ./ ./

# Build app
RUN yarn build

# remove development dependencies
RUN yarn install --production

####################################################### 

FROM nginx:alpine

WORKDIR /usr/app

RUN apk add nodejs-current npm supervisor
RUN mkdir mkdir -p /var/log/supervisor && mkdir -p /etc/supervisor/conf.d

# Remove any existing config files
RUN rm /etc/nginx/conf.d/*

# Copy nginx config files
# *.conf files in conf.d/ dir get included in main config
COPY ./.nginx/default.conf /etc/nginx/conf.d/

# COPY package.json next.config.js .env* ./
# COPY --from=builder /usr/app/public ./public
COPY --from=builder /usr/app/.next ./.next
COPY --from=builder /usr/app/node_modules ./node_modules

# supervisor base configuration
ADD supervisor.conf /etc/supervisor.conf

# replace $PORT in nginx config (provided by executior) and start supervisord (run nextjs and nginx)
CMD sed -i -e 's/$PORT/'"$PORT"'/g' /etc/nginx/conf.d/default.conf && \
  supervisord -c /etc/supervisor.conf
supervisor.conf
[supervisord]
nodaemon=true

[program:nextjs]
directory=/usr/app
command=node_modules/.bin/next start
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=true

[program:nginx]
command=nginx -g 'daemon off;'
killasgroup=true
stopasgroup=true
redirect_stderr=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=true
nginx 配置 (default.conf)
upstream nextjs_upstream {
  server localhost:3000;

  # We could add additional servers here for load-balancing
}

server {
  listen $PORT default_server;

  server_name _;

  server_tokens off;

  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
  proxy_set_header Host $host;
  proxy_cache_bypass $http_upgrade;

  location / {
    proxy_pass http://nextjs_upstream;
  }
}
注意:使用 nginx 作为反向代理。 NextJS 将在端口 3000 上运行。用户将无法直接访问它。它必须通过nginx。

构建 docker 镜像
docker build -t nextjs-img -f ./dockerfile .
运行 docker 容器
docker run --rm -e 'PORT=80' -p 8080:80 -d --name nextjs-img nextjs-img:latest
转至 localhost:8080

关于docker - 有没有办法在 docker 和 nginx 中使用 nextjs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65331554/

相关文章:

docker - 如何在 Alpine 上的 OpenSSH 中调试无效的无密码 RSA 证书?

ruby-on-rails - 从Docker容器中管理Capistrano部署的SSH key

python - 优化docker镜像大小

Docker Compose 保持容器运行

logging - 使用 nginx 记录已解析的请求

node.js - 具有多个 docker 文件的 Git repo 结构

Django channel daphne 返回 200 状态代码

javascript - 有没有办法用 JavaScript 为视频标签添加延迟加载?

javascript - Next.js 读取 Firestore 数据

node.js - 如何在 React 应用程序中进行服务器端处理?