Back to "Ανάπτυξη Docker Βαθιά κατάδυση: Από τα βασικά σε Advanced .NET Containerization"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

.NET Containers DevOps Docker

Ανάπτυξη Docker Βαθιά κατάδυση: Από τα βασικά σε Advanced .NET Containerization

Sunday, 09 November 2025

Εισαγωγή

Ο Ντόκερ έχει μεταμορφώσει ριζικά τον τρόπο που φτιάχνουμε, στέλνουμε και εκτελούμε εφαρμογές.

Αυτό που ξεκίνησε ως ένα απλό εργαλείο εμπορευματοκιβωτίων έχει εξελιχθεί σε ένα πλήρες οικοσύστημα για τη σύγχρονη ανάπτυξη και ανάπτυξη εφαρμογών.

  1. **Αυτό είναι το τέταρτο και πιο περιεκτικό άρθρο στη σειρά Docker μου για τους προγραμματιστές .NET.**Αν είσαι νέος για τον Ντόκερ, ίσως να θέλεις να ξεκινήσεις με:
  2. Docker Compose- Ξεκινώντας με τις βασικές ρυθμίσεις πολλαπλών μεταφορών (Ιούλιος 2024)
  3. Ανάπτυξη εξαρτήσεων με Docker Compose- Καθιέρωση τοπικών dev περιβάλλοντα (Αύγουστος 2024)

ImageSharp με Docker

  • **- Επίλυση θεμάτων άδειας όγκου (Αύγουστος 2024)**Σε αυτή τη βαθιά κατάδυση, θα χτίσουμε σε αυτά τα θεμέλια για να εξερευνήσουμε:
  • Παραγωγή-έτοιμο Docker Compose: Η πραγματική στοίβα τρέχει αυτό το blog
  • Αυτοεξυπηρέτηση σε περιορισμένους πόρους: Πρακτικές τεχνικές βελτιστοποίησης για την ανάπτυξη VPS προϋπολογισμού
  • Υποστήριξη GPU: Εκτέλεση εργασιών ML σε δοχεία
  • Πολυ-αρχιτεκτονική κατασκευή: Υποστήριξη ARM64 και AMD64
  • NET 9 χαρακτηριστικά δοχείου: Ενσωματωμένη έκδοση εμπορευματοκιβωτίων χωρίς Dockerfiles

.NET φιλοδοξεί

: Η σύγχρονη προσέγγιση .NET στην ενορχήστρωση εμπορευματοκιβωτίων

ΣΗΜΕΙΩΣΗ: Αυτό είναι μέρος των πειραμάτων μου με AI / ένας τρόπος για να δαπανήσει $ 1000 Claude Code Web πιστώσεις.

Έχω ταΐσει αυτό ένα σωρό χαρτιά, καταλαβαίνω, ερωτήσεις που έπρεπε να δημιουργήσω αυτό το άρθρο.

Έχει πλάκα και γεμίζει ένα κενό που δεν έχω δει να γεμίζει πουθενά αλλού.

Είτε αναπτύσσετε μια απλή εφαρμογή web ή ενορχηστρώνοντας μια πολύπλοκη αρχιτεκτονική μικρουπηρεσιών με GPU-επιταχυνόμενα μοντέλα εκμάθησης μηχανών, αυτός ο οδηγός σας μεταφέρει από τα βασικά Docker μέχρι τις εφαρμογές συσκευασίας παραγωγής-έτοιμες - με πραγματικά παραδείγματα από το τρέξιμο ως επί το πλείστον διαυγή.com.

  • Docker Θεμελιώδη στοιχεία: Κατανόηση των εμπορευματοκιβωτίωνΤι είναι ο Ντόκερ, αλήθεια;
  • **Στον πυρήνα του, Docker είναι μια πλατφόρμα εμπορευματοκιβωτίων που πακετάρει την εφαρμογή σας και όλες τις εξαρτήσεις της σε μια τυποποιημένη μονάδα που ονομάζεται δοχείο.**Σε αντίθεση με τις εικονικές μηχανές που εικονίζουν ολόκληρα λειτουργικά συστήματα, τα δοχεία μοιράζονται τον πυρήνα του υπολογιστή OS διατηρώντας ταυτόχρονα απομονωμένους χώρους χρηστών.

Σκέψου το ως εξής:

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

# The container solution
"Ship your machine!" 

