Dock Dree Dive: From Bases to Advanced. NET Contentization (Українська (Ukrainian))

Dock Dree Dive: From Bases to Advanced. NET Contentization

Sunday, 09 November 2025

//

37 minute read

Вступ

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

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

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

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

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

. NET Aspire

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

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

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

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

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

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

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

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

# The container solution
"Ship your machine!" 

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

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

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

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

# 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

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

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

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

# 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. Оптимізація шару: Копіювати файли залежностей перед початковим кодом для кращого кешування

Безпека

# 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**Кеш Redisdocker-compose.yml**Сек для ведення журналу

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Мітки " Вартової башти "

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

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

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 для уникнення конфліктів з іншими екземплярами

# .env file (never commit to git!)
DB_PASSWORD=super_secret_password
SMTP_PASSWORD=another_secret
services:
  web:
    environment:
      - DB_PASSWORD=${DB_PASSWORD}  # From .env file
      - STATIC_VALUE=production     # Hardcoded
    env_file:
      - .env                        # Load entire file

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

: Секрети в

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).
  • Змонтовані об' єкти/ Прив' язки

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

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge

services:
  web:
    networks:
      - frontend
      - backend

  db:
    networks:
      - backend  # Not exposed to frontend

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

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

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

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

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

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

# 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

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

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

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

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

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

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

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

services:
  web:
    image: registry.example.com/myapp:${VERSION}
    restart: always
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '2'
          memory: 2G
# Development (base + override)
docker-compose up -d

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

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

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

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

# 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

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

# 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

# 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):

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(продукція):

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

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

umcid-nmt

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:

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

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

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Підтримка зворотного стану

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

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

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

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

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

і

# 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

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

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

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

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

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

# Then use in compose
services:
  web:
    image: myapp:latest  # Already built for multiple architectures

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

#!/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 для вбудованих пристроїв.

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

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: Попереднє збирання зображень

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

<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 для збирання багатоархічних структур:

dotnet publish -p:PublishProfile=DefaultContainer

Цей процес:

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

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

<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

Безпека

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"]

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

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

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

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

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

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

: ~110MБ

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

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

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

<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. Знаходження служб: Служби знаходять одне одного автоматично

Телеметрія

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

dotnet new aspire-starter -n MyDistributedApp
cd MyDistributedApp

Компоненти

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 тощо)

// 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

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

# 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

# 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

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

# 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.**Використовувати у вашій службі:

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

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

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

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 для розподілених програмЕкосистема контейнера надає інструменти для кожного сценарію.

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

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

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Набір інструментів для контейнерів NVIDIAdocker logsDocker buildx
  • **ch працює лише те, що вам потрібно:**Чому це працює для розвитку:
  • SMTP4Dev: Тестова функціональність електронної пошти без справжнього сервера SMTP
  • PostgreSQL: Порівнює базу даних виробництва

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

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

Видите

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

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

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

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

# Add everything
docker-compose up -d

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

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

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

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

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

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

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

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

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

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

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% менші

# 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Б ОЗП на додаткову базу даних

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

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

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

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

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

♪Value ♪

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

# 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) ♪

# 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 Мб} (оплачено) або сам- вузол десь в іншому місці}**

# Quick resource check
docker stats --no-stream

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

Стратегія

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

6.

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

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

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

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):

// 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;
    }
}

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

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.

# 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 та чудовим досвідом розробника.**Встановлення переважного значення

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. **Територія опуклості**Трасування
  2. ** +♪ Автоматично розподіляється}**Виробництво
  3. ** Використовує YML напряму**Крива навчання
  4. **Синтаксис yAML} C # Ви вже знаєте, що це?**Коли використовувати аспірин проти 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. Користування

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

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

# 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

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

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

зі здоров'ям

# 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

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

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

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

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

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

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

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

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

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

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

Висновки

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

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

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

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

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

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

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

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

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

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

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

Крок No1

(Nov 2024)}

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

: Почати з

: Explore.NET Aspire

Happy containerizing! 🐳

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.