Docker Development Deep Sukellus: Perusasioista edistyneeseen .NET Containerization (Suomi (Finnish))

Docker Development Deep Sukellus: Perusasioista edistyneeseen .NET Containerization

Sunday, 09 November 2025

//

35 minute read

Johdanto

Docker on muuttanut perusteellisesti sitä, miten rakennamme, lähetämme ja pyöritämme sovelluksia.

Se, mikä alkoi yksinkertaisena konttityökaluna, on kehittynyt täydelliseksi ekosysteemiksi modernille sovelluskehitykselle ja käyttöönotolle.

  1. **Tämä on neljäs ja kattavin artikkeli Docker-sarjassani .NET-kehittäjille.**Jos olet uusi Dockerissa, kannattaa aloittaa:
  2. Dockerin sävellys- Aloittaminen monipakkausten perussarjoilla (heinäkuu 2024)
  3. Docker Compose -levyn kehitysriippuvuus- Paikallisten dev-ympäristöjen perustaminen (elokuu 2024)

Kuvanvahvistaja Dockerilla

  • **- Määrällisten lupa-asioiden selvittäminen (elokuu 2024)**Tässä syväsukelluksessa rakennamme noille perustuksille tutkiaksemme:
  • Tuotantovalmis Docker Composite: Varsinainen pino pyörittää tätä blogia
  • Omatoimisuus rajatuilla resursseilla: Käytännölliset optimointitekniikat VPS-budjetin käyttöönottoa varten
  • GPU-tuki: ML-kuormat konteissa
  • Moniarkkitehtuurin rakennelmat: ARM64:n ja AMD64:n tukeminen
  • .NET 9 kontin ominaisuudet: Sisäänrakennettu konttijulkaisu ilman Dockerfilejä

.NET-pyrkimys

: Nykyaikainen .net-lähestymistapa konttiorkesterissa

HUOMAUTUS: Tämä on osa kokeilujani tekoälyllä / tapa käyttää 1000 dollaria Claude Code Web -pisteitä.

Olen syöttänyt tälle BUNCH-lehden, ymmärrykseni ja kysymykseni, jotka minun oli tuotettava.

Se on hauskaa ja täyttää aukon, jota en ole nähnyt missään muualla.

Olitpa sitten ottamassa käyttöön yksinkertaisen verkkosovelluksen tai suunnittelemassa monimutkaista mikropalveluarkkitehtuuria GPU-kiihdytetyillä koneoppimismalleilla, tämä opas vie sinut Dockerin alkeista tuotantovalmiisiin sovelluksiin, joissa on todellisia esimerkkejä enimmäkseen lucid.comin pyörittämisestä.

  • Docker Fundamentals: Understanding ContainersMikä Docker oikeasti on?
  • **Sen ytimessä Docker on konttialusta, joka pakkaa sovelluksesi ja kaikki sen riippuvuudet standardoituun yksikköön, jota kutsutaan kontiksi.**Toisin kuin virtuaaliset koneet, jotka virtuaalisoivat kokonaisia käyttöjärjestelmiä, kontit jakavat isäntäjärjestelmän ytimen säilyttäen samalla eristetyt käyttötilat.

Ajattele asiaa näin:

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

# The container solution
"Ship your machine!" 

Virtuaalikoneet

  1. : Jokaisella VM:llä on täysi käyttöjärjestelmäpino (Linux-ydin, järjestelmäkirjastot jne.) - raskas ja hidas käynnistysKontit
  2. : Jaa isäntäydin, paketti vain sovelluskoodi ja riippuvuudet - kevyt ja nopeaMiksi konteilla on merkitystä kehittäjille
  3. **Kontit ratkaisevat useita kriittisiä ongelmia:**Ympäristön yhtenäisyys
  4. : Kehitys-, testaus- ja tuotantoympäristöt ovat identtisetRiippuvuuseristys
  5. Ei enää "DLL Hell" tai ristiriitaisia kirjastoversioitaToistuvia rakennelmia

: Sama tulo = sama lähtö, joka kerta

Nopea käyttöönotto

# 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

: Aloita kontit sekunneissa, ei minuuteissaResurssitehokkuus

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