Εικονικές μηχανές

  1. : Κάθε VM τρέχει μια πλήρη στοίβα OS (Κύκλος Linux, βιβλιοθήκες συστήματος, κ.λπ.) - βαρύ και αργό για να ξεκινήσειΔοχεία
  2. : Μοιραστείτε τον πυρήνα ξενιστή, πακέτο μόνο κωδικό εφαρμογής και εξαρτήσεις - ελαφρύ και γρήγοροΓιατί η ύλη των εμπορευματοκιβωτίων για τους προγραμματιστές
  3. **Τα κοντέινερ λύνουν διάφορα κρίσιμα προβλήματα:**Περιβαλλοντική συνοχή
  4. : Η ανάπτυξη, οι δοκιμές και τα περιβάλλοντα παραγωγής είναι πανομοιότυπαΑπομόνωση εξάρτησης
  5. : Όχι πια "DLL κόλαση" ή αντικρουόμενες εκδόσεις βιβλιοθήκηςΑνατρεπόμενα Οικοδομημένα

: Ίδια είσοδος = ίδια έξοδος, κάθε φορά

Γρήγορη Ανάπτυξη

# 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

: Εκτέλεση δεκάδων εμπορευματοκιβωτίων σε έναν και μόνο ξενιστή

  • Βασικές έννοιες DockerImages vs Containers
  • Εικόνεςείναι αμετάβλητα, layered συστήματα αρχείων.
  • **Κάθε οδηγία σε ένα αρχείο Docker δημιουργεί ένα νέο στρώμα:**Αυτό το στρώμα είναι ισχυρό.

Φύλαξη

: Τα αμετάβλητα στρώματα ξαναχρησιμοποιούνται, επιταχύνοντας τις κατασκευές

# 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

: Εκτέλεση ως μη-root χρήστη

Υγειονομικοί έλεγχοι

: Οι ορχήστρες εμπορευματοκιβωτίων μπορούν να παρακολουθούν την υγεία των εφαρμογών

Ακριβές περιβάλλον

  • : Ορισμός προεπιλογών παραγωγής
  • Κτίριο και Τρέξιμο
  • Docker Compose: Multi-Container Ενορχήστρωση
  • Docker Compose σας επιτρέπει να καθορίσετε και να εκτελέσετε πολλαπλές εφαρμογές.
  • Αντί να διαχειρίζεστε τα εμπορευματοκιβώτια μεμονωμένα, περιγράφετε ολόκληρη τη στοίβα εφαρμογής σας σε ένα αρχείο YAML.

Γιατί ο Ντόκερ Συνταγματάρχης;docker runΕξετάστε μια τυπική εφαρμογή NET web:

ASP.NET Core web app

