Creating a Docker Image with Docker Compose
Now that you are familiar with Docker and Nginx, we will go over the process of dockerizing a Next.js application.
Steps
-
Create a Next.js application in a project root directory:
npx create-next-appYou will need to pick a name for your application and specify a few preferences as shown below:

-
Navigate to the
nextjs-nginx-tutorialdirectory, then create aclientdirectory.Move all files and directories to the
clientdirectory. -
Create an
nginxdirectory under thenextjs-nginx-tutorialdirectory.Navigate to the
nginxdirectory.Create a
nginx.conffile in the same directory using the text editor of your choice and paste the following content:server { listen 8080; server_name localhost; location / { proxy_pass http://client:3000/; proxy_redirect default; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header X-Forwarded-Proto $scheme; } }This is an Nginx configuration. We want the content to be served from the Nginx server’s
localhost:8080and we want the root (/) oflocalhost:8080to serve contents in theclientcontainer’s port 3000.Then create a
Dockerfileusing the text editor of your choice and paste the following content:FROM nginx:1.23.3-alpine RUN rm /etc/nginx/conf.d/default.conf COPY ./nginx.conf /etc/nginx/conf.dA
Dockerfileis a text document that contains all the commands a user could call on the command line to assemble an image. In theDockerfileabove, we instruct Docker to retrieve the official Nginx image, then remove thedefault.confand copynginx.conffrom local to the image’s/etc/nginx/conf.ddirectory. -
Navigate back to
nextjs-nginx-tutorialdirectory.Create a
docker-compose.yamlfile in the same directory using the text editor of your choice and paste the following content:services: client: build: ./client/ ports: - 3000 volumes: - ./client/:/client - /client/node_modules nginx: build: ./nginx/ ports: - "8080:8080" depends_on: - clientThe Compose file defines the services, networks and volumes used for a Docker application. In the example above, we’re creating two services,
clientandnginx. In theclientcontainer, we’re using thebuildattribute to indicate the instructions to build the container image (i.e. aDockerfile) can be found in theclientdirectory, which we will talk about it in the next step, and that this container will publish its port 3000.In the
nginxcontainer, we indicate the container’s port 8080 will be published to the port 8080 of our local machine and this container image will only be built after theclientis successfully built. -
Navigate to the
clientdirectory.Create a
Dockerfileusing the text editor of your choice and paste the following content:FROM node:16-alpine WORKDIR /client COPY . /client/ RUN npm install EXPOSE 3000 CMD npm run devIn the
Dockerfileabove, we instruct Docker to retrieve the official Node.js image with the Alpine Linux distro. Alpine Linux is a very lightweight Linux distro focused on security and a small file size. We then set our working directory and copy over our project files to our image. Next, we runnpm installto install all the project dependencies. Finally, we expose the listening port (i.e. port 300) and issue thenpm run devcommand to start the container from our image. -
Run the resulting containers!
Run the following command in the directory containing the
docker-compose.yamlfile.docker-compose -p <container-name> up --build