Architecture

Container - is a process, which has it’s own file system

Docker depends on Kernel

Recap

When we ran a container and doesn’t interact with it, the container simply stopps

Commands

docker pull ubuntu # downloads an image
docker run ubuntu # ducker pull & docker run
docker run -it ubuntu # interactive mode

Show List

docker ps -a  # all containers
docker image ls (or docker images) # all images

Build

docker build -t <name>:version ./path/to/directoryWithDockerFile # tag with a name and a version
docker image tag <name>:version <another-name>:new-version # to change tag later

docker build -t name:v1 .

Clean&Remove

docker container prune removes all containers
docker image prune removes all images
docker image rm <image name or id> docker container rm <container-name> or docker rm <container-name>
docker rm -f <contianer-name> force remove

Exec

Execute a command in a running container
docker exec -it <container-id> <command>
docker exec -it -u <user-name> <id>

Volumes

Stores data on the local machine. So after deleting a container, the volume will be still avaliable
docker volume create <name>
docker volume inspect <name> get an info
docker run -d -p <local>:<container> -v <volume-name>/absolute/path <image>

Copying files

docker cp <container-id>:/absolute/path/to/file ./path/on/the/local/machine from a container to the local machine docker cp ./path/on/the/local/machine <container-id>:/absolute/path/to/file from a local machine to the container

Sharing source files

docker -d -p <80>:<3000> —name <name> -v $(pwd):/app <image>

Run

docker run -it <image> sh Run a new image with in interactive mode with sh command
docker run -d <image> Run an image in detached mode
docker run -p <machine-port>:<container-port> <image> make machne listen on the port of the container

docker run -d -p 5000:3000 -v app-data:/app/data my-project

Logs

docker logs <container-id>

Start&Stop

docker start -i <id> # starts the contianer in the interactive mode
docker start <container-id>
docker stop <container-id>

Dockerfile

docker build -t <name>:<tag> ./path/toDirWithDockerfile
docker run -d -p <local>:<container> --name <name> -v <volume-name> /absolute/path <image>

.dockerignore

To exlude file

node_modules/

Dockerfile

Image is a collection of layers

we can view it by using docker history <image>

Example

FROM node:16.19-alpine3.17

# RUN addgroup app && adduser -S -G app app
# USER app

WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .

ENV API_URL=https://api.app.com

RUN mkdir ./data

CMD ["npm", "start"]

Instructions

  • from
  • workdir
  • copy
  • add
  • run
  • env
  • expose
  • user
  • cmd
  • entrypoint

COPY

COPY . . # all filees in the current work directory
COPY ["with space.txt", "."]
COPY 1.txt 2.txt /app/

ADD

Add is similar to Copy, but you can add files from urls. It also can use compressed file

ADD . .
ADD https://urls.json
ADD compressed.zip

RUN

RUN npm install

ENV

To set an environemntal variable

ENV API_URL=https://api.app.com

EXPOSE

To set what port the container would be listening for
It’s like documentation. It won’t publish port on a host. You need to write docker run -p 3030:3000 to map ports

EXPOSE 3000

USER

Docker uses the root user. It might lead to security problems, therefore we need to create a user

# addgroup group_name && adduser -S -G group_name user_name
RUN addgroup app && adduser -S -G app app

USER app

There might be a problem if you switch to user with limited privileges in the end. If you creating the folder as a root and then switching to app user, you won’t be able to create, modify files

CMD

To not execute every time in which environment you want to start use CMD instruction. Run instruction runs when images is building, in contrast CMD is a runtime instruction. It’s executed when you starts a container.

# CMD sh

# Shell instruction => 
# you need to start a shell as a new proces in order to run this command
CMD npm start

# Exec form
# It's a best practice, since you don't need to crate a shell process =>
# It's faster to clean resources when exeting a container
CMD ["npm", "start"]

ENTRYPOINT

Similar to the CMD, however you can easily overwrite CMD instruction by running docker run <image> sh
To overwrite ENTRYPOINT you need to run docker run <image> —entrypoint sh

# Shell form
ENTRYPOINT npm start

# Exec form
ENTRYPOINT ["npm", "start"]

Docker-compose

docker-compose build
docker-compose build -no-cache -pull
docker-compose up --build -d
docker-compose down
docker-compose ps shows only running continaers from the app

Example

version: "3.8" # docker-compose version

services:
  web:
    build: ./frontend # path to Dockerfile
    ports:
      - 3000:3000 # mappping ports
    volumes:
      - ./frontend:/app # overwrites app folder with frontend in a container

	web-tests:
		image: image_web
		volumes:
			- ./frontend:/app
		command: npm test


  api: 
    depends_on: 
      - db
    build: ./backend
    ports: 
      - 3001:3001
    environment: 
      DB_URL: mongodb://db/

		volumes:
			- ./backend:/app
    command: ./docker-entrypoint.sh

  db:
    image: mongo:4.0-xenial
    ports:
      - 27017:27017
    volumes:
      - volumeName:/data/db

volumes:
  volumeName: