# Dock Dree Dive: From Bases to Advanced. NET Contentization

<datetime class="hidden">2025-11-09T14:00</datetime>

<!--category-- Docker, .NET, DevOps, Containers -->
## Вступ

Докер докорінно змінив те, як ми будуємо, на кораблі і запускаємо програми.

Те, що почалося, як простий інструмент контейнеризації, еволюціонувало в повну екосистему для сучасного розвитку та розвитку програм.

1. **[Це четверта і найбільш вичерпна стаття з моєї серії "Докер" для розробників.NET.](/dockercompose)**Якщо ви новий у Докер, вам слід почати з:
2. **[Докер Композитний](/dockercomposedevdeps)**Початок з базових конфігурацій з декількома наборами (липень 2024).
3. **[Залежності розвитку з комбінацією докерів](/imagesharpwithdocker)**- Встановлення локальних середовищ dev (серпень 2024)

Розширення різкості зображень за допомогою DockerName

- **- Розв'язування проблем з дозволом на гучність (серпень 2024)**У цьому глибокому пірнанні ми побудуємо на цих основах для дослідження:
- **Компіляція дошки для виробництва**: Поточний стек, що працює у цьому блозі
- **Самопідтримка обмежених ресурсів**: Практичні методи оптимізації внесків у бюджет
- **Підтримка GPU**: Виконання роботи ML у контейнерах
- **Багатоархічне збирання**: Підтримка ARM64 і AMD64
- **Можливості контейнера. NET 9**: Вбудовані контейнери публікуються без файлів Docker

> . NET Aspire

: Сучасний NET - підхід до ансамблю.

[TOC]

## ЗАУВАЖЕННЯ: це частина моїх експериментів з комп'ютером / способом витратити 100 000 платежів на Code Code.

### Я надав вам папірець, моє розуміння, питання, які я повинен був написати цю статтю.

Это весело и заполняет прорыв, который я больше не видел.

Чи ви впроваджуєте просту веб-програму, чи керуєте складною мікрослужбовою архітектурою з моделями для машинного навчання GPU, цей гід відводить вас від основ Docker до програм, готових до виробництва, - з реальними прикладами від запуску quallucid.com.

- **Фундаменти докера: розуміння контейнерів**Що таке Докер?
- **В основі Докера є платформа контейнеризації, яка пакує вашу програму і всі її залежності у стандартизовану одиницю, що називається контейнером.**На відміну від віртуальних машин, які вибудовують цілі операційні системи, контейнери діляться ядром ОС вузла, підтримуючи ізольовані простори.

### Подумайте про це так:

```bash
# The classic developer problem
"It works on my machine!" 

# The container solution
"Ship your machine!" 
```

Віртуальні машини

1. **: Кожен VM запускає повний набір операційних систем (ядро Linux, системні бібліотеки тощо) - важкий і повільний для запуску**Контейнери
2. **: Спільний доступ до ядра вузла, пакунок лише коду програми і залежностей - легкий і швидкий**Чому розробники мають значення
3. **Контейнери вирішують декілька критичних проблем:**Зручність середовища
4. **: Розробка, тестування та виробничі середовища ідентичні**Незалежність
5. **: Немає більше " пекла " або суперечливих версій бібліотеки**Незламні споруди

### : Те саме вхід = однаковий вивід, кожного разу

#### Швидке впровадження

```bash
# An image is a template (like a class in OOP)
docker pull mcr.microsoft.com/dotnet/aspnet:9.0

# A container is a running instance (like an object)
docker run -d -p 8080:8080 myapp:latest
```

**: Запускати контейнери у секундах, а не у хвилинах**Ефективність ресурсу

```dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:9.0      # Layer 1: Base OS + .NET runtime
WORKDIR /app                                   # Layer 2: Directory structure
COPY *.dll ./                                  # Layer 3: Application files
ENTRYPOINT ["dotnet", "MyApp.dll"]            # Layer 4: Startup command
```

: Запустити десятки контейнерів на одному вузлі

- **Важливі стереотипи докерів**Зображення/ Контейнери
- **Зображення**є незмінні, нашаровані файлові системи.
- **Кожна з настанов у файлі Docker створює новий шар:**Цей шар дуже потужний.

#### Кечінгgreat- britain_ counties. kgm

: Незмінені шари буде повторно використано, збільшення швидкості збирання

```dockerfile
# Multi-stage build: separates build environment from runtime
# Stage 1: Build
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src

# Copy only csproj files first (better layer caching)
COPY ["MyApp/MyApp.csproj", "MyApp/"]
COPY ["MyApp.Core/MyApp.Core.csproj", "MyApp.Core/"]

# Restore dependencies (cached unless csproj changes)
RUN dotnet restore "MyApp/MyApp.csproj"

# Copy everything else
COPY . .

# Build the application
WORKDIR "/src/MyApp"
RUN dotnet build "MyApp.csproj" -c Release -o /app/build

# Stage 2: Publish
FROM build AS publish
RUN dotnet publish "MyApp.csproj" -c Release -o /app/publish /p:UseAppHost=false

# Stage 3: Final runtime image
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS final
WORKDIR /app

# Create non-root user for security
RUN addgroup --gid 1001 appuser && \
    adduser --uid 1001 --gid 1001 --disabled-password --gecos "" appuser

# Copy published output from publish stage
COPY --from=publish /app/publish .

# Switch to non-root user
USER appuser

# Expose port (documentation only, doesn't actually publish)
EXPOSE 8080

# Set environment variables
ENV ASPNETCORE_URLS=http://+:8080
ENV ASPNETCORE_ENVIRONMENT=Production

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:8080/health || exit 1

ENTRYPOINT ["dotnet", "MyApp.dll"]
```

**Спільне користування**

1. **: Декілька зображень можуть ділитися базовими шарами.**Ефективність
2. **: Потрібно звантажити/ завантажити лише змінені шари**Найкращі вправи Dockerfile
3. **Ось готовий до виробництва файл. NET Dockerfile з коментарями:**Унаочнення ключових принципів:
4. **Багатостратегійне збирання**: Відокремлені етапи збирання/ пубуляції різко зменшують кінцевий розмір зображення.
5. **Оптимізація шару**: Копіювати файли залежностей перед початковим кодом для кращого кешування

#### Безпека

```bash
# Build the image
docker build -t myapp:1.0.0 -t myapp:latest .

# Run with common options
docker run -d \
  --name myapp \
  -p 8080:8080 \
  -e ConnectionStrings__DefaultConnection="Server=db;Database=myapp" \
  -v /data/logs:/app/logs \
  --restart unless-stopped \
  myapp:latest

# View logs
docker logs -f myapp

# Execute commands inside running container
docker exec -it myapp /bin/bash

# Stop and remove
docker stop myapp
docker rm myapp
```

## : Запустити від імені користувача, який не є адміністратором

Перевірка здоров'я

### : Оргатори можуть стежити за станом застосування.

Явне середовище

- : Встановити типові значення виробництва
- Будівництво і біг
- Докер Композиція: Багатоконечний оркестр
- Докер Композитний надає вам змогу визначати і запускати програми, які містять багато контейнерів.
- Замість керування контейнерами окремо, ви описуєте весь ваш стос програм у файлі YAML.

