【问题标题】:Dockerize next.js and nginx at one Dockerfile在一个 Dockerfile 中对 next.js 和 nginx 进行 Dockerize
【发布时间】:2020-11-11 15:03:24
【问题描述】:

我已经使用两个 docker 映像成功地将我的应用程序 dockerize,一个用于 nginx,第二个用于应用程序,它运行良好,因为我使用 docker compose。 现在我只想拥有一个包含 app 和 nginx 的 Dockerfile,然后在我的本地计算机上运行它。我怎样才能做到这一点?

这是我的nginx/default.conf

# Cache zone
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=STATIC:10m inactive=7d use_temp_path=off;

upstream nextjs {
  server nextjs:3000;
}

server {
  listen 80 default_server;

  server_name _;

  server_tokens off;

  gzip on;
  gzip_proxied any;
  gzip_comp_level 4;
  gzip_types text/css application/javascript image/svg+xml;

  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;

  # BUILT ASSETS (E.G. JS BUNDLES)
  # Browser cache - max cache headers from Next.js as build id in url
  # Server cache - valid forever (cleared after cache "inactive" period)
  location /_next/static {
    proxy_cache STATIC;
    proxy_pass http://nextjs;
  }

  # STATIC ASSETS (E.G. IMAGES)
  # Browser cache - "no-cache" headers from Next.js as no build id in url
  # Server cache - refresh regularly in case of changes
  location /static {
    proxy_cache STATIC;
    proxy_ignore_headers Cache-Control;
    proxy_cache_valid 60m;
    proxy_pass http://nextjs;
  }

  # DYNAMIC ASSETS - NO CACHE
  location / {
    proxy_pass http://nextjs;
  }
}

我的 /nginx/Dockerfile

FROM nginx:alpine as build
RUN rm /etc/nginx/conf.d/*
COPY ./default.conf /etc/nginx/conf.d/
EXPOSE 80
CMD [ "nginx", "-g", "daemon off;" ]

/Dockerfile [旧]

FROM node:alpine
WORKDIR /usr/app
RUN npm install --global pm2
COPY ./package*.json ./
RUN npm install --production
COPY ./ ./
RUN npm run build
EXPOSE 3000
USER node
CMD [ "pm2-runtime", "start", "npm", "--", "start" ]

这是新的 Dockerfile

FROM node:alpine
WORKDIR /usr/app
RUN npm install --global pm2
COPY ./package*.json ./
RUN npm install --production
COPY ./ ./
# Build app
RUN npm run build
EXPOSE 3000
USER node
CMD [ "pm2-runtime", "start", "npm", "--", "start" ]
FROM nginx:stable-alpine
COPY --from=build /usr/app/.next /usr/share/nginx/html
RUN mkdir /usr/share/nginx/log
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/default.conf /etc/nginx/conf.d
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

我可以构建它,但是每当我运行图像时都会抛出错误 在 /etc/nginx/conf.d/default.conf:5 的上游“nextjs:3000”中找不到主机

【问题讨论】:

    标签: docker nginx dockerfile next.js


    【解决方案1】:

    感谢@octagon_octopus 我终于通过更改我的 nginx/default.conf 解决了这个问题

    我的 Dockerfile

    # build react app, it should be /build
    # FROM node:12.2.0-alpine as build
    FROM node:13-alpine as build
    WORKDIR /app
    COPY package.json /app/package.json
    RUN npm install --only=prod
    COPY . /app
    RUN npm run build
    
    # Creating nginx image and copy build folder from above
    # FROM nginx:1.16.0-alpine
    FROM nginx:stable-alpine
    RUN mkdir /usr/share/nginx/buffer
    COPY --from=build /app/.next /usr/share/nginx/buffer
    COPY --from=build /app/deploy.sh /usr/share/nginx/buffer
    RUN chmod +x /usr/share/nginx/buffer/deploy.sh
    RUN cd /usr/share/nginx/buffer && ./deploy.sh
    RUN mkdir /usr/share/nginx/log
    RUN rm /etc/nginx/conf.d/default.conf
    COPY nginx/nginx.conf /etc/nginx/conf.d
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]
    

    和 nginx/default.conf

    server {
    
      listen 80;
    
      location / {
        root   /usr/share/nginx/html/pages;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
      }
    
      error_page   500 502 503 504  /50x.html;
    
      location = /50x.html {
        root   /usr/share/nginx/html/pages;
      }
      error_log /usr/share/nginx/log/error.log warn;
      access_log /usr/share/nginx/log/access.log;
    }
    

    【讨论】:

    • 现在可以正常使用了。我假设你正在运行一个 nodejs 应用程序,但看起来 nextjs 是不同的,我的错。通过 nginx 容器为您的 Web 应用程序提供服务是您现在所做的正确方法。
    • COPY --from=build /app/deploy.sh /usr/share/nginx/buffer 。你能粘贴 deploy.sh 的代码吗
    • @otniel 你能分享一下 deploy.sh 吗?
    • @VaibhavKumarGautam 对不起,我不再使用那个配置了。现在我的应用只有一个 docker 镜像并在 kubernetes 上提供服务
    • 是的,你是如何将两个容器放在一个 docker 镜像中并在 Kubernetes 中使用的?我现在也遇到了同样的问题。
    【解决方案2】:

    之所以得到host not found in upstream "nextjs:3000" in /etc/nginx/conf.d/default.conf:5,是因为根据你的nginx/default.conf,nginx会将所有收到的请求转发到http://nextjs。这在以前有效,因为您可能在一个名为nextjs 的单独容器中运行了节点。现在你尝试在同一个容器中运行 nginx 和 node,所以 nextjs 容器不再存在,nginx 没有任何东西可以转发请求。

    在我看来,您正在尝试在同一个容器中运行反向代理和节点应用程序,当在两个单独的容器中运行它们时应该像以前那样更可取。

    如果你只是在本地开发你的 node 应用,你不需要 nginx 反向代理,你可以直接向 node 应用发送请求,所以只需要 node 容器。当您部署到生产环境时,您通常会出于 SSL 终止和负载平衡等各种原因使用类似 nginx 反向代理的东西。在这种情况下,您可以将 nginx 和节点容器一起部署。

    如果您真的想继续当前的方法,那么您可能必须将请求转发到 http://localhost 而不是 http://nextjs,尽管我认为这不是唯一的问题。 Node 也可能不在您的容器中运行。在多阶段 docker 构建中使用 CMD [ "pm2-runtime", "start", "npm", "--", "start" ] 启动 Node 应用程序,该节点映像将被丢弃。您将不得不在 nginx 容器内启动您的 Node 应用程序。

    【讨论】:

    • 嗨,感谢您的解释。我现在可以理解了。我对我的 dockerfile 和 nginx/default.conf 做了一些更改,它运行良好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 2019-12-15
    • 2017-10-29
    • 1970-01-01
    • 2022-01-23
    • 2014-11-18
    相关资源
    最近更新 更多