¿Hay una manera de usar Nextjs con docker y nginx

Tengo un proyecto de Nextjs que quiero ejecutar usando Docker y Nginx.

Me gustaría utilizar nginx que se conecta a los próximosjs detrás de las escenas (sólo nginx puede hablar con nextjs, el usuario necesita hablar con nginx para hablar con nextjs).

Suponiendo que sea la estructura estándar del proyecto Nextjs y el contenido del fichero docker (proporcionado a continuación), ¿Hay alguna manera de usar nginx en docker con Nextjs?

Soy consciente de que puedo usar Docker-compose. Pero me gustaría mantenerlo bajo una imagen de muelle. Desde Planeo empujar la imagen al hospedaje web de heroku.

NOTA: Estoy usando Server Side Rendering

dockerfile

# 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 inspirado en https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile.multistage

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

Pregunta hecha hace 3 años, 4 meses, 28 días - Por bitcraftsman


4 Respuestas:

  • Para poder utilizar Nginx y NextJS juntos en un solo contenedor Docker sin usando Docker-Compose, necesitas usar Supervisord

    Supervisor es un sistema cliente/servidor que permite a sus usuarios controlar a number of processes on UNIX-like operating systems.

    El problema no era nginx config ni el archivo del docker. Corría tanto nginx como Nextjs al iniciar el contenedor. Desde No pude encontrar una manera de correr ambos, usando supervisor era la herramienta que necesitaba.

    Será necesario que funcione lo siguiente:

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

    NOTA: usar nginx como un proxy inverso. Siguiente La JS se ejecutará en el puerto 3000. El usuario no podrá alcanzarlo directamente. Tiene que pasar por Nginx.


    Imagen de la puerta del edificio

    docker build -t nextjs-img -f ./dockerfile .
    

    Contenedor de muelles

    docker run --rm -e 'PORT=80' -p 8080:80 -d --name nextjs-img nextjs-img:latest
    

    Ve. localhost:8080

    Respondida el Dec 16, 2020 a las 21:48 - por bytebard30f9

    Votos positivos: 0 | Votos negativos: 0

  • Puedes usar docker-compose para ejecutar Nginx y su aplicación NextJS en el contenedor Docker, luego tener una red de puente entre esos contenedores.

    entonces en nginx conf:

    server {
        listen       80;
        listen       443 ssl;
    
        server_name localhost [dns].com;
    
        ssl_certificate certs/cert.pem;
        ssl_certificate_key certs/cert.key;
    
        location / {
            proxy_pass http://nextApplication; // name based on your docker-compose file
            proxy_http_version 1.1;
            proxy_read_timeout      90;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host [dns].com;
            proxy_cache_bypass $http_upgrade;
        }
    }
    

    No usé upstream script, loadbalancer está encima de nginx (a nivel del proveedor de la nube)

    Respondida el Dec 16, 2020 a las 21:57 - por compilercaptain7dab

    Votos positivos: 0 | Votos negativos: 0

  • Sí, es posible utilizar Next.js con Docker y Nginx. Para lograrlo, necesitas realizar las siguientes modificaciones en tu archivo Dockerfile inspirado en el ejemplo que proporcionaste:

    • Agregar la instalación de Nginx al contenedor de Docker.
    • Configurar Nginx para que actúe como un servidor proxy inverso que canalizará las solicitudes al servidor Next.js.

    Aquí está cómo puedes modificar tu Dockerfile para incluir Nginx y configurar el proxy inverso:

    Dockerfile
    

    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

    Copy Nginx configuration

    COPY nginx/default.conf /etc/nginx/conf.d/default.conf

    Install Nginx

    RUN apk add --no-cache nginx

    Copy Next.js build to Nginx default directory

    RUN cp -r ./.next /var/www RUN chown -R nginx:nginx /var/www

    Expose port 80

    EXPOSE 80

    Start Nginx and Next.js

    CMD ["nginx", "-g", "daemon off;"]

    En este código, se agrega la instalación de Nginx y se copia la configuración de Nginx (default.conf) al contenedor. Luego, se copian los archivos de construcción de Next.js a la carpeta de Nginx. Finalmente, se inicia Nginx en primer plano para actuar como servidor proxy inverso.

    Además, asegúrate de proporcionar el archivo de configuración default.conf para Nginx en la carpeta nginx dentro de tu proyecto.

    Con estas modificaciones, podrás ejecutar tu proyecto de Next.js utilizando Docker y Nginx como servidor proxy inverso.

    Respondida el Dec 17, 2020 a las 21:50 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Sí, es posible utilizar Nginx con Next.js en un solo contenedor Docker. Aquí tienes los pasos:

    • Crea un archivo `nginx.conf` con la siguiente configuración:
    
    upstream nextjs_upstream {
      server localhost:3000;
    }
    
    server {
      listen 80;
      server_name _;
    
      location / {
        proxy_pass http://nextjs_upstream;
      }
    }
    
    • Actualiza tu Dockerfile para incluir la imagen de Nginx y la configuración del servidor virtual:
    
    FROM node:latest as builder
    
    

    ... Código anterior ...

    FROM nginx:1.23-alpine RUN mkdir -p /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf COPY --from=builder /usr/app/public /usr/share/nginx/html CMD ["nginx", "-g", "daemon off;"]
    • Construye la imagen de Docker:
    
    docker build -t my-nextjs-nginx .
    
    • Ejecuta el contenedor:
    
    docker run -p 80:80 my-nextjs-nginx
    

    Ahora, Nginx escuchará en el puerto 80 y reenviará las solicitudes a la aplicación Next.js que se ejecuta en el puerto 3000 dentro del mismo contenedor.

    Notas:

    Asegúrate de que el archivo package.json de tu proyecto Next.js incluye la siguiente configuración para habilitar el renderizado del lado del servidor (SSR):

    json
    {
      "target": "serverless"
    }
    

    Puedes ajustar el puerto de escucha de Nginx modificando la línea listen 80; en el archivo nginx.conf.

    Respondida el Dec 17, 2020 a las 21:57 - por Gemini

    Votos positivos: 0 | Votos negativos: 0