Start Chat
Search
Ithy Logo

Jak Zautomatyzować Wdrożenia Docker na Zewnętrznym Hoście za Pomocą Azure DevOps?

Pełny przewodnik krok po kroku do tworzenia potoków CI/CD wykorzystujących zdalne środowiska Docker.

azure-devops-docker-external-host-0ge7papn

Tworzenie potoku (pipeline) w Azure DevOps, który współpracuje z obrazem Docker na zewnętrznym hoście, to częsty scenariusz pozwalający na elastyczne zarządzanie środowiskami i wdrożeniami. Można to osiągnąć na kilka sposobów, w zależności od konkretnych potrzeb – czy chcesz uruchomić zadania potoku w specyficznym kontenerze, czy też wdrożyć aplikację na zdalnym serwerze Docker.

Kluczowe Aspekty Konfiguracji

  • Połączenia Usług (Service Connections): Niezbędne do bezpiecznego uwierzytelniania z zewnętrznymi rejestrami kontenerów (np. Azure Container Registry, Docker Hub) oraz potencjalnie ze zdalnymi hostami Docker.
  • Definicje Zadań w Kontenerach (YAML): Użycie sekcji container w pliku YAML potoku pozwala na wykonywanie zadań wewnątrz kontenera pobranego z określonego obrazu Docker.
  • Agenci Self-Hosted: Instalacja agenta Azure DevOps bezpośrednio na zewnętrznym hoście (lub w kontenerze Docker na tym hoście) jest najpewniejszym sposobem na bezpośrednie wykonywanie poleceń Docker na tej maszynie.

Główne Podejścia do Integracji z Zewnętrznym Hostem Docker

Istnieją dwie główne metody integracji potoków Azure DevOps z obrazami Docker na zewnętrznych hostach:

Podejście 1: Uruchamianie Zadań Potoku w Kontenerze z Zewnętrznego Rejestru

Ta metoda jest idealna, gdy środowisko wykonawcze Twojego potoku (np. do budowania, testowania) wymaga specyficznych narzędzi lub konfiguracji dostępnych w niestandardowym obrazie Docker. Obraz ten może być przechowywany w zewnętrznym rejestrze (prywatnym lub publicznym).

Krok 1: Konfiguracja Połączenia Usługi z Rejestrem Kontenerów

Aby Azure DevOps mógł pobrać obraz z zewnętrznego rejestru (np. Azure Container Registry (ACR), prywatnego Docker Hub, innego rejestru), musisz skonfigurować Połączenie Usługi (Service Connection):

  1. Przejdź do Ustawień Projektu (Project Settings) -> Potoki (Pipelines) -> Połączenia usług (Service connections).
  2. Kliknij "New service connection" i wybierz typ "Docker Registry".
  3. Wybierz swój typ rejestru (ACR, Docker Hub, Others).
  4. Podaj wymagane dane: adres URL rejestru, nazwę użytkownika/ID jednostki usługi, hasło/klucz jednostki usługi oraz nazwę połączenia usługi.

Krok 2: Definicja Zadania Kontenerowego w YAML

W pliku azure-pipelines.yml zdefiniuj zadanie (job), które ma być uruchomione w kontenerze:


pool:
  vmImage: 'ubuntu-latest' # Agent hostujący (może być też self-hosted)

resources:
  containers:
  - container: my_container_alias # Alias kontenera
    type: ACR # Typ rejestru (ACR, Docker Hub, etc.)
    azureSubscription: 'MyAzureSubscriptionServiceConnection' # Opcjonalne dla ACR
    resourceGroup: 'MyResourceGroup' # Opcjonalne dla ACR
    registry: 'youracrname.azurecr.io' # Nazwa twojego rejestru
    repository: 'your-image-name' # Nazwa repozytorium obrazu
    endpoint: 'MyDockerRegistryServiceConnection' # Nazwa połączenia usługi (jeśli nie ACR lub publiczny Docker Hub)
    image: 'yourregistry.com/your-image-name:tag' # Pełna nazwa obrazu (alternatywa dla endpoint/registry/repository)

jobs:
- job: BuildInContainer
  displayName: 'Build inside custom container'
  container: my_container_alias # Użyj zdefiniowanego kontenera
  steps:
  - script: |
      echo "Ten skrypt działa wewnątrz kontenera!"
      # Tutaj umieść kroki budowania, testowania itp.
      # Masz dostęp do narzędzi zainstalowanych w obrazie Docker.
    displayName: 'Run script in container'
  

