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.
11 KiB
11 KiB
1. Многоступенчатая сборка образов
1.1.1
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:
docker build -t todo-bundle .
1.1.2
Создание сети:
docker network create todo
Создание тома для PostgerSQL:
docker volume create todo_pgdata
Запуск PostgreSQL:
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
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
docker container rm -f todo_bundle && docker image rm -f todo-bundle
Докер-файл для API-сервиса
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
)
docker build -t todo-api .
Конфигурация 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-приложения:
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
)
docker build -t todo-ui .
1.2.2
Запуск API-сервиса:
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:
docker run -d -p 8080:80 --name=todo_ui --network=todo todo-ui
1.2.3
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
:
docker build -t todo-api .
Запуск, как и выше:
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.
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.
version: '3.9'
services:
hello:
image: busybox
entrypoint: /bin/echo 'Hello, World!'
Запуск, здесь и далее: docker compose up
2.
из директории cats_app
из прошлой лабы:
Dockerfile взять из solutions.md оттуда
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.
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.
docker swarm init
Потом необходимо запомнить токен
2.
docker node ls
3.
docker swarm join-token worker
4.
docker network create -d overlay todo_swarm
5.
docker volume create todo_swarm_pgdata --sharing onewriter
6.
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.
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.
docker service create -p 8080:80 --name=todo_ui --replicas 1 --network=todo_swarm todo-ui
9.
Открыть localhost:8080 в браузере
10.
docker service scale todo_ui=3 todo_api=3
11.
docker service ps todo_ui
docker service ps todo_api
12.
docker service logs todo_api
13.
docker service rm todo_api && docker service rm todo_ui && docker service rm todo_postgreq
14
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.
docker stack deploy --compose-file docker-compose.yml