Чому дошки з'єднані?`docker run`Розглянемо типову веб- програму.NET:

### Веб-програма ASP.NET

База даних PostgreSQL**Кеш Redis`docker-compose.yml`**Сек для ведення журналу

```yaml
services:
  # Main ASP.NET Core application
  mostlylucid:
    image: scottgal/mostlylucid:latest
    restart: always
    healthcheck:
      test: [ "CMD", "curl", "-f -K", "https://mostlylucid:7240/healthy" ]
      interval: 30s
      timeout: 10s
      retries: 5
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    env_file:
      - .env
    environment:
      - Auth__GoogleClientId=${AUTH_GOOGLECLIENTID}
      - Auth__GoogleClientSecret=${AUTH_GOOGLECLIENTSECRET}
      - Auth__AdminUserGoogleId=${AUTH_ADMINUSERGOOGLEID}
      - SmtpSettings__UserName=${SMTPSETTINGS_USERNAME}
      - SmtpSettings__Password=${SMTPSETTINGS_PASSWORD}
      - Analytics__UmamiPath=${ANALYTICS_UMAMIPATH}
      - Analytics__WebsiteId=${ANALYTICS_WEBSITEID}
      - ConnectionStrings__DefaultConnection=${POSTGRES_CONNECTIONSTRING}
      - TranslateService__ServiceIPs=${EASYNMT_IPS}
      - Serilog__WriteTo__0__Args__apiKey=${SEQ_API_KEY}
      - Markdown__MarkdownPath=${MARKDOWN_MARKDOWNPATH}
    volumes:
      - /mnt/imagecache:/app/wwwroot/cache
      - /mnt/logs:/app/logs
      - /mnt/markdown:/app/markdown
      - ./mostlylucid.pfx:/app/mostlylucid.pfx
      - /mnt/articleimages:/app/wwwroot/articleimages
      - /mnt/mostlylucid/uploads:/app/wwwroot/uploads
    networks:
      - app_network
    depends_on:
      - db

  # PostgreSQL database
  db:
    image: postgres:16-alpine
    ports:
      - 5266:5432  # Custom external port to avoid conflicts
    env_file:
      - .env
    networks:
      - app_network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 5s
      timeout: 5s
      retries: 5
    volumes:
      - /mnt/umami/postgres:/var/lib/postgresql/data
    restart: always

  # Cloudflare tunnel for secure external access
  cloudflared:
    image: cloudflare/cloudflared:latest
    command: tunnel --no-autoupdate run --token ${CLOUDFLARED_TOKEN}
    env_file:
      - .env
    restart: always
    networks:
      - app_network

  # Umami analytics
  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    env_file: .env
    environment:
      DATABASE_URL: ${DATABASE_URL}
      DATABASE_TYPE: ${DATABASE_TYPE}
      HASH_SALT: ${HASH_SALT}
      APP_SECRET: ${APP_SECRET}
      TRACKER_SCRIPT_NAME: getinfo
      API_COLLECT_ENDPOINT: all
    depends_on:
      - db
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    networks:
      - app_network
    restart: always

  # Translation service (CPU-limited for resource management)
  easynmt:
    image: easynmt/api:2.0.2-cpu
    volumes:
      - /mnt/easynmt:/cache/
    deploy:
      resources:
        limits:
          cpus: "4.0"  # Prevent translation service from consuming all CPU
    networks:
      - app_network

  # Caddy reverse proxy with automatic HTTPS
  caddy:
    image: caddy:latest
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - app_network
    restart: always

  # Seq centralized logging
  seq:
    image: datalust/seq
    container_name: seq
    restart: unless-stopped
    environment:
      ACCEPT_EULA: "Y"
      SEQ_FIRSTRUN_ADMINPASSWORDHASH: ${SEQ_DEFAULT_HASH}
    volumes:
      - /mnt/seq:/data
    networks:
      - app_network

  # Prometheus metrics collection
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
      - prometheus-data:/prometheus
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    networks:
      - app_network

  # Grafana visualization
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    volumes:
      - grafana-data:/var/lib/grafana
    networks:
      - app_network
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}

  # Host metrics exporter
  node_exporter:
    image: quay.io/prometheus/node-exporter:latest
    container_name: node_exporter
    command:
      - '--path.rootfs=/host'
    networks:
      - app_network
    restart: unless-stopped
    volumes:
      - '/:/host:ro,rslave'

  # Automatic container updates
  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_LABEL_ENABLE=true
    command: --interval 300  # Check every 5 minutes

volumes:
  grafana-data:
  caddy_data:
  caddy_config:
  prometheus-data:

networks:
  app_network:
    driver: bridge
```

**Може бути, послуга працівника на фоні.**

1. **Керування цими окремими елементами з**команди стають невихованими.`app_network`Докер Комос вирішує це.
2. **Повний приклад реального світу: Платформа блогу для виробництва**Ось вам`/mnt/*`поточне виробництво
3. **цей сайт (здебільшого за все locid.com):**Шаблони створення ключів:
4. **Одна мережа**: Всі служби on
5. **для простоти**Прив' язки до змонтувань
6. **: Шляхи вузлів (**) для постійних даних, які вам потрібні для створення резервної копії/ доступу
7. **Іменовані гучності**: Обладнання зберігання даних для даних, до яких вам не потрібен безпосередній доступ`.env`Мітки " Вартової башти "

### : Тільки служби оновлення явно позначені для автооновлення

#### Обмеження виконавців

```yaml
services:
  web:
    depends_on:
      db:
        condition: service_healthy  # Wait for health check
      redis:
        condition: service_started  # Just wait for start
```

: Обмеження процесора на перекладацьку службу запобігають голоду.`condition: service_healthy`Приписування зовнішніх портів

#### : PostgreSQL на 5266 замість 5432 для уникнення конфліктів з іншими екземплярами

```bash
# .env file (never commit to git!)
DB_PASSWORD=super_secret_password
SMTP_PASSWORD=another_secret
```

```yaml
services:
  web:
    environment:
      - DB_PASSWORD=${DB_PASSWORD}  # From .env file
      - STATIC_VALUE=production     # Hardcoded
    env_file:
      - .env                        # Load entire file
```

Файли середовища

#### : Секрети в

```yaml
services:
  db:
    volumes:
      # Named volume (managed by Docker)
      - postgres_data:/var/lib/postgresql/data

  web:
    volumes:
      # Bind mount (maps host directory to container)
      - ./data/markdown:/app/Markdown
      - ./logs:/app/logs
```

**файл (ніколи не передано git)**:

- Можливості комбінування ключів
- Залежності служб
- Порядок запуску оркестрів Docker Compose.
- The

**Перш ніж запускати веб-програму, потрібно пройти перевірку здоров'я бази даних.**:

- Змінні середовища і таємниці
- Для секретів виробництва скористайтеся Doncker Секрети або зовнішніми інструментами для керування секретами (OWS Decutor, Azure key Vault, HashhiCorp Vault).
- Змонтовані об' єкти/ Прив' язки

#### Іменовані томи

```yaml
networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge

services:
  web:
    networks:
      - frontend
      - backend

  db:
    networks:
      - backend  # Not exposed to frontend
```

Керується комбінацією

#### Настійні дані через місткість перезапускаються

```yaml
services:
  db:
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
```

