Home

Docker

Enable Docker Deamon

On Linux

Check status

sudo systemctl status docker

Activate docker

sudo systemctl start docker

Enable/disable docker on system boot

sudo systemctl enable docker / sudo systemctl disable docker

Add User To The Docker Group

To avoid using sudo every time (then logout/login again or execute newgrp docker)

sudo usermod -aG docker $USER

Starting The Container

With Dockerfile

docker build -t my-express-app . # create an image
docker run -p 5000:5000 my-express-app # start the container

Pros:

  • Simple if you’re only running one container.

Cons:

  • You must manually build the image before running it.
  • If you add MongoDB later, managing multiple containers gets trickier.

With Compose File

You need to install docker-compose first

sudo apt install docker-compose-plugin

If an image already exists, that will be used

docker compose up -d creates the image and starts the container(s)

Pros:

  • No need to manually build the image.
  • Everything starts with a single command.
  • Easier container networking (backend & database talk to each other automatically).

Cons:

  • Slightly more setup (the yml file), but worth it if you use multiple containers.

Stopping/restarting the container

When created with a Dockerfile

docker ps    # show running containers and get the container id
docker ps -a # show all containers (even when not running)
docker stop < container_id >   # stop container
docker start < container_id >  # restart container

When Started With Compose File

docker-compose down // stops and removes containers

Stop containers without removing them

docker-compose stop

Stop and remove containers and all images (created with that compose file)

docker-compose down --rmi all

Generic Commands

Check if docker is running

docker info

Show running/all (including stopped) containers

docker ps / docker ps -a

Show images (images are not displayed in the project folder, instead in a different docker storage place)

docker images

Remove Container

docker rm <id> or docker rm <name>

Remove Image

docker rmi <id> or docker rmi <name>

Show docker disc usage

docker system df

Save docker image in a file

docker save -o <image-name>.tar <image-name>

Import docker image from a file

docker load -i <image-name>.tar

Clean up docker container/images

# Removes all stopped containers
# Removes all unused networks
# Removes all dangling images (not tagged or referenced by any container.)
docker system prune

# Like above but deletes all unused images
docker system prune -a

# Additionally removes all volumes
docker system prune --volumes

# Delete all containers (even if running)
docker rm -f $(docker ps -aq)

# Delete all images (even those containers use)
docker rmi -f $(docker images -q)

Connecting/looking into a container

#  with shell, -it = interactive and terminal
docker exec -it < name or id > sh

# with bash (not available in all images)
docker exec -it < name or id > bash

Sample Docker File

Dockerfile (no file extension like .txt)

# alpine is a lightweight linux distribution
FROM node:18-alpine 
# the working directory inside the container
WORKDIR /app 
# copies package.json and package-lock.json to the container
COPY package*.json ./ 

RUN npm install
# copies all other files (except those in .dockerignore) to the container
COPY . . 
# container will listen on port 5000, but it's only for documentation
EXPOSE 5000 
# executes node server.js
CMD ["node", "server.js"] 

Sample Compose File

Configures a nodejs backend and a mongodb server

docker-compose.yml

version: '3.9' # Specifies the Docker Compose file format version

networks: # Defines a custom network named app-network
  app-network: # All services in this file will communicate through this network

services: # Each service represents a containerized application
  backend: # Defines a service named backend
    build: . # Tells Docker to build the image from the current directory
    container_name: wiki-backend # Assigns a custom container name wiki-backend to the backend container
    ports:
      - "5000:5000" # Maps port 5000 on the host to port 5000 on the container
    networks:
      - app-network # Connects the backend service to the app-network
    depends_on:
      - mongo  # Ensures MongoDB starts before the backend

  mongo:
    image: mongo:latest # Uses the official MongoDB image from Docker Hub
    container_name: mongo-db
    ports:
      - "27017:27017"
    networks:
      - app-network
    volumes: # Defines a named volume mongo-data for persistent storage of MongoDB data
      - mongo-data:/data/db 

volumes: # Even if the MongoDB container is deleted, the data remains stored on the host machine
  mongo-data:

Run PostgreSQL From Compose File

version: '3.8'
services:
  postgres:
    image: postgres
    container_name: postgres-container
    restart: always
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
      POSTGRES_DB: mydatabase
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Connect using psql from inside the Docker container

docker exec -it postgres-container psql -U myuser -d mydatabase