简体   繁体   中英

Docker Node.js with nginx

i try to dockerzied node.js, pm2

This is my 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;"]

it's working without nginx and run succesfuly, but when i try to proxy_pass there is error.

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;
    }
}

when i add nginx conf and run

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

there is error 502. what is my problem? why it's not working proxy_pass. without proxy_pass working fine, in 3000 port what is my problem? why it's not working proxy_pass. without proxy_pass working fine, in 3000 port

A Dockerfile only builds one image, usually out of the very last build stage (starting from the final FROM line). So in your case the image that's being built only contains the Nginx server and the compiled front-end application. It does not contain the separate Node server and nothing inside the container is listening on port 3000.

I'd suggest one of two possible approaches here.

If your application is something like a React or Angular pure front-end application, leave this setup as-is. The first stage will never be run per se so you don't need a CMD in it. Remove the proxy_pass Nginx configuration option (and maybe the entire custom Nginx configuration) and just serve the static files.

On the other hand, if your application is more of an Express back-end service, then you need to run this as two separate containers. This is a more involved process:

First, split this Dockerfile into two. I might have the Dockerfile be just the back-end application (I might remove the unnecessary pm2 setup, and definitely do not leak credentials via Dockerfile ENV ). A second Dockerfile.nginx would copy the static assets from the first image; I might simplify the Dockerfile slightly

# 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

(So long as the built application includes an index.html it will overwrite the default contents; the base image's CMD is inherited and you don't need to restate it.)

In the Nginx configuration set proxy_pass http://backend:3000/; Keep a try_files line too, or add separate routes for a /static or /assets path, if those files are in the image.

Finally, write a Docker Compose setup to start the two containers together:

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

You need to build the image in two steps; first build the back-end image and then build the proxy image. Compose doesn't have any native way to understand that one of the images depends on the other's content.

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

Compose automatically creates a network for you so the two containers can talk to each other using their service names backend and proxy as host names. (You will see many examples that manually configure networks: and container_name: but these options are not necessary.) You can connect to the built application on http://localhost:8080 ; in the Compose ports: option the first port number matches the port number in the URL, and the second matches the Nginx listen directive (the port inside the container where the server is running). I've commented out a second ports: line which would allow you to directly reach the back-end service bypassing the proxy, if you'd find that useful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM