|
|
### 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
|
|
|
````
|