Можна створити резервну копію за допомогою команд Docker

- Сумісний з міжплатформами
- Змонтувати прив' язки
- Пряма прив' язка до файлової системи вузла

### Корисно для розробки (підзарядки з кодом)

```bash
# Start all services (detached)
docker-compose up -d

# Start specific services
docker-compose up -d web db

# View logs (all services)
docker-compose logs -f

# View logs (specific service)
docker-compose logs -f web

# Stop services (containers remain)
docker-compose stop

# Stop and remove containers
docker-compose down

# Stop, remove containers, and remove volumes
docker-compose down -v

# Rebuild and restart
docker-compose up -d --build

# Scale a service
docker-compose up -d --scale worker=3

# Execute command in running service
docker-compose exec web /bin/bash

# Run one-off command
docker-compose run --rm web dotnet ef database update
```

### Файли налаштування, журнали, вивантаження

Робота у мережі

**Мережа забезпечує ізоляцію.**Тут база даних доступна лише для служб серверів, а не безпосередньо.

```yaml
services:
  web:
    build: .
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
```

**Перевірка здоров'я**Докер може перевіряти стан здоров'я:

```yaml
services:
  web:
    volumes:
      - .:/app  # Live code reloading
    ports:
      - "5000:8080"
```

**Визначає, чи є контейнер насправді готовим (не лише запуском)**Перезапустити нездорові контейнери

```yaml
services:
  web:
    image: registry.example.com/myapp:${VERSION}
    restart: always
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '2'
          memory: 2G
```

```bash
# Development (base + override)
docker-compose up -d

# Production
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
```

## Надайте статус оркестраторам (Kubernetes, Docker Furm)

Звичайні команди докерів

### Розробка/ Виробництво файлів

```bash
# Install NVIDIA Container Toolkit (Ubuntu/Debian)
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

# Configure Docker daemon
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

# Test GPU access
docker run --rm --gpus all nvidia/cuda:12.6.0-base-ubuntu24.04 nvidia-smi
```

### Об' єм проблем, пов' язаних з декількома файлами складання:

```dockerfile
# Use NVIDIA CUDA base image
FROM nvidia/cuda:12.6.0-cudnn-runtime-ubuntu24.04

# Install Python
RUN apt-get update && apt-get install -y \
    python3.12 \
    python3-pip \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Install PyTorch with CUDA support
COPY requirements.txt .
RUN pip3 install --no-cache-dir torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124

# Copy application
COPY . .

# Test GPU on container start
RUN python3 -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}'); print(f'GPU: {torch.cuda.get_device_name(0) if torch.cuda.is_available() else \"None\"}')"

ENTRYPOINT ["python3", "train.py"]
```

### docker-compose.yml

```bash
# Run with all GPUs
docker run --gpus all myapp:gpu

# Run with specific GPUs
docker run --gpus '"device=0,2"' myapp:gpu

# Run with GPU memory limits
docker run --gpus all --memory=16g myapp:gpu
```

### (base):

```yaml
services:
  ml-trainer:
    build:
      context: .
      dockerfile: Dockerfile.gpu
    image: myapp:gpu
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all  # or specific count: 1, 2, etc.
              capabilities: [gpu]
    volumes:
      - ./models:/app/models
      - ./data:/app/data
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - CUDA_VISIBLE_DEVICES=0,1  # Use GPUs 0 and 1
```

### docker-compose. oververse.yml

