hectoday
DocsCoursesChangelog GitHub
DocsCoursesChangelog GitHub

Access Required

Enter your access code to view courses.

Invalid code

← All courses Deploying Node.js Apps with Docker

Why Docker

  • The "Works on My Machine" Problem
  • Docker Concepts

Your First Dockerfile

  • Writing a Dockerfile
  • Multi-Stage Builds
  • The .dockerignore File

Running Containers

  • Running and Managing Containers
  • Environment Variables and Secrets
  • Health Checks

Multi-Container Apps

  • Docker Compose
  • Adding a Reverse Proxy
  • Persistent Data

Deploying to Production

  • Deploying to a VPS
  • HTTPS with Let's Encrypt
  • Zero-Downtime Deploys

CI/CD

  • Building Images in CI
  • Automated Deployment

Production Hardening

  • Container Security
  • Logging and Monitoring
  • Deployment Checklist and Capstone

Running and Managing Containers

Starting a container

docker run -p 3000:3000 myapp

This starts a container from the myapp image, maps port 3000 on your machine to port 3000 inside the container, and runs the CMD from the Dockerfile.

The terminal is attached — you see the app’s output. Press Ctrl+C to stop.

Detached mode

In production, you want the container to run in the background:

docker run -d -p 3000:3000 --name myapp-container myapp

-d runs detached (in the background). --name myapp-container gives the container a human-readable name instead of a random one like elegant_babbage.

Common docker run flags

-p HOST:CONTAINER — Map a port. -p 8080:3000 means port 8080 on the host forwards to port 3000 in the container.

-d — Detached mode. Run in the background.

--name NAME — Name the container. Makes it easier to reference in other commands.

-e KEY=VALUE — Set an environment variable. -e NODE_ENV=production.

--restart unless-stopped — Restart the container if it crashes or the server reboots. Does not restart if you explicitly stop it.

-v HOST_PATH:CONTAINER_PATH — Mount a volume. Covered in the persistent data lesson.

# Production-style run command
docker run -d \
  -p 3000:3000 \
  --name myapp \
  --restart unless-stopped \
  -e NODE_ENV=production \
  myapp

Managing containers

# List running containers
docker ps

# List all containers (including stopped)
docker ps -a

# View logs
docker logs myapp
docker logs -f myapp    # Follow (like tail -f)
docker logs --tail 50 myapp  # Last 50 lines

# Stop a container
docker stop myapp

# Start a stopped container
docker start myapp

# Restart
docker restart myapp

# Remove a stopped container
docker rm myapp

# Force remove a running container
docker rm -f myapp

Executing commands inside a running container

# Open a shell inside the container
docker exec -it myapp sh

# Run a one-off command
docker exec myapp node -e "console.log(process.env.NODE_ENV)"

# Check what is in the container
docker exec myapp ls /app
docker exec myapp cat /app/package.json

docker exec runs a command inside an existing, running container. -it makes it interactive (for shells).

Inspecting a container

# Full container details (JSON)
docker inspect myapp

# Just the IP address
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' myapp

# Resource usage
docker stats myapp

Exercises

Exercise 1: Build your image and run it in detached mode with a name. Verify it works with curl http://localhost:3000/health.

Exercise 2: View the logs with docker logs. Stop and start the container. View logs again.

Exercise 3: Open a shell inside the container with docker exec -it myapp sh. Look around: ls /app, node --version, cat /app/package.json. Exit with exit.

Exercise 4: Run docker stats myapp to see CPU and memory usage. How much memory does your app use?

What does docker run --restart unless-stopped do?

← The .dockerignore File Environment Variables and Secrets →

© 2026 hectoday. All rights reserved.