: Suorita kymmeniä kontteja yhdellä kerralla

  • Olennaiset docker-käsitteetKuvat vs. kontit
  • KuvatNe ovat muuttumattomia, kerroksellisia tiedostojärjestelmiä.
  • **Jokainen Dockerfile-ohje luo uuden kerroksen:**Tämä kerros on voimakas:

Välilyöntejä

: Muuttumattomia kerroksia käytetään uudelleen, mikä nopeuttaa rakentamista

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

Jakaminen

  1. : Useilla kuvilla voi jakaa pohjakerroksiaTehokkuus
  2. : Vain vaihdetut kerrokset on ladattava/ladattavaDockerfile parhaat käytännöt
  3. **Tässä on tuotantovalmis .NET Dockerfile, jossa on kommentteja:**Keskeisiä periaatteita havainnollistettiin:
  4. Monivaiheiset rakenteet: Erilliset rakennus- ja julkaisuvaiheet pienentävät lopullista kuvakokoa dramaattisesti
  5. Tason optimointi: Kopioi riippuvuustiedostot ennen lähdekoodia parempaan välimuistiin

Turvallisuus

# 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

: Juokse ei-juurellisena käyttäjänä

Terveystarkastukset

: Konttiorkesterit voivat seurata sovellusterveyttä

Erityinen ympäristö

  • : Aseta tuotannon oletukset
  • Rakentaminen ja juokseminen
  • Dockerin sävellys: Multi-Container Orchestration
  • Docker Compose -ohjelmiston avulla voit määritellä ja pyörittää monipakkaussovelluksia.
  • Sen sijaan, että hallinnoisit kontteja yksilöllisesti, kuvaat koko hakemuspinon YAML-tiedostossa.

Miksi dokkari säveltää?docker runHarkitse tyypillistä .NET-verkkosovellusta:

ASP.NET Core -verkkosovellus

PostgreSQL-tietokanta**Uusi välimuistidocker-compose.yml**Seq puunkorjuuta varten

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