(розробка - автоматичне об'єднання):[docker-compose.prod.yml](https://github.com/scottgal/mostlylucid-nmt)(продукція):

Підтримка GPU в Docker: Завантаження роботи Acceatith ML

- **Вивчення машин, наукове обчислювання та програм для комп'ютерної обробки часто вимагають прискорення процесора.**Docker підтримує GPU NVIDIA через інструмент контейнера NVIDIA.
- **Налаштування набору інструментів контейнера NVIDIA**Dockerfile для програми GPU- Accelified Python/PyTorch
- **Запуск контейнерів GPU**GPU в Docker Compose
- **Приклад реального світу: Служба перекладу з GPU та збирання процесора**Ось справжній приклад виробництва з

#### umcid-nmt

```yaml
services:
  translation:
    image: scottgal/mostlylucid-nmt:gpu
    container_name: translation-gpu
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    environment:
      - MODEL_FAMILY=opus-mt
      - FALLBACK_MODELS=mbart50,m2m100
      - CUDA_VISIBLE_DEVICES=0
      - LOG_LEVEL=info
    volumes:
      - model_cache:/app/cache  # Persistent model storage
    ports:
      - "8888:8888"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8888/health"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  model_cache:
```

#### Нейромеханічна служба перекладу, яку я збудував на цьому блозі.

Проект продемонстрирует:

```yaml
services:
  translation:
    image: scottgal/mostlylucid-nmt:cpu
    container_name: translation-cpu
    environment:
      - MODEL_FAMILY=opus-mt
      - FALLBACK_MODELS=mbart50,m2m100
    volumes:
      - model_cache:/app/cache
    ports:
      - "8888:8888"
    restart: unless-stopped

volumes:
  model_cache:
```

**Варіанти GPU і процесора**

- `scottgal/mostlylucid-nmt:gpu`- Та сама база коду, різні базові зображення
- `scottgal/mostlylucid-nmt:cpu`Багатоархічне збирання
- `scottgal/mostlylucid-nmt:gpu-min`- Підтримує AMD64 і ARM64
- `scottgal/mostlylucid-nmt:cpu-min`Оптимізовані зображення Docker

**- Повних і мінімальних варіантів**

- **Виробництво- готове**- Перевірка здоров'я, інтенсивність об'єму, належне ведення лісозаготівель.
- **Служба перекладу GPU**Альтернативна лише ЦП
- **Для середовищ без GPU, та сама служба виконується на процесорі:**Доступні варіанти зображення:
- **- CUDA 12.6 з підтримкою PyTorch GPU (~5GB)**- Тільки ЦП, менший відбиток (~ 2. 5GB)
- **- Мінімальне збирання GPU, без попередньо завантажених моделей (~4GB)**: `/health`- Мінімальне збирання процесора (~1. 5GB)`/ready`Можливості ключів:
- **Прискорення GPU**: 10-15x швидший переклад з CUDA

Модель Автозавантаження[: Звантажує моделі перекладу на- demand](https://github.com/scottgal/mostlylucid-nmt)Підтримка зворотного стану

## : Treees Opus-MT → mBART50 → M2M100 для максимального покриття мови

Наполегливість у об' ємі

### : Моделі кешу через перезапуск контейнера

```bash
# Problem: Image built on M1 Mac won't run on Linux server
docker build -t myapp:latest .  # Builds for ARM64
docker push myapp:latest
# Server tries to run it... error: "exec format error"

# Solution: Build for multiple platforms
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest --push .
```

### Кінець здоров'ю

і

```bash
# Verify buildx is available
docker buildx version

# Create a new builder instance
docker buildx create --name multiarch --driver docker-container --use

# Inspect and bootstrap the builder
docker buildx inspect --bootstrap

# List available platforms
docker buildx inspect | grep Platforms
```

### для оркестраторів

Багатоархітектура

```dockerfile
# Use official multi-arch base images
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base

# For platform-specific operations, use build arguments
ARG TARGETPLATFORM
ARG BUILDPLATFORM

RUN echo "Building on $BUILDPLATFORM for $TARGETPLATFORM"

# Install architecture-specific dependencies
RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
        apt-get update && apt-get install -y some-arm64-package; \
    elif [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
        apt-get update && apt-get install -y some-amd64-package; \
    fi
```

### : Runs on x86_ 64 and ARM64 (Apple Sicon, Raspberry Pi)

```bash
# Build and push for AMD64 and ARM64
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t myregistry/myapp:latest \
  -t myregistry/myapp:1.0.0 \
  --push \
  .

# Build without pushing (loads into local Docker)
# Note: Can only load one platform at a time
docker buildx build \
  --platform linux/amd64 \
  -t myapp:latest \
  --load \
  .

# Build and export to tar files
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t myapp:latest \
  -o type=tar,dest=./myapp.tar \
  .
```

### Видите

повний проект GitHub

**Для прикладів Dockerfile, збирання скриптів і документації з API.**

```bash
# Build multi-arch images first
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest --push .

# Then use in compose
```

```yaml
services:
  web:
    image: myapp:latest  # Already built for multiple architectures
```

**Мульти- архівний збірок з Docker ЗбиранняxName**

```bash
#!/bin/bash
# build-multiarch.sh

docker buildx build --platform linux/amd64,linux/arm64 \
  -t myregistry/web:latest \
  -f web/Dockerfile \
  --push \
  web/

docker buildx build --platform linux/amd64,linux/arm64 \
  -t myregistry/worker:latest \
  -f worker/Dockerfile \
  --push \
  worker/

docker-compose pull  # Pull the multi-arch images
docker-compose up -d
```

### Сучасні програми повинні працювати на декількох архітектурах: x86_ 64 (AMD64) для серверів, ARM64 для Raspberry Pi і Apple Clibon Macs, іноді навіть ARM32 для вбудованих пристроїв.

Чому багатоархічні питання

```yaml
name: Build and Push Multi-Arch Images

on:
  push:
    branches: [ main ]
    tags: [ 'v*' ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: myregistry/myapp
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha,prefix={{branch}}-

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=registry,ref=myregistry/myapp:buildcache
          cache-to: type=registry,ref=myregistry/myapp:buildcache,mode=max
```

Налаштування збирання

- Докер Збирання буде включено до стільниці Docker.
- Для Linux:
- Багатоархічний файл Dockerfile
- Більшість файлів Dockers працюють без змін, але ось декілька підказок:
- Будівництво декількох платформ

## Мульти- архів з комбінацією Docker

К сожалению, Докер Компос не поддерживает стройку.

### Обмеження роботи:

Параметр 1: Попереднє збирання зображень

```bash
# Publish as a container image (no Dockerfile needed!)
dotnet publish --os linux --arch x64 -p:PublishProfile=DefaultContainer

# Specify image name and tag
dotnet publish \
  --os linux \
  --arch x64 \
  -p:PublishProfile=DefaultContainer \
  -p:ContainerImageName=myapp \
  -p:ContainerImageTag=1.0.0

# Multi-architecture
dotnet publish --os linux --arch arm64 -p:PublishProfile=DefaultContainer
```

### Скрипт збирання 2:

Приклад реального світу: CI/CD Cileline`.csproj`:

```xml
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>

    <!-- Container Configuration -->
    <ContainerImageName>myapp</ContainerImageName>
    <ContainerImageTag>$(Version)</ContainerImageTag>
    <ContainerRegistry>myregistry.azurecr.io</ContainerRegistry>

    <!-- Base image (defaults to mcr.microsoft.com/dotnet/aspnet:9.0) -->
    <ContainerBaseImage>mcr.microsoft.com/dotnet/aspnet:9.0-alpine</ContainerBaseImage>

    <!-- Container runtime configuration -->
    <ContainerWorkingDirectory>/app</ContainerWorkingDirectory>
    <ContainerPort>8080</ContainerPort>
    <ContainerEnvironmentVariable Include="ASPNETCORE_ENVIRONMENT">Production</ContainerEnvironmentVariable>

    <!-- User (security best practice) -->
    <ContainerUser>app</ContainerUser>

    <!-- Labels -->
    <ContainerLabel Include="org.opencontainers.image.description">My awesome app</ContainerLabel>
    <ContainerLabel Include="org.opencontainers.image.source">https://github.com/me/myapp</ContainerLabel>
  </PropertyGroup>
</Project>
```

Процес роботи з діями GitHub для збирання багатоархічних структур:

```bash
dotnet publish -p:PublishProfile=DefaultContainer
```

### Цей процес:

1. **Вмикає пересування на головні теґи або версії програми**Встановлює QEMU для міжплатформової емуляції
2. **Збудова для AMD64 і ARM64**Створює автоматично мітки (назва branch, семантичні версії, SHA)
3. **Використовувати кеш списку для пришвидшення збирання**. NET 9 Удосконалення контейнера
4. **. NET 9 - це істотні покращення у підтримці контейнерів, завдяки чому, як ніколи раніше, легше перетасовувати програми.NET, навіть не написавши Dockerfile.**Видавництво вбудованого контейнера
5. **За допомогою . NET 9 ви можете безпосередньо оприлюднити програму з контейнерами:**Налаштування властивостей контейнера

### Додати до вашого

```xml
<PropertyGroup>
  <!-- Enable trimming to remove unused code -->
  <PublishTrimmed>true</PublishTrimmed>
  <TrimMode>full</TrimMode>

  <!-- OR use Native AOT for even smaller, faster images -->
  <PublishAot>true</PublishAot>
</PropertyGroup>
```

Тоді опублікуйте:

- **Переваги вбудованої підтримки контейнера**Не потрібен файл Docker
- **: Зменшує складність**Оптимізовані зображення
- **: Microsoft налаштовує зображення для швидкодії**Сумісність

### : Стандартні зображення у всіх програмах. NET

**Безпека**

```dockerfile
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY ["MyApp.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish

FROM mcr.microsoft.com/dotnet/aspnet:9.0
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]
```

**: Автоматичне оновлення базових зображень**

```bash
# Just this!
dotnet publish -p:PublishProfile=DefaultContainer
```

Менші зображення

### : Підтримка збирання трімінгів та AOT

**Об' єднання і AT для менших зображень**

- Результати:
- Стандартний
- : ~220МБ
- З обрізанням

**: ~110MБ**

- З АОТО
- : ~12МБ для простих програм!
- Порівняння: Dockerfile vs вбудовано
- Традиційний підхід до файлів Docker:

### Доступ до вбудованого контейнера:

Обидва створюють подібні зображення, але вбудований підхід простіший і придатний для збереження.

```xml
<PropertyGroup>
  <ContainerBaseImage>mcr.microsoft.com/dotnet/aspnet:9.0-noble-chiseled</ContainerBaseImage>
</PropertyGroup>
```

Коли використовувати файл Dockerfile/s вбудовано

- **Використовувати файл Docker, якщо:**Вам потрібен повний контроль над зображенням
- **Встановлення залежностей системи**Комплексне багатостратегічне збирання
- **Нестандартні базові зображення**Використовувати вбудоване, якщо:

Стандартні веб- програми. NET

- Вам потрібна простота
- Переведення Microsoft оптимізації

Швидке прототипування

## Chimeled Ubuntu Images

. NET 9 підтримує " обрізані " зображення Ubuntu - надмінні базові зображення:

### Користі:

Крихітний

1. **: ~50% менше звичайних зображень**Безпечний
2. **: Мінімальна поверхня атаки (без керування пакунками, оболонки)**Швидка
3. **: Швиденько тягне і починає**Торгівля:
4. **Без оболонки (важке для зневаджування)**Обмежені системні програми
5. **Ідеально для виробництва, де безпека та розмір мають найбільше значення.**Вступ до Аспіратора NET

### НЕТ Аспір - це опціонована, "хмарна купа" для створення програм, що розповсюджуються.

Вважайте це Докер Компосом на стероїдах, спеціально розробленим для послуг мікрослужб.

1. **Що таке Аспрі?**Постачальник Apire:
2. **Оркестрація**: Запустити і з' єднати декілька служб локально
3. **Знаходження служб**: Служби знаходять одне одного автоматично

### Телеметрія

**: Вбудована лісозаготівля, метрики, слідкування**

```bash
dotnet new aspire-starter -n MyDistributedApp
cd MyDistributedApp
```

**Компоненти**

```csharp
var builder = DistributedApplication.CreateBuilder(args);

// Add Redis cache
var cache = builder.AddRedis("cache");

// Add PostgreSQL database
var db = builder.AddPostgres("postgres")
               .AddDatabase("mydb");

// Add API service (references cache and db)
var api = builder.AddProject<Projects.MyApi>("api")
                 .WithReference(cache)
                 .WithReference(db);

// Add frontend (references API)
builder.AddProject<Projects.MyWeb>("web")
       .WithReference(api);

builder.Build().Run();
```

**: Попередньо налаштовані інтеграції (Redis, PostgreSQ, RockMQ тощо)**

```csharp
// MyApi/Program.cs
var builder = WebApplication.CreateBuilder(args);

// Aspireing
3.  Multi-stage builds to reduce image size
4.  Use `.dockerignore` generously
5.  Alpine/chiseled images for smaller size
6.  Use volume mounts for development
7.  Configure appropriate resource limits
8.  Use health checks for orchestration

## Troubleshooting Common Issues

### Container Won't Start

```bash
# Check logs
docker logs container-name

# Common issues:
# 1. Port already in use
docker ps | grep 8080  # Find conflicting container
docker stop conflicting-container

# 2. Missing environment variables
docker inspect container-name | grep Env

# 3. Failed health check
docker inspect container-name | grep Health -A 20
```

### Впровадження

```bash
# Enable BuildKit for faster builds
export DOCKER_BUILDKIT=1

# Use build cache
docker build --cache-from myapp:latest -t myapp:latest .

# Check what's taking time
docker build --progress=plain -t myapp:latest .
```

### : Створення дисплеїв Kubernetes/ Docker Compose

```bash
# Containers can't communicate
# Solution: Ensure they're on the same network
docker network ls
docker network inspect network-name

# DNS not working
# Container names are DNS names within Docker networks
docker exec web ping db  # Should work if both on same network
```

### Аспіральна архітектура

```bash
# Permission denied on volume
# Solution: Match user IDs
FROM ubuntu
RUN useradd -u 1000 appuser  # Match host user ID
USER appuser
```

## Розв' язання аспіра складається з трьох типів проектів:

Вузол App

- **: Окулярифікують ваші послуги**Службові проекти
- **: Ваші справжні послуги (Профілактичні інтерфейси, працівники тощо)**Типові значення служб
- **: Спільне налаштування (уклади, перевірки здоров'я тощо)**Швидкий приклад
- **1.**Створити проект аспірування:
- **2.**Вузол App (MyDistribedApp.AppHost/Program.cs):
- **3.**Використовувати у вашій службі:

Повільні збирання

### Спірні питання мережі

- [Питання щодо прав доступу до об' єму](https://docs.docker.com/)
- [Висновки](https://docs.docker.com/compose/compose-file/)
- [Докер розвинувся від простого інструменту контейнеризації до універсальної платформи для будівництва, відправки та виконання сучасних програм.](https://github.com/dotnet/dotnet-docker)
- [Чи ви:](https://learn.microsoft.com/en-us/dotnet/aspire/)
- [Початок роботи](https://github.com/NVIDIA/nvidia-container-toolkit)
- [: Основи і основні контейнери Master Dockerfile](https://github.com/docker/buildx)

Happy containerizing! 🐳
Будування програм

```yaml
services:
  smtp4dev:
    image: rnwood/smtp4dev
    ports:
      - "3002:80"
      - "2525:25"
    volumes:
      - e:/smtp4dev-data:/smtp4dev
    restart: always

  postgres:
    image: postgres:16-alpine
    container_name: postgres
    ports:
      - "5432:5432"
    env_file:
      - .env
    volumes:
      - e:/data:/var/lib/postgresql/data
    restart: always
```

**: Vererage Docker Compose для багатослужбового оркестрування**

- **Acceatith ML**: Підтримка Haress GPU для обчислювальних робочих завдань
- **Починається багатоплатформа**: Використовувати buildx для сумісності ARM і AMD64
- **Спростивши. NET**: Видання вбудованого контейнера Embrace

Створення мікрослужб[: Explore.NET Aspire для розподілених програм](/dockercomposedevdeps)Екосистема контейнера надає інструменти для кожного сценарію.

### Почніть з простого, засвоюйте його і поступово засвоюйте з ростом ваших потреб.

Додаткові ресурси

```yaml
services:
  # Core application
  mostlylucid:
    image: scottgal/mostlylucid:latest
    restart: always
    env_file: .env
    volumes:
      - ./markdown:/app/markdown
      - ./logs:/app/logs
    networks:
      - app_network
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '1.0'
        reservations:
          memory: 256M

  # Database only
  db:
    image: postgres:16-alpine
    env_file: .env
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - app_network
    deploy:
      resources:
        limits:
          memory: 512M
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 30s
      timeout: 5s
      retries: 3

  # Caddy for HTTPS
  caddy:
    image: caddy:latest
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
    networks:
      - app_network
    deploy:
      resources:
        limits:
          memory: 128M

volumes:
  db_data:
  caddy_data:

networks:
  app_network:
```

**Документація Docker**

- **Довідка з компонування Docker**Зображення. NET
- **Документація. NET Aspire**Набір інструментів для контейнерів NVIDIA`docker logs`Docker buildx
- **ch працює лише те, що вам потрібно:**Чому це працює для розвитку:
- **SMTP4Dev**: Тестова функціональність електронної пошти без справжнього сервера SMTP
- **PostgreSQL**: Порівнює базу даних виробництва

### Загальний слід

: ~200MБ ОЗП проти 2-4GB для всього стеку

**Видите**

```bash
# Just app + database + reverse proxy
docker-compose up -d mostlylucid db caddy
```

**Повноцінний напрямник залежностей розвитку**

```bash
# Add lightweight monitoring
docker-compose up -d mostlylucid db caddy seq
# Use Seq free 10GB/month
```

**для налаштування інструкцій.**

```bash
# Add everything
docker-compose up -d
```

### Налаштоване налаштування виробництва ресурсів

#### Для бюджетної VPS (2- 4GB RAM) визначити важливі служби:

```yaml
services:
  myapp:
    image: postgres:16-alpine     # 50% smaller than postgres:16
    # vs
    image: postgres:16            # Full Debian base
```

**Видалені та альтернативи:**No Prometheus/Grafana

#### : Використовувати зовнішній монітор (Uptime Robot, letterStack full  ще раз)

Без Seq

```yaml
db:
  image: postgres:16-alpine
  # One instance, multiple databases
  # Umami, Mostlylucid, etc. all share this PostgreSQL
```

**: Використовувати журналювання на основі файлів +**, або пам' ять Сек- Хмара

#### Немає " Вартової башти "

```yaml
easynmt:
  deploy:
    resources:
      limits:
        cpus: "2.0"      # Don't let translation consume all CPU
      reservations:
        cpus: "0.5"      # Guarantee minimum
```

: Ручні оновлення за допомогою сповіщень про дії GitHub

#### Немає служби перекладу

: Запустити on- demand у окремому контейнері, який ви запускаєте/ зупиніть вручну[Обмеження ресурсів](/imagesharpwithdocker): Захищати будь- яку окрему службу від споживання всієї пам' яті

```yaml
mostlylucid:
  volumes:
    - /mnt/imagecache:/app/wwwroot/cache  # ImageSharp cache persists across restarts
```

**Стратегія прогресивного зростання**Почати мінімальне, додати служби за потреби:

#### Крок 1: Корінь (512 Мб- 1 ГБ- VPS)

Стадія 2: Додати спостереження (2GB VPS)
|---------|-----------------|---------------------|
Стек 3: Повний стек (4GB+ VPS)
Техніка оптимізації ресурсів
1.

**Використовувати альпійські зображення**Ощадний

#### : Альпійські зображення на 50- 70% менші

2.

```bash
# Create a separate compose file
# translation-compose.yml
services:
  easynmt:
    image: easynmt/api:2.0.2-cpu
    ports:
      - "8888:8888"
    volumes:
      - /mnt/easynmt:/cache/

# Only run when needed
docker-compose -f translation-compose.yml up -d

# Translate your content
# ...

# Shut down when done
docker-compose -f translation-compose.yml down
```

**Спільний внесок до бази даних**Замість однієї бази даних на службу, скористайтеся одним екземпляром PostgreSQL з декількома базами даних:

### Ощадний

: 400MБ ОЗП на додаткову базу даних

```yaml
# Minimal production compose
services:
  mostlylucid:
    image: scottgal/mostlylucid:latest
    restart: always
    env_file: .env
    volumes:
      - /mnt/markdown:/app/markdown
      - /mnt/logs:/app/logs
      - /mnt/imagecache:/app/wwwroot/cache
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    env_file: .env
    volumes:
      - /mnt/postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]
      interval: 30s

  cloudflared:
    image: cloudflare/cloudflared:latest
    command: tunnel run --token ${CLOUDFLARED_TOKEN}
    restart: always

  watchtower:
    image: containrrr/watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      WATCHTOWER_CLEANUP: "true"
      WATCHTOWER_LABEL_ENABLE: "true"
    command: --interval 3600  # Check once per hour, not every 5 minutes
```

**3.**

- Обмежити ЦП для фонових служб
- Це запобігає голодуванню фонових завдань від вашої веб-програми.
- 4.

**Постійні об' єми кешу**

- Як вкрито в
- Розширення різкості зображень за допомогою DockerName`docker logs`, каталоги монтування кешу забороняють непотрібну обробку:
- Чому це важливо
- : Без цього, кожен контейнер перезапускає всі мініатюри/ оброблені зображення.
- 5.

### Використовувати зовнішні служби (вільні служби)

♪Value ♪

** Seq  500MG}Чарівник Seq (10GB/Mail free) **

```bash
# Simple health check script
#!/bin/bash
while true; do
  curl -f http://localhost/healthz || echo "Health check failed!" | mail -s "Alert" you@example.com
  sleep 300
done
```

**♪ Prometheus + Grafana ♪600M] Grafana Хмара (free blustr) ♪**

```bash
# Watch for errors
docker-compose logs -f --tail=100 | grep -i error

# Email on critical errors
docker-compose logs -f | grep -i "critical" | while read line; do
  echo "$line" | mail -s "Critical Error" you@example.com
done
```

** Уммі---- 200 Мб} (оплачено) або сам- вузол десь в іншому місці}**

```bash
# Quick resource check
docker stats --no-stream

# Pretty output
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
```

## Стратегія

: Не перевантажуйте так зв'язку, щоб у вас не було тіста, залиште ключову програму на VPS.

### 6.

Служби " Вмикання" Comment

```bash
# Add Aspire to your solution
dotnet new aspire-apphost -n Mostlylucid.AppHost
cd Mostlylucid.AppHost
```

**Для нечасто використовуваних служб, таких як переклад:**

```csharp
var builder = DistributedApplication.CreateBuilder(args);

// PostgreSQL with persistent data
var postgres = builder.AddPostgres("postgres")
    .WithDataVolume()  // Persistent storage
    .WithPgAdmin();     // Optional: PgAdmin for database management

var mostlylucidDb = postgres.AddDatabase("mostlylucid");
var umamiDb = postgres.AddDatabase("umami");

// Seq for centralized logging
var seq = builder.AddSeq("seq")
    .WithDataVolume();

// Redis for caching (if needed)
var redis = builder.AddRedis("cache")
    .WithDataVolume()
    .WithRedisCommander();  // Optional: Redis Commander UI

// Main blog application
var mostlylucid = builder.AddProject<Projects.Mostlylucid>("web")
    .WithReference(mostlylucidDb)
    .WithReference(seq)
    .WithReference(redis)
    .WithEnvironment("TranslateService__Enabled", "false")  // Disable for dev
    .WithHttpsEndpoint(port: 7240, name: "https");

// Umami analytics
var umami = builder.AddContainer("umami", "ghcr.io/umami-software/umami", "postgresql-latest")
    .WithReference(umamiDb)
    .WithEnvironment("DATABASE_TYPE", "postgresql")
    .WithEnvironment("TRACKER_SCRIPT_NAME", "getinfo")
    .WithEnvironment("API_COLLECT_ENDPOINT", "all")
    .WithHttpEndpoint(port: 3000, name: "http");

// Translation service (CPU version, with resource limits)
var translation = builder.AddContainer("easynmt", "easynmt/api", "2.0.2-cpu")
    .WithDataVolume("/cache")
    .WithHttpEndpoint(port: 8888, name: "http")
    .WithEnvironment("MODEL_FAMILY", "opus-mt");

// Scheduler service (Hangfire background jobs)
var scheduler = builder.AddProject<Projects.Mostlylucid_SchedulerService>("scheduler")
    .WithReference(mostlylucidDb)
    .WithReference(seq);

// Prometheus for metrics
var prometheus = builder.AddContainer("prometheus", "prom/prometheus", "latest")
    .WithDataVolume()
    .WithBindMount("./prometheus.yml", "/etc/prometheus/prometheus.yml")
    .WithHttpEndpoint(port: 9090);

// Grafana for visualization
var grafana = builder.AddContainer("grafana", "grafana/grafana", "latest")
    .WithDataVolume()
    .WithHttpEndpoint(port: 3001)
    .WithEnvironment("GF_SECURITY_ADMIN_PASSWORD", builder.Configuration["Grafana:AdminPassword"] ?? "admin");

builder.Build().Run();
```

### Ощадний

: 1- 2GB RAM, якщо не запущено службу перекладу**Приклад використання бюджету у реальному світі**Ось що працює на Hetzner VPS (2 vCPU, 4GB RAM):

```csharp
// Extensions.cs
public static class Extensions
{
    public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder)
    {
        // OpenTelemetry
        builder.Services.AddOpenTelemetry()
            .WithMetrics(metrics =>
            {
                metrics.AddAspNetCoreInstrumentation()
                    .AddHttpClientInstrumentation()
                    .AddRuntimeInstrumentation();
            })
            .WithTracing(tracing =>
            {
                if (builder.Environment.IsDevelopment())
                {
                    tracing.SetSampler(new AlwaysOnSampler());
                }

                tracing.AddAspNetCoreInstrumentation()
                    .AddHttpClientInstrumentation()
                    .AddEntityFrameworkCoreInstrumentation();
            });

        // Health checks
        builder.Services.AddHealthChecks()
            .AddCheck("self", () => HealthCheckResult.Healthy(), tags: new[] { "live" });

        return builder;
    }

    public static IApplicationBuilder MapDefaultEndpoints(this WebApplication app)
    {
        app.MapHealthChecks("/healthz");
        app.MapHealthChecks("/ready", new HealthCheckOptions
        {
            Predicate = check => check.Tags.Contains("ready")
        });

        return app;
    }
}
```

### Повне використання ресурсів:

```csharp
var builder = WebApplication.CreateBuilder(args);

