How to set up Next.js with Docker Composer and Nginx

Updated: January 2, 2024 By: Guest Contributor Post a comment

Learn to containerize a Next.js v13+ app using Docker Compose and serve it efficiently with Nginx, enhancing your development and deployment workflow.

Before you begin, ensure you have installed Docker, Docker Compose, and Node.js on your system. Familiarity with basic Docker concepts, Next.js app development, and Nginx configuration are also recommended.

Step 1: Create a Next.js App

npx create-next-app@latest nextjs-docker-nginx-app
cd nextjs-docker-nginx-app

Step 2: Dockerize the Next.js App

Start by creating a Dockerfile in the root directory of your Next.js app.

FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]

Step 3: Configure Docker Compose

Create a docker-compose.yml file to define multi-container Docker applications.

version: '3'
services:
  nextjs:
    build: .
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=production

Step 4: Set Up Nginx as a Reverse Proxy

Create an Nginx configuration file, usually named default.conf, to set up Nginx as a reverse proxy.

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://nextjs:3000;
        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;
    }
}

Include this configuration in a Dockerfile for Nginx.

# Dockerfile for Nginx
FROM nginx:alpine
COPY default.conf /etc/nginx/conf.d/
EXPOSE 80

Step 5: Update Docker Compose for Nginx

Edit the docker-compose.yml to include the Nginx service.

services:
  nextjs:
    # ... previous nextjs service definition
  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - '80:80'
    depends_on:
      - nextjs

Step 6: Adding Environment Variables and Volumes

Manage sensitive data and persist data using environment variables and volumes in the docker-compose.yml

services:
  nextjs:
    # ... previous nextjs service definitions
    environment:
      - NEXT_PUBLIC_API_URL=${API_URL}
    volumes:
      - ./:/app
      - /app/node_modules
  nginx:
    # ... previous nginx service definitions
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf

Step 7: Production Optimization

To optimize for production, consider adding health checks, using multi-stage builds, or enabling HTTPS with Let’s Encrypt.

Now go ahead and run your stack.

docker-compose up -d

Conclusion

By following the steps above, you have encapsulated a Next.js v13+ app within a Docker container and leveraged Nginx’s powerful features for serving it. This setup is scalable, production-ready, and streamlines development and deployment processes.