Βάση δεδομένων PostgreSQL**Redis cachedocker-compose.yml**Seq για την καταγραφή

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. Complete Real-World Παράδειγμα: Πλατφόρμα blog παραγωγήςΕδώ είναι το/mnt/*πραγματική παραγωγή
  3. **που τρέχει αυτό ακριβώς το site (κυρίως διαυγής.com):**Βασικά πρότυπα παραγωγής:
  4. Ενιαίο δίκτυο: Όλες οι υπηρεσίες
  5. για απλότηταΌρη υπόκλισης (Bind Mounts)
  6. : Μονοπάτια υποδοχής () για επίμονα δεδομένα που χρειάζεστε για backup/access
  7. Ονομάζονται τόμοι: Docker-managed αποθήκευση για δεδομένα που δεν χρειάζεστε άμεση πρόσβαση σε.envΕτικέτες Σκοπιάς

: Μόνο υπηρεσίες ενημέρωσης που επισημαίνονται ρητά για την αυτόματη ενημέρωση

Όρια πόρων

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

: Οι περιορισμοί CPU στη μεταφραστική υπηρεσία εμποδίζουν την πείνα των πόρων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 βασικά χαρακτηριστικά
  • Εξαρτήσεις υπηρεσιών
  • Docker Compose orchestrates startup order.
  • Η

απαιτεί τον έλεγχο υγείας της βάσης δεδομένων να περάσει πριν από την έναρξη της εφαρμογής web.:

  • Μεταβλητές περιβάλλοντος και μυστικά
  • Για μυστικά παραγωγής, χρησιμοποιήστε Docker Secrets ή εξωτερικούς μυστικούς διαχειριστές (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault).
  • Ονομάζονται τόμοι εναντίον Bind Mounts

Ονομαζόμενοι όγκοι

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

services:
  web:
    networks:
      - frontend
      - backend

  db:
    networks:
      - backend  # Not exposed to frontend

Διοικούμενος από τον Docker

Επιβραδυντικά δεδομένα σε όλο το δοχείο επανεκκινεί

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

Μπορεί να υποστηρίζεται/αποκατασταθεί με εντολές Docker

  • Συμβατό cross-platform
  • Αγκίστρια
  • Άμεση χαρτογράφηση στο σύστημα αρχείων υπολογιστή

Χρήσιμο για ανάπτυξη (ζωντανός κωδικός επαναφόρτωσης)

# 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

Αρχεία ρύθμισης, αρχεία καταγραφής, uploads

Δικτύωση

**Τα δίκτυα παρέχουν απομόνωση.**Εδώ, η βάση δεδομένων είναι προσβάσιμη μόνο σε υπηρεσίες υποστήριξης, όχι άμεσα εκτεθειμένη.

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

Κοινή Docker Compose Εντολές

Ανάπτυξη εναντίον Αρχείων Compose Παραγωγής

# 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

(βάση):

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

(ανάπτυξη - αυτόματη επεξεργασία):Docker-compose. prod.yml(παραγωγή):

Υποστήριξη GPU σε Docker: Επιτάχυνση ML Lettings

  • **Η μηχανική μάθηση, οι επιστημονικές υπολογιστικές εφαρμογές και οι εφαρμογές επεξεργασίας βίντεο συχνά απαιτούν επιτάχυνση GPU.**Docker υποστηρίζει NVIDIA GPUs μέσω της NVIDIA Container Toolkit.
  • Ρύθμιση εργαλείων κοντέινερ NVIDIAΑρχείο Docker για εφαρμογή GPU-Accelerated Python/PyTorch
  • Τρέξιμο κοντέινερ GPUGPU σε Docker Compose
  • Real-World Παράδειγμα: Translation Service with GPU and CPU BuildsΕδώ είναι ένα πραγματικό παράδειγμα παραγωγής από

ως επί το πλείστον διαυγής - 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:

, μια νευρική υπηρεσία μετάφρασης μηχανών που έφτιαξα ότι δύναμη αυτόματη μετάφραση σε αυτό το blog.

Το έργο καταδεικνύει:

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 και CPU

  • scottgal/mostlylucid-nmt:gpu- Ίδια βάση κώδικα, διαφορετικές βασικές εικόνες
  • scottgal/mostlylucid-nmt:cpuΠολυ-αρχιτεκτονική κατασκευή
  • scottgal/mostlylucid-nmt:gpu-min- Υποστηρίζει AMD64 και ARM64
  • scottgal/mostlylucid-nmt:cpu-minΒελτιστοποιημένες εικόνες Docker

- Τόσο πλήρεις όσο και ελάχιστες παραλλαγές

  • Έτοιμη για την παραγωγή- Υγειονομικοί έλεγχοι, επιμονή όγκου, σωστή καταγραφή
  • GPU-Accelerated Translation ServiceCPU-Μόνο εναλλακτική
  • **Για περιβάλλοντα χωρίς GPU, η ίδια υπηρεσία τρέχει σε CPU:**Διαθέσιμες παραλλαγές εικόνας:
  • - CUDA 12.6 με υποστήριξη GPU PyTorch (~5GB)- Μόνο CPU, μικρότερο αποτύπωμα (~2,5GB)
  • - Minimal GPU κατασκευή, κανένα προφορτωμένο μοντέλο (~4GB): /health- Minimal CPU build (~1.5GB)/readyΒασικά χαρακτηριστικά:
  • Επιτάχυνση GPU: 10-15x ταχύτερη μετάφραση με CUDA

Μοντέλο Auto-Download: Downloads translation models on-demandΥποστήριξη FallbackName

: Δοκιμάζει Opus-MT → mBART50 → M2M100 για μέγιστη γλωσσική κάλυψη

Επιμονή σε Όγκο

: Τα μοντέλα Cache σε όλο το δοχείο επανεκκινεί

# 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

για ορχηστρωτές

Multi-Architecture

# 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

: Λειτουργεί σε x86_64 και ARM64 (Apple Silicon, 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

Multi-Architecture Κατασκευάζει με Docker Buildx

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

Ρύθμιση Buildx

  • Docker Buildx περιλαμβάνεται στην επιφάνεια εργασίας Docker.
  • Για το Linux:
  • Multi-Architecture Dockerfile
  • Τα περισσότερα αρχεία Dockers λειτουργούν χωρίς αλλαγές, αλλά εδώ είναι μερικές συμβουλές:
  • Κατασκευή πολλαπλών πλατφορμών

Multi-Architecture με Docker Compose

Δυστυχώς, ο Ντόκερ Κόμπος δεν υποστηρίζει άμεσα την κατασκευή.

Δουλειές γύρω από:

Επιλογή 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 αγωγός.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. Ενεργοποιητές σε ωθήσεις σε κύριες ή ετικέτες έκδοσηςΟρίζει QONI για την εξομοίωση της εγκάρσιας πλάκας
  2. Κατασκευές για AMD64 και ARM64Δημιουργεί ετικέτες αυτόματα (κατάστημα όνομα, σημασιολογικές εκδόσεις, SHA)
  3. Χρησιμοποιεί το μητρώο caching για γρηγορότερες κατασκευέςNET 9 Βελτιώσεις εμπορευματοκιβωτίων
  4. **NET 9 εισάγει σημαντικές βελτιώσεις στην υποστήριξη εμπορευματοκιβωτίων, καθιστώντας ευκολότερο από ποτέ να εμπορευματοκιβωτίων .NET εφαρμογές χωρίς καν να γράψετε ένα αρχείο Docker.**Ενσωματωμένο Container Publishing
  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

Μικρότερες εικόνες

: Trimming and AOT collection support

Κοπή και AOT για μικρότερες εικόνες

  • Αποτελέσματα:
  • Πρότυπο
  • ~220MB
  • Με κούρεμα

~110MB

  • Με AOT
  • ~12MB για απλές εφαρμογές!
  • Σύγκριση: Dockerfile vs Built-in
  • Παραδοσιακή προσέγγιση Dockerfile:

Ενσωματωμένη προσέγγιση εμπορευματοκιβωτίων:

Και οι δύο παράγουν παρόμοιες εικόνες, αλλά η ενσωματωμένη προσέγγιση είναι απλούστερη και μπορεί να διατηρηθεί.

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

Πότε να χρησιμοποιήσετε Dockerfile vs Ενσωματωμένο

  • **Χρησιμοποιήστε το Dockerfile όταν:**Χρειάζεστε πλήρη έλεγχο της εικόνας
  • Εγκατάσταση εξαρτήσεων συστήματοςΣυγκρότημα πολυβάθμιων κατασκευών
  • Μη τυποποιημένες βασικές εικόνεςΧρήση ενσωματωμένου όταν:

Standard .NET web/console εφαρμογές

  • Θέλεις απλότητα.
  • Βελτιστοποιήσεις Microsoft Leveraging

Γρήγορη πρωτοτυποποίηση

Φωτογραφίες chiseled Ubuntu

NET 9 υποστηρίζει "chiseled" Ubuntu εικόνες - υπερ-μίνι εικόνες βάσης:

Παροχές:

Μικροσκοπικό

  1. ~50% μικρότερο από τις κανονικές εικόνεςΑσφαλής
  2. **: Ελάχιστη επιφάνεια επίθεσης (χωρίς διαχειριστή συσκευασίας, κέλυφος)**Γρήγορα.
  3. : Πιο γρήγορα τραβάει και ξεκινάειΑνταλλαγές:
  4. **Χωρίς κέλυφος (σκληρότερα προς αποσφαλμάτωση)**Βοηθητικά συστήματα περιορισμένης ευθύνης
  5. **Ιδανικό για την παραγωγή όπου η ασφάλεια και το μέγεθος ύλη περισσότερο.**Εισαγωγή στο .NET Aspire

.NET Το Aspire είναι μια κοινή, έτοιμη για σύννεφα στοίβα για την κατασκευή κατανεμημένων εφαρμογών.

Σκεφτείτε το ως Docker Compose σε στεροειδή, ειδικά σχεδιασμένο για .NET μικρουπηρεσίες.

  1. **Τι είναι το "Aspire";**Ο Aspire παρέχει:
  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, PostgreSQL, RabbitMQ, κ.λπ.)

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

Aspire Architecture

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

Μια λύση Aspire έχει τρεις τύπους έργων:

App Host

  • : Οργανώνει τις υπηρεσίες σαςService Projects
  • **: Οι πραγματικές σας υπηρεσίες (Web APIs, εργαζόμενοι κ.λπ.)**Προκαθορισμένα στοιχεία υπηρεσίας
  • **: Shared configuration (logging, health checks, κλπ.)**Γρήγορο παράδειγμα
  • **1.**Δημιουργία έργου Aspire:
  • **2.**App Host (MyDistributedApp.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

: Πόσιμο Docker Compose για πολυ-service ενορχήστρωση

  • Επιτάχυνση ML: Υποστήριξη Harness GPU για τον υπολογισμό της έντασης του φόρτου εργασίας
  • Multi-Platform: Χρησιμοποιήστε builtx για ARM και AMD64 συμβατότητα
  • Απλούστευση .NET: Ενσωμάτωση ενσωματωμένης έκδοσης εμπορευματοκιβωτίων

Χτίζοντας μικροϋπηρεσίες: Εξερευνήστε .NET Επιδιώκουν για κατανεμημένες εφαρμογέςΤο οικοσύστημα εμπορευματοκιβωτίων παρέχει εργαλεία για κάθε σενάριο.

Ξεκινήστε απλά, περιηγηθείτε και σταδιακά υιοθετήστε προηγμένα χαρακτηριστικά καθώς οι ανάγκες σας αυξάνονται.

Συμπληρωματικοί πόροι

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 Compose Reference.NET Container Εικόνες
  • .NET Επιθυμούν τεκμηρίωσηΕργαλείο εμπορευματοκιβωτίων NVIDIAdocker logsΝτόκερ ΧιούτξCity name (optional, probably does not need a translation)
  • **ch τρέχει μόνο ό, τι χρειάζεστε:**Γιατί αυτό λειτουργεί για την ανάπτυξη:
  • SMTP4Dev: Λειτουργία email δοκιμής χωρίς πραγματικό διακομιστή SMTP
  • PostgreSQL: Ταιριάζει με τη βάση δεδομένων παραγωγής

Συνολικό αποτύπωμα

~200MB RAM vs 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

**Τι έχει αφαιρεθεί και εναλλακτικές λύσεις:**Αριθ. Prometheus/Grafana

: Χρήση εξωτερικής παρακολούθησης (UptimeRobot, BetterStack ελεύθερη βαθμίδα)

Αριθ. Seq

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

: Χρήση καταγραφής με βάση το αρχείο +, ή Seq Cloud ελεύθερη βαθμίδα

Χωρίς Σκοπιά

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

: Χειροκίνητες ενημερώσεις με τις κοινοποιήσεις GitHub Activities

Καμία μεταφραστική υπηρεσία

: Εκτέλεση κατά παραγγελία σε ξεχωριστό δοχείο που ξεκινάτε/σταματάτε χειροκίνηταΌρια πόρων: Αποτρέψτε κάθε ενιαία υπηρεσία από την κατανάλωση όλης της μνήμης

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

Στρατηγική Προοδευτικής ΕνίσχυσηςΞεκινήστε minimal, προσθέστε υπηρεσίες όπως απαιτείται:

Στάδιο 1: Κεντρικό (512MB-1GB 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

Κοινόχρηστο piλαίσιο δεδοένωνΑντί για μία βάση δεδομένων ανά υπηρεσία, χρησιμοποιήστε ένα παράδειγμα PostgreSQL με πολλαπλές βάσεις δεδομένων:

Αποταμιεύσεις

: 400MB RAM ανά πρόσθετη βάση δεδομένων που εδραιώνετε

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

  • Όριο CPU για υπηρεσίες υποβάθρου
  • Αυτό εμποδίζει τις εργασίες υποβάθρου να λιμοκτονήσουν την εφαρμογή σας στο διαδίκτυο.

Συνεχείς όγκοι Cache

  • Όπως αναφέρεται στο άρθρο 1 παράγραφος 1 στοιχείο α) του κανονισμού (ΕΕ) αριθ. 182/2011 του Ευρωπαϊκού Κοινοβουλίου και του Συμβουλίου, της 11ης Φεβρουαρίου 2011, για τη θέσπιση κανόνων εφαρμογής του κανονισμού (ΕΕ) αριθ. 182/2011 του Ευρωπαϊκού Κοινοβουλίου και του Συμβουλίου όσον αφορά τους οργανισμούς αξιολόγησης της συμμόρφωσης με τις απαιτήσεις του κανονισμού (ΕΕ) αριθ. 182/2011 του Ευρωπαϊκού Κοινοβουλίου και του Συμβουλίου (ΕΕ L 347 της 20.12.2013, σ. 885), και για την τροποποίηση του κανονισμού (ΕΕ) αριθ. 182/2011 του Ευρωπαϊκού Κοινοβουλίου και του Συμβουλίου (ΕΕ L 347 της 20.12.2013, σ. 1).
  • ImageSharp με Dockerdocker logs, η τοποθέτηση καταλόγων cache εμποδίζει την περιττή επεξεργασία:
  • Γιατί έχει σημασία;
  • : Χωρίς αυτό, κάθε δοχείο επανεκκίνηση αναγεννά όλες τις μικρογραφίες/επεξεργασμένες εικόνες.

Χρήση εξωτερικών υπηρεσιών (δωρεάν κατηγορίες)

Εξυπηρέτηση Αυτό-Hosted RAM & Εξωτερική Εναλλακτική

~500MB ~ Seq Cloud (10GB/μήνα δωρεάν) ~

# 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

Προμηθέας + Grafana ~600MB ~ Grafana Cloud (δωρεάν βαθμίδα)

# 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

Ουμάμι ~200MB Πιθανό (πληρωμένο) ή αυτο-ξενώνας κάπου αλλού

# Quick resource check
docker stats --no-stream

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

Στρατηγική

: Αποφορτίστε την παρατηρητικότητα σε ελεύθερες βαθμίδες, κρατήστε την εφαρμογή πυρήνα στο VPS σας.

6.

Υπηρεσίες On-Demand

# 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 όταν η μεταφραστική υπηρεσία δεν λειτουργείΠαράδειγμα φιλοξενίας προϋπολογισμού πραγματικού κόσμουΕδώ είναι τι τρέχει σε ένα $ 6 μήνες 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,2GB ελεύθερο)

Δίσκος: ~2GB

  1. CPU: < 10% σε αδράνεια, <50% υπό φορτίο: dotnet run --project Mostlylucid.AppHostΤι είναι διαφορετικό:
  2. **No Prometheus/Grafana (use UptimeRobot + Cloudflare Analytics)**Αριθ. Seq (χρήση)
      • περιστασιακό grep)
    • Δεν Umami (χρησιμοποιήστε Cloudflare Web Analytics - χωρίς)
    • Η Σκοπιά ελέγχει ωριαία αντί για 5 λεπτά
    • Καμία μεταφραστική υπηρεσία (τρέξε με το χέρι όταν χρειάζεται)
  3. Παρακολούθηση του προϋπολογισμούΧωρίς τον Προμηθέα/Γκράφανα, χρησιμοποιήστε αυτές τις ελεύθερες εναλλακτικές λύσεις:
  4. **Παρακολούθηση της υγείας:**Παρακολούθηση καταγραφής:.envΧρήση πόρων:

Aspire Version: The .NET Way

Τώρα ας ξαναφτιάξουμε ολόκληρη τη στοίβα χρησιμοποιώντας .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

Πρώτα, δημιουργήστε το Aspire App Host:

Κυρίως διαυγής. AppHost/Program.cs: |---------|---------------|-------------| | Προκαθορισμένα προγράμματα υπηρεσιών έμπνευσηςNameΔημιουργία | Κυρίως διαυγής.ΥπηρεσίεςΠροκαταβολέςΈργο: | Ενημέρωση ως επί το πλείστον διαυγής/πρόγραμμα.csΟφέλη της Εμπνευσμένης Προσέγγισης | Εμπειρία στην ανάπτυξη: | docker-compose up | dotnet runΕνιαία εντολή | **Ξεκινάει τα πάντα.**Ταχυδρόμος | : Beautiful UI at http://localhost:15888 showing: | docker logsΌλες οι υπηρεσίες με ζωντανή κατάσταση | Καταχωρήσεις από όλες τις υπηρεσίες σε ένα μέροςΔιανεμημένα ίχνη σε όλες τις υπηρεσίες | Μετρικός και υγειονομικός έλεγχοςΑνακάλυψη υπηρεσίας | : Οι υπηρεσίες βρίσκουν ο ένας τον άλλον αυτόματα μέσω ονομάτωνΡύθμιση

: Κεντρικοποιημένο στο AppHost, όχι άλλο

juggling

  • Ανάπτυξη Παραγωγής:
  • Δημιουργία δηλώσεων ανάπτυξης από το Aspire:
  • Δημιουργία Docker-compose.yml
  • (απλουστευμένο):
  • Aspire vs Traditional Docker Compose

Χαρακτηριστικό ~ Docker Compose ~ .NET Aspire ~

  • Ρύθμιση
  • ~ Εγχειρίδιο YAML ~ κωδικός C# με IntelliSense ~
  • Ανακάλυψη υπηρεσίας
  • Αυτόματη συσκευή εγγραφής VarsComment
  • Παρατηρησιμότητα

Φέρτε το δικό σας Ενσωματωμένο (OpenTelemetry)

  • Ανάπτυξη
    • Dashboard
  • Αποσφαλμάτωση

Επισυνάψτε το δοχείο στο Visual Studio στο F5

Ημερολόγια

  1. **Το κεντρικό ταμπλό**Εντοπισμός
  2. **Τοποθέτηση χειροκίνητα ~ Αυτόματη κατανεμημένη ιχνηλάτηση ~**Παραγωγή
  3. **Χρησιμοποίησε το YAML άμεσα δημιουργήστε τα δηλωτικά **Μάθηση καμπύλης
  4. **~ YAML σύνταξη ~ C# you already know ~**Πότε να χρησιμοποιήσετε Aspire vs Docker Compose
  5. **Χρησιμοποιήστε το Aspire όταν:**Κτίριο .NET μικρουpiηρεσίε

Θέλετε ολοκληρωμένη αποσφαλμάτωση

  • Η ομάδα είναι άνετη με C#
  • Πρέπει να μοιραστείτε τον εντοπισμό έξω από το κουτί
  • Αναπτύσσεστε σε εφαρμογές Azure Container (μητρική υποστήριξη)
  • Χρησιμοποιήστε Docker Compose όταν:
  • Υπηρεσίες Polyglot (Node.js, Python, Go κ.λπ.)
  • Η ομάδα προτιμά την υποδομή ως κωδικό YAML

Αναπτύσσοντας σε οποιοδήποτε Docker-συμβατό ξενιστή

Χρειάζεστε τον μέγιστο έλεγχο της ρύθμισης του δοχείου

  1. Απλές εφαρμογές ενιαίας υπηρεσίας
  2. Χρήση και των δύο:
  3. Επιδιώκουν την τοπική ανάπτυξη
  4. Δημιουργήστε Docker Compose για την ανάπτυξη της παραγωγήςlatest)
  5. Οι καλύτεροι και από τους δύο κόσμους!
  6. Εξέλιξη της εγκατάστασης Docker αυτού του blog.dockerignoreΑυτό το ταξίδι Docker του blog δείχνει τυπική εξέλιξη:
  7. Ιούλιος 2024 - Απλή Αρχή
  8. : Μόνο η εφαρμογή, Cloudflared και η Σκοπιά

Αύγουστος 2024 - Dev Εξαρτήσεις

  1. : Προστιθέμενες υπηρεσίες μόνο ανάπτυξης
  2. Αύγουστος 2024 - ImageSharp Fix
  3. : Λύθηκε άδειες όγκου για την αποθήκευση.envΝοέμβριος 2024 - Πλήρης Στοίβα
  4. : Πλήρης παρατηρητικότητα με τον Προμηθέα, Grafana, Seq
  5. Σήμερα.depends_on: Επιδίωξη επιλογής για .NET-πρώτη ανάπτυξη
  6. Μαθήματα που έμαθαν:
  7. Ξεκινήστε απλά, προσθέστε την πολυπλοκότητα μόνο όταν χρειάζεται
  8. Χωριστές ρυθμίσεις dev και παραγωγής

Τα όρια πόρων εμποδίζουν μια υπηρεσία από το να σκοτώνει άλλους

  1. Ογκομετρήσεις για caches εξοικονομήστε σημαντικό χρόνο επεξεργασίας
  2. Το Watchtown επιτρέπει την αυτόματη ενημέρωση του χρόνου μηδέν-down
  3. Παρατηρησιμότητα αξίζει το κόστος των πόρων στην παραγωγή
  4. Περίληψη βέλτιστων πρακτικών
  5. Βέλτιστες πρακτικές Dockerfile
  6. Χρήση πολυβάθμιων κατασκευών
  7. Εκτελέστε ως μη-root χρήστης
  8. Οδηγίες παραγγελίας για βέλτιστη αποθήκευση

Χρήση ειδικών ετικετών εικόνας βάσης (όχι

  1. Συμπεριλάβετε υγειονομικούς ελέγχους
  2. Χρήση
  3. να αποκλείσει περιττά αρχεία
  4. Ελαχιστοποιήστε τα στρώματα (εντολές συνδιαλλαγής 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 χρήστης

Κρυπτογράφηση στρώματος

  • Πολυβάθμιες κατασκευές για τη μείωση του μεγέθους της εικόνας
  • Χρήση
  • γενναιόδωρα
  • Αλπικές εικόνες για μικρότερο μέγεθος
  • Χρησιμοποιήστε βάσεις όγκου για την ανάπτυξη

Ρύθμιση κατάλληλων ορίων πόρων

  • Χρήση υγειονομικών ελέγχων για ενορχήστρωση
  • Αντιμετώπιση των κοινών ζητημάτων
  • Το κοντέινερ δεν ξεκινάει.
  • Αργά Κατασκευές
  • Θέματα δικτύωσης
  • Ζητήματα Άδειας Όγκος

Συμπέρασμα

  • Docker έχει εξελιχθεί από ένα απλό εργαλείο εμπορευματοκιβωτίων σε μια ολοκληρωμένη πλατφόρμα για την οικοδόμηση, τη ναυτιλία, και τη λειτουργία σύγχρονων εφαρμογών.
  • Αυτός ο οδηγός σας έχει οδηγήσει από τα βασικά στοιχεία μέχρι την παραγωγή-έτοιμες εφαρμογές, με πραγματικά παραδείγματα από το τρέξιμο ως επί το πλείστον διαυγή.com.
  • Απομακρύνσεις κλειδιών@ title: window
  • Για αρχάριους:
  • Ξεκινήστε με το

βασική ρύθμιση Docker Compose

    • μόνο 3 υπηρεσίες
  • Χρήση
  • Εξαρτήσεις μόνο για την ανάπτυξη
  • για τοπική εργασία

Λύστε κοινά θέματα όπως

άδειες έντασης

νωρίς |-------|----------|-----------|------------| | **Για Self-Hosters για τον προϋπολογισμό VPS:**Μίνιμουμ εκκίνησης: App + Βάση δεδομένων + Αντιστροφή Proxy (~800MB RAM) | Χρήση αλπικών εικόνων και ορίων πόρωνOffload παρατηρησιμότητα σε ελεύθερες βαθμίδες (Seq Cloud, Grafana Cloud, UptimeRobot) | Εκτελέστε δαπανηρές υπηρεσίες (μετάφραση, ML) μόνο κατά παραγγελίαΈνα VPS $ 6 μηνών μπορεί να τρέξει ένα blog παραγωγής με χώρο για να διαθέσει | **Για την ανάπτυξη της παραγωγής:**Οι έλεγχοι υγείας καθιστούν δυνατή την ενημέρωση του χρόνου μηδενισμού με τη Σκοπιά | **Τα ξεχωριστά δίκτυα παρέχουν ασφάλεια (απομόνωση πρόσοψης/υποστήριξης)**Δέστε βάσεις για τα δεδομένα που χρειάζεστε για την υποστήριξη/πρόσβαση

Ονόματα τόμων για την αποθήκευση Docker-managedΤα όρια CPU/μνήμης εμποδίζουν την πείνα των πόρων

Η σήραγγα Cloudflare εξαλείφει την ανάγκη για δημόσιες διευθύνσεις IP

Για τους προγραμματιστές NET:

Στάδιο Υπηρεσίες RAM Usage Πολυπλοκότητα

Στάδιο 1

(Νοε 2024) Πλήρες παρατηρητήριο ~3.5GB ~ Παραγωγή

  1. Στάδιο 5(Σήμερα) & > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < > > > > < > < > > < > > > < > > > > > > > > > > > > > < > > > > > > > > < > < > > > < > > < > > > < > > > < > > > > < > < > < < < < < < & & > > > > & > > > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > < < < < < &lt
  2. Το μοτίβο: Ξεκινήστε απλά, λύστε τα προβλήματα καθώς προκύπτουν, προσθέστε την πολυπλοκότητα μόνο όταν χρειάζεται.
  3. Ποιο είναι το επόμενο;Ανάλογα με το μονοπάτι σας:
  4. Μαθαίνοντας Ντόκερ

: Ξεκινήστε με

: Εξερευνήστε .NET Aspire

Happy containerizing! 🐳

logo

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