// Add Aspire service defaults (telemetry, health checks)
builder.AddServiceDefaults();

// Add services
builder.AddNpgsqlDbContext<MostlylucidDbContext>("mostlylucid");
builder.AddRedisClient("cache");

// Existing service registrations...
// builder.Services.AddControllersWithViews();
// etc...

var app = builder.Build();

// Map Aspire default endpoints
app.MapDefaultEndpoints();

// Existing middleware...
app.Run();
```

### RAM: ~800MB (залишає 3. 2 ГБ)

**Диск: ~2GB**

1. **ЦП: <10% бездіяльності, <50% під навантаженням**: `dotnet run --project Mostlylucid.AppHost`Що відрізняється:
2. **Без Prometheus/ Grafana (використовуйте пункт Uptime Robot + Haryflare Analizes)**Без Seq (use
   - + випадкове grep)
   - Без Умамі (використовувати веб- аналітичні аналітики у вигляді Хмара)
   - " Вартова башта " перевіряється щогодини замість кожних 5 хвилин
   - Без служби перекладу (за потреби запустити вручну)
3. **Спостереження за бюджетом**Без "Прометей"/Графана, використовуйте вільні альтернативи:
4. **Спостереження за здоров'ям:**Спостереження за журналами:`.env`Використання Resource:

**Aspire Version: The.NET WY**

Тепер давайте передумаємо, що весь стек використовує NET Aspire.

```bash
# Generate Docker Compose
dotnet run --project Mostlylucid.AppHost -- \
  --publisher compose \
  --output-path ./deploy

