Docker Node.js with nginx



我尝试对接node.js , pm2

这是我的Dockerfile

FROM node:14.17.0 AS build
# Set working directory
WORKDIR /usr/app
# Install PM2 globally
RUN npm install --global pm2
RUN cd /usr/app && ls
# Credential for real time monitoring PM2 Plus
ENV PM2_PUBLIC_KEY xxxxx
ENV PM2_SECRET_KEY xxxxx

# Copy "package.json" and "package-lock.json" before other files
# Utilise Docker cache to save re-installing dependencies if unchanged
COPY ./package*.json ./
# Install dependencies
RUN npm install
# Copy all files
COPY ./ ./
# Build app
RUN npm run-script build
# Expose the listening port
EXPOSE 3000
# Launch app with PM2
CMD [ "pm2-runtime", "start", "npm", "--", "start" ]

FROM nginx:alpine
# ## Replace the default nginx index page with our Angular app
RUN rm -rf /usr/share/nginx/html/*
RUN ls
COPY --from=build  /usr/app /usr/share/nginx/html
COPY ./.nginx/nginx.conf /etc/nginx/nginx.conf
ENTRYPOINT ["nginx", "-g", "daemon off;"]

它在没有nginx的情况下工作,并且运行成功,但当我尝试proxypass时出现了错误。

nginx

# Run as a less privileged user for security reasons.
user nginx;
# #worker_threads to run;
# "auto" sets it to the #CPU_cores available in the system, and
# offers the best performance.
worker_processes    auto;
events { worker_connections 1024; }
http {
server {
# Hide nginx version information.
server_tokens off;
listen  80;
root /usr/share/nginx/html/public;
include /etc/nginx/mime.types;
location / {
proxy_pass http://localhost:3000;
#   try_files $uri $uri/ /index.php$is_args$args;
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;
}
gzip            on;
gzip_vary       on;
gzip_http_version  1.0;
gzip_comp_level 5;
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component;
gzip_proxied    no-cache no-store private expired auth;
gzip_min_length 256;
gunzip          on;
}
}

当我添加nginx-conf并运行时

docker run -d -p 3000:3000 test/test

则存在错误502。我的问题是什么?为什么代理通行证不起作用。在3000端口中没有proxy_pass正常工作我的问题是什么?为什么代理通行证不起作用。在3000端口中,没有proxy_pass正常工作

Dockerfile只构建一个映像,通常在最后一个构建阶段(从最后一行FROM开始(。因此,在您的情况下,只构建的映像包含Nginx服务器和编译的前端应用程序。它不包含单独的Node服务器,容器中没有任何内容在端口3000上侦听。

我在这里建议两种可能的方法之一。

如果您的应用程序类似于React或Angular纯前端应用程序,请保持此设置不变。第一阶段将永远不会运行本身,因此您不需要其中的CMD。删除proxy_passNginx配置选项(可能还有整个自定义Nginx设置(,只提供静态文件。

另一方面,如果您的应用程序更像是一个Express后端服务,那么您需要将其作为两个独立的容器来运行。这是一个更复杂的过程:

首先,将Dockerfile一分为二。我可能让Dockerfile只是后端应用程序(我可能会删除不必要的pm2设置,并且绝对不会通过DockerfileENV泄露凭据(。第二CCD_ 8将从第一图像复制静态资产;我可能会稍微简化Dockerfile

# Dockerfile.nginx
FROM nginx:alpine
COPY --from=my-name/my-app /usr/app/dist/ /usr/share/nginx/html/
COPY ./.nginx/nginx.conf /etc/nginx/nginx.conf

(只要构建的应用程序包含index.html,它就会覆盖默认内容;基本映像的CMD是继承的,您不需要重述它。(

在Nginx配置集中,proxy_pass http://backend:3000/;也保留try_files行,或者为/static/assets路径添加单独的路由(如果这些文件在映像中(。

最后,编写一个Docker Compose设置,将两个容器一起启动:

version: '3.8'
services:
backend: # <-- this name matches proxy_pass
build: .
image: my-name/my-app # <-- this name matches COPY --from=
# ports: ['3000:3000']  # optional
proxy:
build:
context: .
dockerfile: Dockerfile.nginx
ports:
- '8080:80'
depends_on:
- backend

您需要分两个步骤构建图像;首先构建后端映像,然后构建代理映像。Compose没有任何原生的方式来理解其中一个图像依赖于另一个的内容。

docker-compose build backend
docker-compose build
docker-compose up -d

Compose会自动为您创建一个网络,这样两个容器就可以使用它们的服务名称backendproxy作为主机名进行通信。(您会看到许多手动配置networks:container_name:的示例,但这些选项不是必需的。(您可以连接到http://localhost:8080上构建的应用程序;在Composeports:选项中,第一个端口号与URL中的端口号匹配,第二个与Nginxlisten指令(服务器运行的容器内的端口(匹配。我已经注释了第二行ports:,如果您觉得有用的话,它将允许您绕过代理直接到达后端服务。

最新更新