Wszystkie kroki (steps) w ramach zadania BuildInContainer będą wykonywane wewnątrz kontenera uruchomionego z obrazu yourregistry.com/your-image-name:tag.

Diagram aplikacji skonteneryzowanej Docker

Architektura aplikacji skonteneryzowanej przy użyciu Docker.

Podejście 2: Wdrażanie/Uruchamianie Kontenerów na Zewnętrznym Hoście przez Agenta Self-Hosted

To podejście jest stosowane, gdy celem potoku jest wdrożenie lub zarządzanie kontenerami bezpośrednio na konkretnej maszynie zewnętrznej (np. serwerze deweloperskim, maszynie wirtualnej w innej chmurze). Wymaga to zainstalowania agenta Azure DevOps na tym hoście.

Krok 1: Instalacja i Konfiguracja Agenta Self-Hosted na Zewnętrznym Hoście

  1. Zainstaluj Docker na zewnętrznym hoście.
  2. Przejdź do Ustawień Organizacji (Organization Settings) -> Pule agentów (Agent pools).
  3. Utwórz nową pulę agentów (lub użyj istniejącej, np. 'Default').
  4. Kliknij "New agent" i postępuj zgodnie z instrukcjami, aby pobrać i skonfigurować agenta na zewnętrznym hoście (Linux, macOS lub Windows). Będziesz potrzebował adresu URL organizacji Azure DevOps i tokenu PAT (Personal Access Token) z odpowiednimi uprawnieniami.
  5. (Opcjonalnie, zalecane) Uruchomienie agenta w kontenerze Docker: Możesz uruchomić agenta w kontenerze na hoście, co zapewnia izolację. Użyj oficjalnego obrazu agenta Microsoft:
    
          # Przykład dla Linuksa
          docker run -d --name azdevops-agent \
            -e AZP_URL=https://dev.azure.com/YOUR_ORG_NAME \
            -e AZP_TOKEN=YOUR_PAT_TOKEN \
            -e AZP_POOL=YOUR_AGENT_POOL_NAME \
            -e AZP_AGENT_NAME=my-docker-agent \
            -v /var/run/docker.sock:/var/run/docker.sock \
            -v /path/on/host/_work:/opt/agent/_work \
            mcr.microsoft.com/azure-pipelines/agent:latest
          
    Ważne: Montowanie gniazda Docker (-v /var/run/docker.sock:/var/run/docker.sock) pozwala agentowi (działającemu w kontenerze) na wykonywanie poleceń Docker na hoście. Jest to potężne, ale niesie ze sobą implikacje bezpieczeństwa – kontener agenta zyskuje uprawnienia do zarządzania wszystkimi kontenerami na hoście.

Krok 2: Wycelowanie Potoku w Pulę Agentów Self-Hosted

W pliku azure-pipelines.yml wskaż pulę agentów, w której znajduje się Twój skonfigurowany agent:


pool:
  name: 'YOUR_AGENT_POOL_NAME' # Nazwa puli zawierającej agenta na zewnętrznym hoście
  

Krok 3: Wykonywanie Poleceń Docker na Zewnętrznym Hoście

Teraz możesz używać kroków script lub zadania Docker@2 do interakcji z Dockerem na hoście, na którym działa agent.


steps:
- script: |
    echo "Running on the external host: $(hostname)"
    docker pull yourregistry.com/your-app-image:latest
    docker stop my-app-container || true # Zatrzymaj stary kontener, jeśli istnieje
    docker rm my-app-container || true # Usuń stary kontener
    docker run -d --name my-app-container -p 8080:80 yourregistry.com/your-app-image:latest
  displayName: 'Deploy application container on external host'

# Alternatywnie, używając zadania Docker@2 (wymaga Docker Host Service Connection lub wykonania na agencie z dostępem do dockerd)
# - task: Docker@2
#   displayName: 'Run image on external host'
#   inputs:
#     command: 'run'
#     # dockerHostEndpoint: 'MyExternalDockerHostConnection' # Jeśli używasz Docker Host Service Connection
#     imageName: 'yourregistry.com/your-app-image:latest'
#     containerName: 'my-app-container'
#     ports: '8080:80'
#     # ... inne argumenty 'run'