# This creates a production-ready docker-compose.yml
cd deploy
docker-compose up -d
```

**Це дає вам всі переваги оркестрування з кращою інтеграцією NET та чудовим досвідом розробника.**Встановлення переважного значення

```yaml
services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres-data:/var/lib/postgresql/data

  mostlylucid-db:
    image: postgres:16
    # Database initialization

  seq:
    image: datalust/seq:latest
    environment:
      ACCEPT_EULA: Y
    volumes:
      - seq-data:/data

  web:
    image: scottgal/mostlylucid:latest
    environment:
      ConnectionStrings__mostlylucid: Host=postgres;Database=mostlylucid;Username=postgres;Password=${POSTGRES_PASSWORD}
      ConnectionStrings__cache: cache:6379
    depends_on:
      - postgres
      - cache
      - seq

  cache:
    image: redis:7-alpine
    volumes:
      - redis-data:/data

  # ... other services
```

### По- перше, створіть вузол ASPre Appy:

usiculcid. AppHost/Program.cs:
|---------|---------------|-------------|
| **Типові значення служби Aspire**Створити
| **Типове значення usiclucid.Service**проект:
| **Оновити здебільшого у форматі program.cs**Користь від постійного наближення
| **Досвід розвитку:** | `docker-compose up` | `dotnet run`Одна команда
| **розпочати все**Панель приладів
| **: Прекрасний інтерфейс на http:// localhost: 15888 showing:** | `docker logs`Всі служби з живим станом
| **Журнали всіх служб в одному місці**Розподілені сліди за службами
| **Метрики та обстеження здоров'я**Знаходження служб
| **: Служби знаходять одне одного автоматично за допомогою імен**Налаштування

### : Creamized in AppHost, no more

**жонглювання**

- Виробництво:
- Створити об' єм, що з' являється за допомогою Aspire:
- Створено docker-compose.yml
- (спрощено):
- Аспірин/ Традиційний комбінатор Docker

**Дзвінок Докконоза. НЕТ Аспірі**

- Налаштування
- ♪
- Знаходження служб
-  =env vars} Автоматично}
- Спостереження

**♪ Sheep your self's core- in (OpenTemepry) ♪**

- Розробка
- + DAboard}
- Зневадження

### Дівчино. Переводчики: minutes_ of_ construction, construction, construction, construction, construction, construction

Журнали

1. **[Територія опуклості](/dockercompose)**Трасування
2. **[ +♪ Автоматично розподіляється}](/dockercomposedevdeps)**Виробництво
3. **[ Використовує YML напряму](/imagesharpwithdocker)**Крива навчання
4. **[Синтаксис yAML} C # Ви вже знаєте, що це?](/dockercompose)**Коли використовувати аспірин проти Docker Compose
5. **Використовувати аспірин, якщо:**Побудова мікрослужби .NET

**Вам потрібне інтегроване зневадження**

- Команді зручно з C#
- Вам потрібно розподілити визначення виходу з-смужки
- Ви вступаєте до Apps контейнера Azure (наукова підтримка)
- Використовувати комбінацію панелі, якщо:
- Служби поліглоти (Node.js, Python, Go тощо)
- Команда надає перевагу інфраструктурі як коду YAML

## Впорядкування для будь- якого сумісного з Docker вузла

### Вам потрібно максимального керування конфігурацією контейнера

1. Просте впровадження однієї служби
2. Використовувати обидва:
3. Аспірувати до локального розробки
4. Створити комбінацію докерів для показу сировини`latest`)
5. Лучшие из обоих миров!
6. Еволюція налаштування панелі перегляду цього блогу`.dockerignore`У цьому блозі показано типовий прогрес:
7. Липень 2024 - Простий початок
8. : Тільки додаток, Хмара, і Вартова Башта

### Серпень 2024.

1. : Додані служби, пов' язані з розвитком
2. Серпень 2024 - виправлення різкості зображень
3. : Розв' язані права доступу до гучності для кешування`.env`Листопад 2024 - Повний стек
4. : Повний зв'язок з Prometheus, Grafana, Seq
5. Сьогодні`depends_on`: Аспірувати параметр для розробки. NET- першого
6. Уроки:
7. Почніть з простого, додайте складність лише за потреби
8. Розділити конфігурації dev і виробничих даних

### Обмеження ресурсів не дозволяють одній службі вбивати інших

1. Монтування об' ємів для кешів зберігають значний час повторного обробки
2. " Вартова башта " вмикає автозавершення нульового часу
3. Нагляд вартий вартості ресурсів у виробництві.
4. Резюме найліпших вправ
5. Найкращі вправи Dockerfile
6. Використовувати багатосценну колекцію
7. Виконати як неroot користувач
8. Настанови з порядку для оптимального кешування

### Використовувати специфічні базові мітки зображень (не)

1. Залучайте до перевірки стану здоров'я
2. Користування
3. для виключення непотрібних файлів
4. Мінімізувати шари (combine команди RUN)`.dockerignore`Для гнучкості використовуйте аргументи збирання
5. Докер комбінує найкращі практики
6. Використовувати іменовані гучності для даних
7. Реалізація перевірки здоров'я
8. Користування

## для секретів (ніколи не вносити)

### Визначення явних мереж

```bash
# Check logs
docker logs container-name