Ehkä taustatyöntekijän palvelu

  1. Yksittäin hallinnoiminenkäskyistä tulee kankeita.app_networkDocker Compose ratkaisee tämän.
  2. Complete Real-World Example: Production Blog PlatformTässä on/mnt/*Todellinen tuotanto
  3. **joka pyörittää juuri tätä sivustoa (useimmitenlucid.com):**Avaintuotantomallit:
  4. Yhtenäinen verkko: Kaikki palvelut
  5. yksinkertaisuuden puolestaRinnakkaiskiinnikkeet
  6. : Hosting-polut () Pysyvien tietojen varmuuskopiointi/käyttö
  7. Nimetyt volyymit: Docker-hallittu tietojen tallennus, johon ei tarvita suoraa pääsyä.envVartiotornin tarroja

: Vain päivityspalvelut, jotka on nimenomaisesti merkitty automaattiseksi päivitykseksi

Resurssirajat

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

: Käännöspalveluun liittyvät prosessorirajoitukset estävät resurssien nälänhädäncondition: service_healthyUlkoinen satamakartoitus

: PostgreSQL 5266:ssa 5432:n sijaan, jotta vältyttäisiin ristiriidoilta muiden tapausten kanssa

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

Ympäristötiedostot

: Salaisuudet in

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

Tiedosto (ei koskaan sitoutunut gittiin):

  • Dockerin pääpiirteet
  • Palvelun riippuvuus
  • Docker Composite orkestroi startup-tilauksen.
  • Erytropoietiini

edellyttää, että tietokannan terveystarkastus läpäisee ennen verkkosovelluksen käynnistämistä.:

  • Ympäristömuuttujat ja -salaisuudet
  • Tuotantosalaisuuksiin käytetään Docker Secretsiä tai ulkopuolisia salaisia johtajia (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault).
  • Nimetyt tilavuudet vs. kiinnikkeet

Nimetyt määrät

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

services:
  web:
    networks:
      - frontend
      - backend

  db:
    networks:
      - backend  # Not exposed to frontend

Dockerin hallinnoima

Sinnikkäät tiedot konteista käynnistyvät uudelleen

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

Voidaan varmuuskopioida/palauttaa Docker-komennuksilla

  • Liitännät yhteensopivat
  • Rinnakkaiskiinnikkeet
  • Suorakartoitus isäntätiedostojärjestelmään

Hyödyllistä kehitykselle (elävän koodin uudelleenlataus)

# 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

Asetukset-tiedostot, lokit, lataukset

Verkottuminen

**Verkot tarjoavat eristyneisyyttä.**Täällä tietokanta on saatavilla vain taustapalveluille, ei suoraan.

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

TerveystarkastuksetTerveystarkastusten perusteella Docker voi

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

**Määrittele, onko kontti todella valmis (ei vain käynnistynyt)**Aloita epäterveelliset kontit uudelleen

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

Anna status orkesterille (Kubernetes, Docker Swarm)

Yleiset dokkarin komennot

Kehitys vs Production Composite -tiedostot

# 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

Erilliset huolet useista koostetiedostoista:

# 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

(pohja):

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.override.yml

(kehittäminen – automaattisesti sulautettuna):docker-compose.prod.yml(tuotanto):

GPU-tuki Dockerissa: ML-työlatausten nopeuttaminen

  • **Koneoppiminen, tieteellinen tietojenkäsittely ja videonkäsittelysovellukset vaativat usein GPU-kiihdytystä.**Docker tukee NVIDIA GPU:ta NVIDIA Container Toolkitin kautta.
  • NVIDIA-konttipakkausten asennusGPU-kiihdytetyn Python/PyTorch-sovelluksen Docker-tiedosto
  • Käytössä olevat GPU-kontitGPU Dockerin kokoonpanossa
  • Real-World Example: Käännöspalvelu GPU:lla ja CPU:llaTässä on todellinen tuotantoesimerkki

enimmäkseen lusid-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:

, neurokonekäännöspalvelu, jonka rakensin tähän blogiin automaattikäännöksen.

Hanke osoittaa:

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- ja CPU-variantit

  • scottgal/mostlylucid-nmt:gpu- Sama koodipohja, eri pohjakuvat
  • scottgal/mostlylucid-nmt:cpuMoniarkkitehtuurin rakennelmat
  • scottgal/mostlylucid-nmt:gpu-min- Tukee AMD64:ää ja ARM64:ää
  • scottgal/mostlylucid-nmt:cpu-minOptimoidut Docker-kuvat

- Täydet ja minimaaliset vaihtoehdot

  • Tuotantovalmiit- Terveystarkastukset, äänenvoimakkuuden pysyvyys, asianmukainen puunkorjuu
  • GPU-kiihdytetty käännöspalveluCPU-Vain vaihtoehto
  • **Ympäristöissä, joissa ei ole GPU:ita, sama palvelu toimii suorittimella:**Saatavilla olevat kuvaversiot:
  • - CUDA 12.6, jolla on PyTorch GPU -tuki (~5GB)- Vain prosessori, pienempi jalanjälki (~2.5GB)
  • - Minimaalinen GPU-rakenne, ei esiladattuja malleja (~4GB): /health- Minimaalinen prosessorirakenne (~1,5GB)/readyTärkeimmät ominaisuudet:
  • GPU-kiihdytys: 10-15x nopeampaa käännöstä CUDA:lla

Mallin automaattinen lataaminen: Lataukset käännösmallit tilauksestaVaratuki

: Tries Opus-MT → mBART50 → M2M100 mahdollisimman kattavalle kielelle

Volyymin pysyvyys

: Cache-mallit kontissa käynnistyvät uudelleen

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

Terveyden loppupäätteitä

sekä

# 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

orkesterille

Moniarkkitehtuuri

# 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 ja ARM64 (Apple Silicon, Vadelma 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 \
  .

Katso

GitHubilla täysi projekti

Dockerfile-esimerkeille rakenna skriptejä ja API-dokumentaatioita.

# 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

Moniarkkitehtuuri rakentaa Docker Buildexilla

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

Nykyajan sovelluksia on käytettävä useissa eri sarjoissa: x86_64 (AMD64) palvelimille, ARM64 Vadelma Piille ja Apple Silicon Maceille, joskus jopa ARM32 sulautetuille laitteille.

Miksi moniarkkitehtisuus on tärkeää

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

Asetetaan buildxia

  • Docker Buildex on mukana Docker Desktopissa.
  • Linuxille:
  • Multi-Architecture Dockerfile
  • Useimmat Dockerfiles-tiedostot toimivat ilman muutoksia, mutta tässä muutamia vinkkejä:
  • Rakentaminen useille alustoille

Moniarkkitehtuuri Docker Compose -levyllä

Valitettavasti Docker Composite ei suoraan tue bundexia.

Työskentelyt:

Vaihtoehto 1: Esirakentamiskuvat

# 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

Vaihtoehto 2: Koosta skripti

Reaalimaailman esimerkki: CI/CD-putkisto.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>

Moniarkkitehtuurin GitHub-toiminnon työnkulku rakentuu:

dotnet publish -p:PublishProfile=DefaultContainer

Tämä työnkulku:

  1. Liittää pää- tai versiotallenteisiinAsettaa QEMU:n cross-platform-emulointiin
  2. Rakentaa AMD64:lle ja ARM64:lleLuo tunnisteet automaattisesti (sivunimi, semanttiset versiot, SHA)
  3. Käyttää rekisteriä välimuistina nopeammille rakennuksille.NET 9 Konttien parannustyöt
  4. **.NET 9 tuo konttitukeen merkittäviä parannuksia, mikä helpottaa .net-sovellusten pakkaamista ilman edes Dockerfileä.**Sisäänrakennettu konttikustantamo
  5. **.NET 9 -verkolla voit julkaista suljetun hakemuksen suoraan:**Kontin ominaisuuksien määrittely

Lisää ruutuusi

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

Julkaistaan sitten:

  • Sisäänrakennetun konttituen edutDocker-tiedostoa ei tarvita
  • : Vähentää monimutkaisuuttaOptimoidut kuvat
  • : Microsoft virittää kuvat suoritukseenJohdonmukainen

: Vakiokuvat kaikissa .net-sovelluksissa

Turvallisuus

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

: Automatisoitu pohjakuvapäivitys

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

Pienempiä kuvia

: Trimmingin ja AOT:n kokoelmatuki

Pienten kuvien karsinta ja AOT

  • Tulokset:
  • Standardi
  • ~220MB
  • joissa on trimmaus

~110MB

  • AOT:n kanssa
  • ~12MB yksinkertaisiin sovelluksiin!
  • Vertailu: Dockerfile vs sisäänrakennettu
  • Perinteinen Dockerfile-lähestymistapa:

Sisäänrakennettu konttilähestymistapa:

Molemmat tuottavat samanlaisia kuvia, mutta sisäänrakennettu lähestymistapa on yksinkertaisempi ja huollettavampi.

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

Milloin Dockerfileä käytetään vastaan sisäänrakennettu

  • **Käytä Dockerfileä, kun:**Kuvaa pitää hallita täysin.
  • Asennusjärjestelmän riippuvuudetMonivaiheiset monimutkaiset rakennelmat
  • Peruskuvat, jotka eivät ole normaalejaKäytä sisäänrakennettua, kun:

Standardi .NET-verkko/konsolisovellukset

  • Haluat yksinkertaisuutta
  • Microsoftin optimointien velkaantuminen

Nopea prototyypitys

Ripoteltuja Ubuntu-kuvia

.NET 9 tukee "piristettyjä" Ubuntu-kuvia - ultraminimaaliset pohjakuvat:

Hyödyt:

Pieni

  1. : ~50 % pienempi kuin tavalliset kuvatTurvallinen
  2. **: Minimaalinen hyökkäyspinta (ei pakettihallintaa, shell)**Nopea
  3. : Nopeammat vedot ja lähdötVastoinkäymiset:
  4. **Ei simpukkaa (kovempaa vianetsintään)**Rajalliset järjestelmähyödykkeet
  5. **Täydellinen tuotantoon, jossa turvallisuus ja koko ovat tärkeimpiä.**Johdatus .NET-hakuun

.NET Aspire on mielipiteellinen, pilvinen pino jaettujen sovellusten rakentamiseen.

Ajattele, että Docker Composite on steroideja, jotka on erityisesti suunniteltu .NET-mikropalveluihin.

  1. **Mitä tavoitteleminen on?**Tavoitteena on:
  2. Orkesteri: Suorita ja yhdistä useita palveluja paikallisesti
  3. Palvelun löytäminen: Palvelut löytävät toisensa automaattisesti

Telemetria

: Sisäänrakennettu puunkorjuu, metrit, jäljitys

dotnet new aspire-starter -n MyDistributedApp
cd MyDistributedApp

Komponentit

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();

Esiasetetut integraatiot (Redis, PostgreSQL, RabbitMQ jne.)

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

Käyttöönotto

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

: Luo Kubernetes/Docker Composite -luettelo

# 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

Pyri arkkitehtuuriin

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

Aspire-ratkaisussa on kolme projektityyppiä:

Sovelluspalvelin

  • : Järjestää palveluksiasiPalveluhankkeet
  • **: Varsinaiset palvelusi (Web-rajapinnat, työntekijät jne.)**Palvelun oletukset
  • **: Yhteinen kokoonpano (loggaus, terveystarkastukset jne.)**Pikainen esimerkki
  • 1 TäysosumaLuo Aspire-projekti:
  • **2.**App Host (MyDistributedApp.AppHost/Program.cs):
  • **3.**Käyttö palveluksessasi:

Hidas rakentaa

Verkkokysymyksiä

Happy containerizing! 🐳 Rakennussovellukset

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

: Leverage Docker Compose monen palvelun orkestrointiin

  • Nopeutetaan ML:ää: Valjasta GPU:n tuki laskentaintensiivisille työtahdille
  • Käynnissä oleva moniplanaatti: Käytä buildxia ARM- ja AMD64-yhteensopivuuteen
  • Yksinkertaistetaan .NET-verkkoa: Syleile sisäänrakennettuja kontteja

Rakennusmikropalvelut: Tutki .NET Havittele jaettuja sovelluksiaKonttiekosysteemi tarjoaa työkaluja jokaiseen skenaarioon.

Aloita yksinkertaisesta, iteroivasta ja omaksu edistyneitä ominaisuuksia vähitellen tarpeidesi kasvaessa.

Lisäresurssit

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:

Dockerin dokumentointi

  • Dockerin sävellysreferenssi.NET Container Images
  • .NET:n tavoitedokumentaatioNVIDIA Container Toolkitdocker logsDocker Buildex
  • **ch pyörittää vain sitä, mitä tarvitsee:**Miksi tämä toimii kehityksen hyväksi:
  • SMTP4Dev: Testaa sähköpostin toimivuus ilman todellista SMTP-palvelinta
  • PostgreSQL: Vastaa tuotantotietokantaa

Kokonaisjalanjälki

: ~200MB RAM vs 2-4GB täyteen pinoon

Katso

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

täyden kehityksen riippuvuusoppaat

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

asennusohjeita varten.

# Add everything
docker-compose up -d

Resurssien hillitsemä tuotantoasetelma

Budjetti VPS:lle (2-4GB RAM) priorisoi olennaiset palvelut:

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

**Mitä on poistettu ja vaihtoehtoja:**Ei Prometheus/Grafanaa

: Käytä ulkoista seurantaa (UptimeRobot, BetterStack Free Tier)

Ei Seqia

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

: Käytä tiedostopohjaista kirjausta +, tai Seq Cloud Free -tason

Ei Vartiotornia

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

: Manuaalinen päivitys GitHub-toimintoilmoituksilla

Ei käännöspalvelua

: Suorita tilauksesta erillisessä astiassa, jonka käynnistät/pysäytät manuaalisestiResurssirajat: Estä yhtäkään palvelua kuluttamasta kaikkea muistia

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

Progressiivinen tehostamisstrategiaAloita minimaalisesti, lisää palveluita tarpeen mukaan:

Vaihe 1: Core (512MB-1GB VPS)

Vaihe 2: Lisää havaintokyky (2GB VPS) |---------|-----------------|---------------------| Vaihe 3: Full Stack (4GB+ VPS) Resurssien optimointitekniikat 1 Täysosuma

Käytä alppikuviaSäästöt

: Alppikuvat ovat 50-70 prosenttia pienempiä

# 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

Jaettu tietokantaSen sijaan, että käytössä olisi yksi tietokanta per palvelu, käytä yhtä PostgreSQL-instanssia, jossa on useita tietokantoja:

Säästöt

: 400MB RAM/lisää tietokantaa kokoat

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

  • Rajaussuoritin taustapalveluille
  • Tämä estää taustatyöpaikkoja näkemästä nälkää verkkosovelluksessasi.
  • Nelonen

Jatkuvat välimuistin volyymit

  • Kuten on esitetty
  • Kuvanvahvistaja Dockerilladocker logsAsentavat kätköhakemistot estävät tarpeettoman uudelleenkäsittelyn:
  • Miksi sillä on väliä?
  • : Ilman tätä jokainen kontti käynnistää uudelleen kaikki kuvakynnet/jalostetut kuvat.

Käytä ulkoisia palveluja (free Tiers)

Palvelu Omatoiminen RAM Ulkoinen vaihtoehto

Seq ~500MB Seq Cloud (10GB/kk ilmaiseksi)

# Simple health check script
#!/bin/bash
while true; do
  curl -f http://localhost/healthz || echo "Health check failed!" | mail -s "Alert" [email protected]
  sleep 300
done

Prometheus + Grafana ~600MB Grafana Cloud (vapaa taso)

# 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" [email protected]
done

Umami ~200MB Todennäköinen (palkallinen) tai itsekeskeinen muualla

# Quick resource check
docker stats --no-stream

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

Strategia

: Poista havainnointi vapaalle tasolle, pidä ydinsovellus VPS:ssä.

6.

On-demand-palvelut

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

Harvoin käytetyt palvelut, kuten kääntäminen:

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();

Säästöt

: 1-2GB RAM kun käännöspalvelu ei toimiReaalimaailman budjetin isäntäesimerkkiTässä on 6 dollarin kuukausipalkkainen 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;
    }
}

Resurssien kokonaiskäyttö:

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 (jättää 3,2GB ilmaiseksi)

Levy: ~2GB

  1. Suoritin: <10 % joutokäynnillä, <50 % kuormitettuna: dotnet run --project Mostlylucid.AppHostMikä on toisin:
  2. **Ei Prometheus/Grafanaa (käytä UptimeRobottia + Cloudflare Analyticsia)**Ei Seqiä (käytä
      • satunnaiset grepit)
    • Ei Umamia (käytä Cloudflare Web Analyticsia – ilmaiseksi)
    • Vartiotornin tarkistus tunnin välein viiden minuutin välein
    • Ei käännöspalvelua (käytä tarvittaessa manuaalisesti)
  3. Talousarvion seurantaIlman Prometheusta/Grafanaa käytä seuraavia ilmaisia vaihtoehtoja:
  4. **Terveyden seuranta:**Lokin seuranta:.envResurssien käyttö:

Aspire-versio: The .NET Way

Nyt reimagoidaan koko pino uudelleen .NET Aspire -palvelun avulla.

# 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

**Tämä antaa sinulle kaikki orkestrointiedut paremmalla .NET-integraatiolla ja hämmästyttävällä kehittäjäkokemuksella.**Enimmäkseen havittelemista

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

Luo ensin Aspire-sovelluksen isäntä:

Enimmäkseen lucid.AppHost/Program.cs: |---------|---------------|-------------| | Havittele palvelun oletuksiaLuo | Enimmäkseen lucid.ServiceDefaultsprojekti: | Päivitä Enimmäkseenlucid/Program.csPyrinnän edut | Kehityskokemus: | docker-compose up | dotnet runYksi komento | aloittaa kaikenKojelauta | : Kaunis käyttöliittymä osoitteessa http://localhost:1588, josta käy ilmi: | docker logsKaikki palvelut, joilla on live-status | Lokit kaikista palveluista samassa paikassaHajautetut jäljet eri palveluissa | Lääkintä ja terveystarkastuksetPalvelun löytäminen | : Palvelut löytävät toisensa automaattisesti nimien kauttaAsetukset

: Keskitetty AppHostiin, ei enää

jongleeraus

  • Tuotannon käyttöönotto:
  • Luo käyttöönoton manifestit Asposta:
  • Luotu docker-compose.yml
  • (yksinkertaistettu):
  • Pyri vastaan perinteinen docker-sävellys

Aihe: Dockerin sävellys .NET Tähtää

  • Asetukset
  • Manuaalinen YAML C#-koodi ja IntelliSense-koodi
  • Palvelun löytäminen
  • Manual env vars Automatic
  • Havainnointikelpoisuus

Tuo oma sisäänrakennettu (OpenTelemetria)

  • Kehitys
    • Dashboard
  • Vianetsintä

Liitä konttiin F5 Visual Studiossa

Lokit

  1. **Keskitetty kojelauta**Jäljitys
  2. **Asetukset manuaalisesti Automaattinen hajautettu jäljitys**Tuotanto
  3. **Käytä YAML:ää suoraan Luo manifestit**Opettele kurveja
  4. **YAML syntaksi C# tiedät jo**Milloin käyttää aspiraatiota docker-sävellystä vastaan
  5. **Käytä aspiraatiota, kun:**Rakentaminen .NET-mikropalvelut

Haluatko integroitua vianetsintää

  • Joukkue viihtyy C#:n kanssa
  • Tarvitset jaetun jäljityksen laatikon ulkopuolelta
  • Olet ottamassa käyttöön Azure Container Apps (natiivituki)
  • Käytä Docker Composite -valmistetta, kun:
  • Polyglot-palvelut (Node.js, Python, Go jne.)
  • Joukkue suosii infrastruktuuria koodina YAML

Deploying any Docker-yhteensopiva isäntä

Konttien kokoonpanoa on ohjattava maksimaalisesti

  1. Yksinkertaiset yhden palvelun käyttöönotot
  2. Käytä molempia:
  3. Paikallisen kehityksen tavoittelu
  4. Luo Docker Composite tuotannon käyttöönottoa vartenlatest)
  5. Molemmista maailmoista parhaat!
  6. Tämän blogin docker-asetelman kehitys.dockerignoreTämän blogin Docker-matka kertoo tyypillisestä etenemisestä:
  7. Heinäkuu 2024 - yksinkertainen alku
  8. : Vain sovellus, Cloudflared ja Vartiotorni

Elokuu 2024 - Haitat

  1. : Lisättäviä vain kehittämispalveluja
  2. Elokuu 2024 - ImageSharp Fix
  3. : ratkaistuja äänenvoimakkuusoikeuksia välimuistiin.envMarraskuu 2024 - Full Stack
  4. : Täydellinen havaintokyky Prometheuksella, Grafanalla, Seqillä
  5. Tänäändepends_on: Havittele vaihtoehtoa . NET-ensikehitykselle
  6. Havaintoja ja haasteita
  7. Aloita yksinkertainen, lisää monimutkaisuutta vain tarvittaessa
  8. Erilliset dev- ja tuotantokokoonpanot

Resurssirajat estävät yhden palvelun tappamisen

  1. Välimuistien äänenvoimakkuuden kiinnitykset säästävät merkittävää uudelleenkäsittelyaikaa
  2. Vartiotorni mahdollistaa nolla- pois päältä -ajan automaattisen päivityksen
  3. Havainnointi on tuotannon resurssikustannusten arvoista
  4. Parhaiden käytäntöjen yhteenveto
  5. Dockerfile parhaat käytännöt
  6. Käytä monivaiheisia rakennelmia
  7. Suorita non-root-käyttäjänä
  8. Tilausohjeet optimaaliseen välilyönteihin

Käytä erityisiä pohjakuvatunnisteita (ei

  1. Sisällytä terveystarkastukset
  2. Käyttö
  3. tarpeettomien tiedostojen poissulkeminen
  4. Minimoi kerrokset (komenna RUN-komentoja).dockerignoreKäytä joustavuuteen rakentavia argumentteja
  5. Docker sävelsi parhaat käytännöt
  6. Käytä dataan nimettyjä määriä
  7. Toteuta terveystarkastukset
  8. Käyttö

salaisuudet (ei koskaan sitoudu)

Määrittele tarkat verkostot

# 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

Käyttö

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

joilla on terveysongelmia

# 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

Aseta uudelleenkäynnistyksen toimintatavat

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

Erilliset dev/prod-konfiguraatiot

Resurssirajat tuotannossa

Turvallisuuden parhaat käytännöt

Suorita non-root-käyttäjänä

Vivutuskerros välimuistina

  • Monivaiheiset rakenteet pienentävät kuvan kokoa
  • Käyttö
  • avokätisesti
  • Pienemmän kokoisia alppi- ja hilsekuvia
  • Käytä äänenvoimakkuuden liittimiä kehittämiseen

Määrittele asianmukaiset resurssirajat

  • Käytä terveystarkastuksia orkestrointiin
  • Yhteisiä ongelmia
  • Kontti ei käynnisty
  • Hidas rakentaa
  • Verkkokysymyksiä
  • Volume licence issues

Päätelmät

  • Docker on kehittynyt yksinkertaisesta konttityökalusta kokonaisvaltaiseksi alustaksi nykyaikaisten sovellusten rakentamiseen, toimitukseen ja käyttöön.
  • Tämä opas on vienyt sinut perusasioista tuotantovalmiisiin, tosimaailman esimerkein lähinnälucid.comin pyörittämisestä.
  • Tärkeimmät takeawayt
  • Aloittelijoille:
  • Aloita

perus Docker Composite setup

    • vain kolme palvelua
  • Käyttö
  • kehitys- ja riippuvuussuhteet
  • paikalliselle työlle

Ratkaise yhteisiä asioita, kuten

äänenvoimakkuusoikeudet

varhain |-------|----------|-----------|------------| | **Budjetti VPS:n omatoimiset kannattajat:**Aloita minimaalisesti: Sovellus + Tietokanta + Käänteinen Proxy (~800MB RAM) | Käytä alppikuvia ja resurssirajojaPoista havainnointi vapaatasoille (Seq Cloud, Grafana Cloud, UptimeRobot) | Suorita kalliita palveluja (kääntäminen, ML) vain tilauksestaKuuden dollarin kuukausipalkalla VPS voi pyörittää tuotantoblogia, jossa on tilaa | **Tuotannon käyttöönotot:**Terveystarkastukset mahdollistavat nolla-ajan päivitykset Vartiotornilla | **Erilliset verkot tarjoavat turvallisuutta (etu-/tausta-eristys)**Band-kiinnikkeet dataa varten, joita tarvitset varmuuskopiointiin/lukitukseen

Dockerin hallinnoiman varaston nimetty määräCPU:n/muistin rajat estävät resurssien nälänhädän

Cloudflaren tunneli poistaa julkisten IP-osoitteiden tarpeen

.NET-kehittäjille:

  • Sisäänrakennettu konttijulkaisu .NET 9 poistaa Docker-tiedostot yksinkertaisista sovelluksistaTaotut Ubuntu-kuvat tarjoavat minimaalisen hyökkäyspinnan.NET Aspire tarjoaa parhaan luokan paikallisen kehityskokemuksen
  • Aspire voi tuottaa Docker Composea tuotannon käyttöönottoa vartenOpenTelemetria-integraatio tulee ilmaiseksi Aspirella
  • **Advanced Use -tapauksissa:**GPU-kontit mahdollistavat ML/AI-kuormat 10-15x-kiihdytyksellä
  • Moniarkkitehtuuri rakentaa tuen ARM64:lle ja AMD64:lle yhdestä lähteestäGitHub-toiminnot automatisoivat monialustan rakenteetTasovälitys nopeuttaa rajusti toistuvia rakennelmia
  • MatkaTämän blogin Dockerin evoluutio heijastaa tyypillistä kehitystä:

Lavan palvelut RAM-muistin käyttö Monimutkaisuus

Vaihe 1

(marras 2024) Täysi havainnoitavuus ~3,5GB tuotanto

  1. Vaihe 5(Tänään) + Pyri vaihtoehto Muuttuja Moderni
  2. Kaava: Aloita yksinkertainen, ratkaise ongelmia niiden ilmetessä, lisää monimutkaisuutta vain tarvittaessa.
  3. Mitä seuraavaksi?Riippuen polustasi:
  4. Opettele dokkaria

: Aloita

: Tutustu .NET-hakuun

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.