W tym scenariuszu potok najpierw buduje i wypycha obraz do rejestru (w poprzednim etapie lub zadaniu, zazwyczaj na agencie hostowanym przez Microsoft), a następnie zadanie uruchamiane na agencie self-hosted pobiera najnowszy obraz i uruchamia go na zewnętrznym hoście.

Diagram architektury DevOps w środowisku hybrydowym

Architektura CI/CD w środowisku hybrydowym z agentami self-hosted.


Wizualizacja Procesu i Komponentów

Mapa Myśli: Kluczowe Elementy Konfiguracji

Poniższa mapa myśli ilustruje główne komponenty i zależności podczas konfiguracji potoku Azure DevOps do pracy z Dockerem na zewnętrznym hoście.

mindmap root["Pipeline Azure DevOps z Dockerem na Zewnętrznym Hoście"] id1["Definicja Pipeline (YAML)"] id1_1["pool: (Wybór Agenta)"] id1_1_1["Microsoft-Hosted (dla zadań w kontenerze)"] id1_1_2["Self-Hosted (na zewnętrznym hoście)"] id1_2["resources: containers: (Definicja Obrazu)"] id1_2_1["Alias kontenera"] id1_2_2["Typ rejestru (ACR, Docker Hub, etc.)"] id1_2_3["Endpoint (Service Connection)"] id1_2_4["Nazwa obrazu i tag"] id1_3["jobs: / steps: (Kroki Wykonawcze)"] id1_3_1["container: (Uruchomienie zadania w kontenerze)"] id1_3_2["script: (Polecenia shell, np. docker run)"] id1_3_3["task: Docker@2 (Zadania Docker)"] id1_3_3_1["buildAndPush"] id1_3_3_2["run"] id1_3_3_3["login/logout"] id2["Konfiguracja Zewnętrzna"] id2_1["Zewnętrzny Host Docker"] id2_1_1["Instalacja Docker Engine"] id2_1_2["Konfiguracja Sieci/Firewall"] id2_1_3["(Opcjonalnie) Instalacja Agenta Self-Hosted"] id2_1_3_1["Bezpośrednio na hoście"] id2_1_3_2["W kontenerze Docker"] id2_2["Rejestr Kontenerów"] id2_2_1["Azure Container Registry (ACR)"] id2_2_2["Docker Hub (Publiczny/Prywatny)"] id2_2_3["Inny Prywatny Rejestr"] id3["Połączenia Usług (Service Connections)"] id3_1["Docker Registry Connection"] id3_1_1["Do ACR"] id3_1_2["Do Docker Hub"] id3_1_3["Do Innych Rejestrów"] id3_2["(Rzadziej) Docker Host Connection"] id3_2_1["Wymaga konfiguracji TLS"] id3_2_2["Alternatywa: Agent Self-Hosted"]

Porównanie Podejść (Radar Chart)

Ten wykres radarowy porównuje dwa główne podejścia ("Zadanie w Kontenerze" vs "Agent Self-Hosted") pod względem kilku kluczowych czynników. Wyższe wartości oznaczają generalnie lepsze dopasowanie do danego kryterium (skala 1-5, gdzie 1=Niska, 5=Wysoka).

Interpretacja: Podejście z agentem self-hosted daje znacznie większą kontrolę nad docelowym hostem i ułatwia lokalne debugowanie, ale może być nieco bardziej złożone w konfiguracji i wymaga starannego zarządzania bezpieczeństwem (zwłaszcza przy montowaniu gniazda Docker). Podejście z zadaniem w kontenerze jest prostsze w konfiguracji dla samego środowiska wykonawczego zadania i oferuje dużą elastyczność środowiska, ale ma ograniczoną kontrolę nad samym hostem agenta.


Przykład Kompletnego Potoku (Build, Push, Deploy)

Poniższy przykład YAML łączy budowanie obrazu, wypychanie go do Azure Container Registry (ACR) i wdrażanie na zewnętrznym hoście za pomocą agenta self-hosted.


trigger:
- main