# Common issues:
# 1. Port already in use
docker ps | grep 8080  # Find conflicting container
docker stop conflicting-container

# 2. Missing environment variables
docker inspect container-name | grep Env

# 3. Failed health check
docker inspect container-name | grep Health -A 20
```

### Користування

```bash
# Enable BuildKit for faster builds
export DOCKER_BUILDKIT=1

# Use build cache
docker build --cache-from myapp:latest -t myapp:latest .

# Check what's taking time
docker build --progress=plain -t myapp:latest .
```

### зі здоров'ям

```bash
# Containers can't communicate
# Solution: Ensure they're on the same network
docker network ls
docker network inspect network-name

# DNS not working
# Container names are DNS names within Docker networks
docker exec web ping db  # Should work if both on same network
```

### Встановити правила перезапуску

```bash
# Permission denied on volume
# Solution: Match user IDs
FROM ubuntu
RUN useradd -u 1000 appuser  # Match host user ID
USER appuser
```

## Розділити налаштування dev/prod

Обмеження ресурсів у виробництві

### Вправи безпеки найліпші

**Виконати як неroot користувач**

- Використовувати обрізані/ мінімальні базові зображення[Шукати зображення для вразливості](/dockercompose)Зберігати базові зображення оновленими
- Не включайте таємниці у зображення[Використовувати файлові системи лише для читання, якщо це можливо](/dockercomposedevdeps)Обмежити можливості контейнера
- Використовувати секрети панелі або зовнішні засоби для керування секретами[Найкращі практики швидкодії](/imagesharpwithdocker)Використовувати buildKit для пришвидшення збирання

**Кечування шару вереражу**

- Багатостратегійне збирання, щоб зменшити розмір зображення
- Користування
- щедро
- Альпійські/ покриті зображення для меншого розміру
- Використовувати монтування гучності для розробки

**Налаштувати відповідні обмеження ресурсів**

- Використовуй контроль здоров'я для оркестру.
- Вирішення загальних питань
- Контейнер не запускати
- Повільні збирання
- Спірні питання мережі
- Питання щодо прав доступу до об' єму

**Висновки**

- Докер розвинувся від простого інструменту контейнеризації до універсальної платформи для будівництва, відправки та виконання сучасних програм.
- Цей гід привів вас від фундаментальних до виробничих реалій, з прикладами реального світу з запуску centrucid.com.
- Захоплення ключів
- Для початківців:
- Почати з

**Базове налаштування композитного набору Docker**

- - тільки 3 служби.
- Користування
- Залежності лише для розробки
- для локальної роботи

### Розв' язати спільні проблеми на зразок

права доступу тому

ранній
|-------|----------|-----------|------------|
| **Для само- Хостерів у бюджеті VPS:**Почати мінімальне: App + База даних + Зворотний проксі (~800МБ ОЗП)
| **Використовувати альпійські зображення і обмеження ресурсів**Об' єм пам'яті для вільного тирсу (Хмара Сек), Хмара Ґрафана, ЧасовийРобот) object name (optional)
| **Запустити дорогі служби (переклад, ML) лише на**VPS на $6/місяця може працювати в виробничому блозі, де є більше місця.
| **Для виробництва:**Перевірка здоров'я уможливила оновлення нульового часу з " Вартовою Баштою "
| **Відокремлені мережі забезпечують безпеку (з' єднання зі зворотним з' єднанням)**Змонтовані прив' язки для даних, які вам потрібні для створення резервної копії/ доступу

**Іменовані томи для сховища з керуванням Docker**Обмеження процесора/ пам' яті запобігають голодові ресурсів

### Тунель " Хмара " усуває потребу у публічних IP- адресах

Для розробників. NET:

- **Вбудований контейнер, що публікується у. NET 9 вилучає Dockerfiles для простих програм**Колективні зображення Ubuntu забезпечують мінімальну кількість атакових поверхонь.[. NET Aspire пропонує локальний досвід локального розвитку](/dockercompose)
- **Аспир може генерувати Докер Композит для виробництва**Інтеграція OpenTelemeterry є вільною з Aspire
- **Для випадків розширеного використання:**Контейнери GPU вмикають роботу ML/AI з 10-15x speedup
- **Багатоархітектура підтримує ARM64 і AMD64 з одного джерела**Дії GitHub вводять багатоплатформові збирання[Колекція шарів значно пришвидшує повторне збирання](https://github.com/scottgal/mostlylucid-nmt)
- **Подорож**Типовий прогрес подій у цьому блозі:

### ДІЗ_Е-Е-Е-У-Е-У-У-У-У-У-У-У-У-У-У-У-У-У-У!

**Крок No1**

- [(липень 2024).](https://docs.docker.com/)
- [Крок No2](https://docs.docker.com/compose/compose-file/)
- [(Ауг 2024) + дев'ятдесят шість) 500 МВ ДІТЕЙ](https://github.com/dotnet/dotnet-docker)
- [Крок No3](https://learn.microsoft.com/en-us/dotnet/aspire/)
- [(Ауг 2024) + Том йде] 500МВ ЗнеохочуюЧАННЯ}](https://github.com/NVIDIA/nvidia-container-toolkit)
- [Крок No4](https://github.com/docker/buildx)

**(Nov 2024)}**

1. [Крок No5](/dockercompose)(0000) + Аспірин } Змінна} МІСЦЕ
2. [Шаблон](/dockercomposedevdeps): Почніть з простого, розв'яжіть проблеми з самого початку, додайте до них ще більше складності лише в разі потреби.
3. [Що далі?](/imagesharpwithdocker)Залежно від вашого шляху:
4. Навчальний гуртожиток

**: Почати з**

- [Обчислені основи блоку](https://github.com/scottgal/mostlylucid-nmt)Самоохайність
- [: Спробуйте встановити мінімальне VPS з цієї статті](https://github.com/scottgal/mostlylucidweb)Створення мікрослужб

: Explore.NET Aspire

Happy containerizing! 🐳