This guide walks you through deploying a Next.js app on an AWS EC2 instance using Docker and NGINX, with CI/CD automation via GitHub Actions.
- Deploying a Next.js App on AWS EC2 with Docker, NGINX, and GitHub Actions
- Next.js Production Dockerfile Explained
-
Create your project folder and Next.js app:
mkdir next-tutorial-app cd next-tutorial-app npx create-next-app@latest website cd website npm run dev
-
Add a
Dockerfile
inside yourwebsite/
folder:FROM node:23.10.0-alpine WORKDIR /app COPY ./package*.json ./ RUN yarn COPY . . EXPOSE 3000
-
Create a
.dockerignore
in yourwebsite/
folder:node_modules .next .DS_Store dist
-
Create a
docker-compose.yml
in your root folder:services: website: build: context: ./website dockerfile: Dockerfile command: yarn dev ports: - "3000:3000"
-
Start your containers:
docker-compose up
-
Create an
nginx/
directory in your root folder. -
Inside
nginx/
createnginx.conf
:server { listen 80; server_name localhost; location / { proxy_pass http://website: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; } }
-
Add a Dockerfile to
nginx/
:FROM nginx:latest RUN rm /etc/nginx/conf.d/* COPY nginx.conf /etc/nginx/conf.d/ EXPOSE 80
-
Update
docker-compose.yml
to add NGINX:services: website: build: context: ./website dockerfile: Dockerfile ports: - "3000:3000" nginx: build: context: ./nginx dockerfile: Dockerfile ports: - "80:80" depends_on: - website
-
Create
.github/workflows/deploy.yml
:name: Deploy to AWS EC2 on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: # - Checkout, build Docker image, SSH to EC2 and deploy
-
Configure your steps for Docker builds and SSH-based deployment.
-
Push to your main branch to trigger deployment.
- Set
output: 'standalone'
in yournext.config.js
for production-ready builds. - Use
.env
files and secure secrets. - For SSL, configure Let's Encrypt as needed.
Happy Coding!
This document provides a detailed, line-by-line explanation of a multi-stage Dockerfile designed for a production-ready Next.js application. The goal is to create a small, secure, and efficient Docker image.
The process is broken down into three main stages:
deps
: Installs the necessary Node.js dependencies.builder
: Builds the Next.js application.runner
: Creates the final, lightweight image to run the application.
This first stage is dedicated solely to installing the project's dependencies. By isolating this step, Docker can cache the result, making future builds much faster if the dependencies haven't changed.
ARG NODE=node:20-alpine
FROM ${NODE} AS deps