variables:
  # Połączenie usługi do Twojego ACR
  dockerRegistryServiceConnection: 'YourACRServiceConnectionName'
  # Nazwa Twojego ACR
  containerRegistry: 'youracrname.azurecr.io'
  # Nazwa repozytorium obrazu w ACR
  imageRepository: 'my-app-image'
  # Ścieżka do Dockerfile
  dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile'
  # Tag obrazu (używamy ID buildu dla unikalności)
  tag: '$(Build.BuildId)'
  # Nazwa puli z agentem self-hosted na zewnętrznym hoście
  externalHostAgentPool: 'YourSelfHostedAgentPoolName'
  # Nazwa kontenera na zewnętrznym hoście
  containerName: 'my-live-app'

stages:
- stage: BuildAndPush
  displayName: 'Build and Push Image'
  jobs:
  - job: Build
    displayName: 'Build and Push to ACR'
    pool:
      vmImage: 'ubuntu-latest' # Użyj agenta hostowanego przez Microsoft do budowania
    steps:
    - task: Docker@2
      displayName: 'Login to ACR'
      inputs:
        command: 'login'
        containerRegistry: $(dockerRegistryServiceConnection)

    - task: Docker@2
      displayName: 'Build and Push image'
      inputs:
        command: 'buildAndPush'
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)
          latest

    - task: Docker@2
      displayName: 'Logout from ACR'
      inputs:
        command: 'logout'
        containerRegistry: $(dockerRegistryServiceConnection)

- stage: DeployToExternalHost
  displayName: 'Deploy to External Host'
  dependsOn: BuildAndPush # Uruchom ten etap po zakończeniu BuildAndPush
  jobs:
  - job: Deploy
    displayName: 'Deploy Container on External Host'
    pool:
      name: $(externalHostAgentPool) # Użyj agenta self-hosted
    steps:
    - script: |
        echo "Deploying image $(containerRegistry)/$(imageRepository):$(tag) on host $(hostname)"

        # Zaloguj się do ACR (jeśli agent nie ma stałych poświadczeń)
        # Możesz użyć <code>docker login z poświadczeniami z Key Vault lub Service Connection
        # Przykład: docker login $(containerRegistry) -u $(ACR_USER) -p $(ACR_PASSWORD)
        # Gdzie ACR_USER i ACR_PASSWORD są zmiennymi tajnymi

        docker pull $(containerRegistry)/$(imageRepository):$(tag)

        echo "Stopping and removing existing container..."
        docker stop $(containerName) || true
        docker rm $(containerName) || true

        echo "Starting new container..."
        docker run -d --name $(containerName) \
          -p 80:80 \
          --restart always \
          $(containerRegistry)/$(imageRepository):$(tag)

        echo "Deployment complete."
      displayName: 'Pull and Run Docker Container'
      # env: # Przykład przekazania zmiennych tajnych
      #   ACR_USER: $(ACRUsernameFromSecretVariable)
      #   ACR_PASSWORD: $(ACRPasswordFromSecretVariable)

  

Wideo: Wdrożenie Aplikacji .NET z Dockerem na Azure

Chociaż ten film koncentruje się na wdrażaniu na Azure App Service, demonstruje kluczowe etapy tworzenia potoku CI/CD w Azure DevOps do budowania obrazu Docker i jego publikacji, co jest fundamentalnym elementem procesu opisanego powyżej.

Ten przewodnik wideo pokazuje krok po kroku, jak wdrożyć aplikację .NET Web App za pomocą Dockera na Azure, w tym konfigurację potoku DevOps.


Podsumowanie Kluczowych Komponentów

Poniższa tabela podsumowuje najważniejsze elementy używane podczas konfiguracji potoków Azure DevOps z Dockerem na zewnętrznych hostach.

