← All posts

How to Run This NestJS Blog Project in Docker: Building the Image, Starting the Container, and Opening It

A step-by-step guide for students new to Docker — three commands take you from source code to a running blog at localhost:3000, with an explanation of what each one does.

Goal

Run this blog on your own machine inside a Docker container, without installing Node.js.

Everything the project needs — Node 20, the dependencies, the compiled code — is built into the image. If Docker is installed, you have enough.


Before you start

Docker must be installed and running.

Open a terminal in the automation/ folder. This matters: it holds the Dockerfile and package.json, and Docker looks for them in the folder you run the command from.

cd AWS_Demo_Project/automation

Step 1 — Build the image

An image is a packaged snapshot of the application: the code, its dependencies, and the Node runtime, frozen together.

docker build -t blog .
  • -t blog gives the image a name, so you can refer to it as blog later
  • . means "build using this folder" — it is not a typo, and it must be there

The first build takes a minute or two. It installs the npm packages and compiles the TypeScript inside the image. Wait until it finishes and you see blog:latest mentioned in the last lines.


Step 2 — Run the container

A container is a running instance of that image. The image is the recipe; the container is the meal.

docker run -d --name blog -p 3000:3000 \
  -e ADMIN_PASSWORD=dev-password \
  -v blog_data:/app/data \
  blog

On Windows PowerShell the \ continuation does not work, so use one line:

docker run -d --name blog -p 3000:3000 -e ADMIN_PASSWORD=dev-password -v blog_data:/app/data blog

What each part does:

Part Meaning
-d Run in the background and give your terminal back
--name blog Name the container blog so later commands are easy to type
-p 3000:3000 Connect port 3000 on your machine to port 3000 inside the container
-e ADMIN_PASSWORD=dev-password Sets the admin password. Without it, you cannot sign in at all
-v blog_data:/app/data Saves posts and images outside the container, so they are not lost
blog The image to run — the one you built in Step 1

You will see a long string of letters and numbers. That is the container ID, and it means the container started.


Step 3 — Open it

http://localhost:3000

The blog seeds itself with a few starter posts the first time it runs.

To sign in to the admin, go to http://localhost:3000/login and use the password you passed above — dev-password.

Page URL
Blog http://localhost:3000
Admin http://localhost:3000/admin
Login http://localhost:3000/login
Health check http://localhost:3000/health

Useful commands

Check that it is running:

docker ps

See the application logs (add -f to keep watching):

docker logs blog

Stop and remove the container:

docker stop blog
docker rm blog

If you change the code

The image was built with a copy of the code inside it, so editing a file on your computer does not change the running container. You have to rebuild:

docker stop blog
docker rm blog
docker build -t blog .
docker run -d --name blog -p 3000:3000 -e ADMIN_PASSWORD=dev-password -v blog_data:/app/data blog

Your posts survive this. They are stored in blog_data, which lives outside the container.


Common problems

Problem Fix
port is already allocated Something else is using port 3000. Stop it, or use -p 8080:3000 and open port 8080 instead
container name "/blog" is already in use An old container is still there. Run docker rm blog first
Cannot sign in You forgot -e ADMIN_PASSWORD=dev-password
Page does not load Check docker ps. If the container is not listed, run docker logs blog to see why it stopped
Posts disappeared The -v blog_data:/app/data part was missing when you started the container