You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

579 lines
11 KiB
Markdown

### 1. Многоступенчатая сборка образов
#### 1.1.1
````Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS api_build
WORKDIR /src
COPY ./TodoApi /src
RUN dotnet restore TodoApi.csproj
RUN dotnet build TodoApi.csproj -c Release -o /app/build
FROM api_build AS publish
RUN dotnet publish TodoApi.csproj -c Release -o /app/publish
FROM node:21 AS ui_build
WORKDIR /src
COPY ./todo_ui /src
RUN npm install
RUN npm run build
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
COPY --from=publish /app/publish .
COPY --from=ui_build /src/wwwroot ./wwwroot
ENTRYPOINT ["./TodoApi"]
````
В директории todo_app:
````bash
docker build -t todo-bundle .
````
#### 1.1.2
Создание сети:
````bash
docker network create todo
````
Создание тома для PostgerSQL:
````bash
docker volume create todo_pgdata
````
Запуск PostgreSQL:
````bash
docker run -d --name=todo_postgres --network=todo -e POSTGRES_DB=todo -e POSTGRES_USER=todo -e POSTGRES_PASSWORD=todo --mount type=bind,source=./initdb,target=/docker-entrypoint-initdb.d --mount type=volume,source=todo_pgdata,target=/var/lib/postgresql/data postgres:16
````
#### 1.1.3
````bash
docker run --rm -p 8080:80 --name todo_bundle -e 'ConnectionStrings__PostgreSQL=Host=todo_postgres;Port=5432;Database=todo;Username=todo;Password=todo' --name=todo_bundle --network=todo -t todo-bundle
````
#### 1.2.1
````bash
docker container rm -f todo_bundle && docker image rm -f todo-bundle
````
Докер-файл для API-сервиса
````Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY . /src
RUN dotnet restore TodoApi.csproj
RUN dotnet build TodoApi.csproj -c Release -o /app/build
FROM build AS publish
RUN dotnet publish TodoApi.csproj -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["./TodoApi"]
````
Сборка образа API-сервиса:
(из директории `TodoApi`)
````bash
docker build -t todo-api .
````
Конфигурация Nginx:
````nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
#gzip on;
keepalive_timeout 65;
server {
listen 80;
location / {
root /var/www/todo;
index index.html;
try_files $uri $uri/ /index.html =404;
}
location /api {
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffers 8 64k;
proxy_busy_buffers_size 128k;
proxy_buffer_size 64k;
client_max_body_size 10m;
proxy_http_version 1.1;
proxy_pass http://todo_api;
}
}
}
````
Докер-файл для JS-приложения:
````Dockerfile
FROM node:21 AS ui_build
WORKDIR /build
COPY . /build
RUN npm install
RUN npm run build
FROM nginx AS base
WORKDIR /var/www/todo
COPY --from=ui_build /build/nginx.conf /etc/nginx/nginx.conf
COPY --from=ui_build /build/wwwroot ./
````
Сборка образа UI:
(из директории `todo_ui`)
````bash
docker build -t todo-ui .
````
#### 1.2.2
Запуск API-сервиса:
````bash
docker run -d --name=todo_api --network=todo -e 'ConnectionStrings__PostgreSQL=Host=todo_postgres;Port=5432;Database=todo;Username=todo;Password=todo' todo-api
````
Запуск UI:
````bash
docker run -d -p 8080:80 --name=todo_ui --network=todo todo-ui
````
#### 1.2.3
````Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:7.0-bullseye-slim AS build
WORKDIR /src
COPY . /src
RUN dotnet restore TodoApi.csproj
RUN dotnet build TodoApi.csproj -c Release -o /app/build
FROM build AS publish
RUN dotnet publish TodoApi.csproj --self-contained -r linux-x64 -c Release -o /app/publish
FROM debian:bullseye-slim AS base
WORKDIR /app
RUN apt-get update && apt-get install libicu67
COPY --from=publish /app/publish .
ENTRYPOINT ["./TodoApi"]
````
В директории `TodoApi`:
````bash
docker build -t todo-api .
````
Запуск, как и выше:
````bash
docker run -d --name=todo_api --network=todo -e 'ConnectionStrings__PostgreSQL=Host=todo_postgres;Port=5432;Database=todo;Username=todo;Password=todo' todo-api
````
### 2. Политики перезапуска
#### 1.
Добавить в `docker run` опцию `--restart=unless-stopped`
#### 2.
````bash
docker run -d --name=todo_postgres --network=todo -e POSTGRES_DB=todo -e POSTGRES_USER=todo -e POSTGRES_PASSWORD=todo --mount type=bind,source=./initdb,target=/docker-entrypoint-initdb.d --mount type=volume,source=todo_pgdata,target=/var/lib/postgresql/data --health-cmd='pg_isready -U todo -d todo' --health-interval=10s --health-retries=5 --health-timeout=5s --health-start-period=10s --restart=unless-stopped postgres:16
````
### 3. Ограничения ресурсов
#### 1.
Добавить опцию `--memory` в `docker run`
#### 2.
Добавить опцию `--cpus` в `docker run`
### 4. Docker compose
#### 1.
`docker compose version`
https://docs.docker.com/compose/install/linux/
#### 1.
````yaml
version: '3.9'
services:
hello:
image: busybox
entrypoint: /bin/echo 'Hello, World!'
````
Запуск, здесь и далее: `docker compose up`
#### 2.
из директории `cats_app` из прошлой лабы:
Dockerfile взять из solutions.md оттуда
````yaml
version: '3.9'
services:
cats_app:
container_name: cats_app
image: cats-app
build:
context: ../
dockerfile: ./cats_app/Dockerfile
networks:
- cats
nginx:
image: nginx
container_name: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- cats_app
ports:
- 5000:80
networks:
- cats
networks:
cats:
driver: bridge
````
#### 3.
см. ниже
#### 4.
````yaml
version: '3.9'
services:
todo_api:
image: todo-api:latest
container_name: todo_api
depends_on:
- todo_postgres
build: ./TodoApi
environment:
ConnectionStrings__PostgreSQL: "Host=todo_postgres;Port=5432;Database=todo;Username=todo;Password=todo"
ASPNETCORE_URLS: 'http://*:80'
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 500M
networks:
- todo
todo_ui:
image: todo-ui:latest
container_name: todo_ui
depends_on:
- todo_api
build: ./todo_ui
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 300M
ports:
- 8080:80
networks:
- todo
todo_postgres:
image: postgres:16
container_name: todo_postgres
environment:
POSTGRES_DB: "todo"
POSTGRES_USER: "todo"
POSTGRES_PASSWORD: "todo"
PGDATA: "/var/lib/postgresql/data"
volumes:
- ./initdb:/docker-entrypoint-initdb.d
- todo_pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U todo -d todo"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
restart: unless-stopped
deploy:
resources:
limits:
cpus: '2'
memory: 800M
networks:
- todo
todo_pgadmin:
container_name: todo_pgadmin
image: dpage/pgadmin4:7
depends_on:
- todo_postgres
environment:
PGADMIN_DEFAULT_EMAIL: "todo@example.com"
PGADMIN_DEFAULT_PASSWORD: "todo"
PGADMIN_CONFIG_SERVER_MODE: "False"
volumes:
- todo_admin_data:/var/lib/pgadmin
ports:
- "5050:80"
restart: unless-stopped
networks:
- todo
volumes:
todo_pgdata:
todo_admin_data:
networks:
todo:
driver: bridge
````
### 5. Docker Swarm
#### 1.
````bash
docker swarm init
````
Потом необходимо запомнить токен
#### 2.
````bash
docker node ls
````
#### 3.
````bash
docker swarm join-token worker
````
#### 4.
````bash
docker network create -d overlay todo_swarm
````
#### 5.
````bash
docker volume create todo_swarm_pgdata --sharing onewriter
````
#### 6.
````bash
docker service create --name=todo_postgres --replicas 1 --network=todo_swarm -e POSTGRES_DB=todo -e POSTGRES_USER=todo -e POSTGRES_PASSWORD=todo --mount type=bind,source=./initdb,target=/docker-entrypoint-initdb.d --mount type=volume,source=todo_swarm_pgdata,target=/var/lib/postgresql/data --health-cmd='pg_isready -U todo -d todo' --health-interval=10s --health-retries=5 --health-timeout=5s --health-start-period=10s postgres:16
````
#### 7.
````bash
docker service create --name=todo_api --replicas 1 --network=todo_swarm -e 'ConnectionStrings__PostgreSQL=Host=todo_postgres;Port=5432;Database=todo;Username=todo;Password=todo' -e 'ASPNETCORE_URLS=http://*:80' todo-api
````
#### 8.
````bash
docker service create -p 8080:80 --name=todo_ui --replicas 1 --network=todo_swarm todo-ui
````
#### 9.
Открыть localhost:8080 в браузере
#### 10.
````bash
docker service scale todo_ui=3 todo_api=3
````
#### 11.
````bash
docker service ps todo_ui
````
````bash
docker service ps todo_api
````
#### 12.
````bash
docker service logs todo_api
````
#### 13.
````bash
docker service rm todo_api && docker service rm todo_ui && docker service rm todo_postgreq
````
#### 14
````yaml
version: '3.9'
services:
todo_api:
image: todo-api:latest
depends_on:
- todo_postgres
environment:
ConnectionStrings__PostgreSQL: "Host=todo_postgres;Port=5432;Database=todo;Username=todo;Password=todo"
ASPNETCORE_URLS: 'http://*:80'
deploy:
mode: replicated
replicas: 3
resources:
limits:
cpus: '1'
memory: 500M
networks:
- todo
todo_ui:
image: todo-ui:latest
depends_on:
- todo_api
deploy:
mode: replicated
replicas: 3
resources:
limits:
cpus: '1'
memory: 300M
ports:
- 8080:80
networks:
- todo
todo_postgres:
image: postgres:16
environment:
POSTGRES_DB: "todo"
POSTGRES_USER: "todo"
POSTGRES_PASSWORD: "todo"
PGDATA: "/var/lib/postgresql/data"
volumes:
- ./initdb:/docker-entrypoint-initdb.d
- todo_pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U todo -d todo"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
deploy:
resources:
limits:
cpus: '2'
memory: 800M
networks:
- todo
todo_pgadmin:
image: dpage/pgadmin4:7
depends_on:
- todo_postgres
environment:
PGADMIN_DEFAULT_EMAIL: "todo@example.com"
PGADMIN_DEFAULT_PASSWORD: "todo"
PGADMIN_CONFIG_SERVER_MODE: "False"
volumes:
- todo_admin_data:/var/lib/pgadmin
ports:
- "5050:80"
networks:
- todo
volumes:
todo_pgdata:
todo_admin_data:
networks:
todo:
driver: overlay
````
#### 15.
````bash
docker stack deploy --compose-file docker-compose.yml
````