Komponent Opis Kiedy Używać Przykładowe Użycie w YAML
Połączenie Usługi (Service Connection) - Docker Registry Umożliwia bezpieczne uwierzytelnienie i połączenie z rejestrami kontenerów (ACR, Docker Hub, inne). Do pobierania (pull) i wypychania (push) obrazów z/do prywatnych rejestrów. endpoint: 'MyDockerRegistryConnection' (w definicji kontenera) lub containerRegistry: 'MyDockerRegistryConnection' (w zadaniu Docker@2).
Połączenie Usługi (Service Connection) - Docker Host Umożliwia bezpośrednie połączenie z demonem Docker na zdalnym hoście (wymaga konfiguracji TLS). Rzadziej używane; alternatywą jest agent self-hosted. Do wykonywania poleceń Docker na zdalnym hoście bez agenta. dockerHostEndpoint: 'MyExternalDockerHostConnection' (w zadaniu Docker@2).
Agent Microsoft-Hosted Agenci zarządzani przez Microsoft, dostępni w chmurze Azure DevOps. Do zadań budowania, testowania, wypychania obrazów, gdy nie jest wymagany dostęp do specyficznej infrastruktury zewnętrznej. Używany często z podejściem "Zadanie w Kontenerze". pool: vmImage: 'ubuntu-latest' (lub inne obrazy).
Agent Self-Hosted Agent instalowany i zarządzany przez użytkownika na własnej infrastrukturze (fizycznej, wirtualnej, w kontenerze). Gdy potok wymaga dostępu do zasobów lokalnych, specyficznego oprogramowania na hoście lub bezpośredniego wykonywania poleceń na zewnętrznym hoście Docker. Kluczowy dla podejścia "Wdrożenie na Zewnętrznym Hoście". pool: name: 'MySelfHostedPoolName'.
YAML: resources: containers: Definiuje alias, obraz i połączenie dla kontenera, który będzie używany do uruchamiania zadań. W podejściu "Zadanie w Kontenerze". resources: containers: - container: myalias ...
YAML: job: container: Określa, że kroki danego zadania (job) mają być wykonane wewnątrz zdefiniowanego kontenera. W podejściu "Zadanie w Kontenerze". jobs: - job: MyJob container: myalias steps: ...
Zadanie Docker@2 Wbudowane zadanie Azure DevOps do wykonywania typowych operacji Docker (build, push, run, login, logout). Do standaryzacji operacji Docker w potoku. Może działać na agentach hostowanych i self-hosted. - task: Docker@2 inputs: command: 'buildAndPush' ...
Krok script: Umożliwia wykonywanie dowolnych poleceń powłoki (bash, PowerShell, cmd). Do elastycznego wykonywania poleceń, w tym docker pull, docker run, docker compose itp., zwłaszcza na agentach self-hosted. - script: 'docker run hello-world'

Najlepsze Praktyki i Uwagi

  • Bezpieczeństwo: Zawsze używaj połączeń usług do zarządzania poświadczeniami. Unikaj umieszczania haseł i tokenów bezpośrednio w pliku YAML. Rozważ użycie Azure Key Vault do przechowywania sekretów. Zabezpiecz dostęp do demona Docker na zewnętrznym hoście za pomocą TLS, jeśli łączysz się zdalnie bez agenta.
  • Zarządzanie Agentami Self-Hosted: Regularnie aktualizuj agentów self-hosted. Monitoruj ich stan i zasoby (CPU, pamięć, dysk). Rozważ uruchamianie agentów w kontenerach dla lepszej izolacji i zarządzania.
  • Sieć: Upewnij się, że agent (hostowany lub self-hosted) ma dostęp sieciowy do rejestru kontenerów. Jeśli używasz agenta self-hosted na zewnętrznym hoście, upewnij się, że może on komunikować się z usługą Azure DevOps (wymagane porty i adresy URL są w dokumentacji Microsoft). Skonfiguruj firewalle odpowiednio.
  • Idempotentność: Projektuj kroki wdrożenia tak, aby były idempotentne – wielokrotne uruchomienie tego samego kroku powinno dawać ten sam rezultat (np. używaj docker stop i docker rm przed docker run).
  • Docker Compose: Jeśli Twoja aplikacja składa się z wielu kontenerów, możesz użyć docker-compose na agencie self-hosted. Wykonaj polecenia docker-compose pull, docker-compose up -d itp. w kroku script.

Często Zadawane Pytania (FAQ)

Co to jest Połączenie Usługi (Service Connection) w Azure DevOps?

Kiedy powinienem użyć agenta self-hosted zamiast agenta hostowanego przez Microsoft?

Jak zabezpieczyć połączenie z moim zewnętrznym hostem Docker?

Czy mogę używać Docker Compose w potoku Azure DevOps na zewnętrznym hoście?

Co zrobić, jeśli mój zewnętrzny host jest za firewallem?


Rekomendowane Zapytania


Referencje


Last updated May 4, 2025
Ask Ithy AI
Download Article
Delete Article