[英]Docker Node.js with nginx
我尝试 dockerzied 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 的情况下工作并成功运行,但是当我尝试 proxy_pass 时出现错误。
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。我的问题是什么? 为什么它不工作proxy_pass。 没有 proxy_pass 工作正常,在 3000 端口我的问题是什么? 为什么它不工作proxy_pass。 没有 proxy_pass 工作正常,在 3000 端口
Dockerfile 只构建一个映像,通常是在最后一个构建阶段(从最后的FROM
行开始)。 因此,在您的情况下,正在构建的映像仅包含 Nginx 服务器和已编译的前端应用程序。 它不包含单独的节点服务器,并且容器内没有任何东西正在监听端口 3000。
我会在这里建议两种可能的方法之一。
如果您的应用程序类似于 React 或 Angular 纯前端应用程序,请保持此设置不变。 第一阶段本身永远不会运行,因此您不需要CMD
。 删除proxy_pass
Nginx 配置选项(可能还有整个自定义 Nginx 配置)并只提供 static 文件。
另一方面,如果您的应用程序更像是 Express 后端服务,那么您需要将其作为两个独立的容器运行。 这是一个更复杂的过程:
首先,将这个 Dockerfile 一分为二。 我可能让Dockerfile
只是后端应用程序(我可能会删除不必要的pm2
设置,并且绝对不会通过 Dockerfile ENV
泄漏凭据)。 第二个Dockerfile.nginx
将从第一个图像中复制 static 资产; 我可能会稍微简化 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 setup 来一起启动两个容器:
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会自动为您创建一个网络,因此这两个容器可以使用它们的服务名称backend
和proxy
作为主机名相互通信。 (您将看到许多手动配置networks:
和container_name:
的示例,但这些选项不是必需的。)您可以在http://localhost:8080
上连接到已构建的应用程序; 在 Compose ports:
选项中,第一个端口号与 URL 中的端口号匹配,第二个端口号与 Nginx listen
指令(容器内运行服务器的端口)匹配。 我已经注释掉了第二个ports:
行,它允许您绕过代理直接访问后端服务,如果您觉得这很有用的话。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.