Hopp til innhold

Docker - Publisere container med workflow

Skip to content

Publisere et Docker-image med GitHub Actions

Her lager du en workflow som bygger Docker-imaget automatisk og publiserer det til GitHub Container Registry (GHCR).

Du skal vise en vellykket Actions-kjøring og finne imaget med riktig tagg under Packages. Å hente og kjøre imaget på en server er neste øvelse. Du trenger ikke DNS eller reverse proxy for å publisere et image.

GitHub Actions bygger et image fra kildekoden og publiserer det til GHCR. Å hente imaget og opprette en container på serveren er et eget utrullingssteg.

Workflowen her bygger og publiserer et image. Den oppdaterer ikke en kjørende container på serveren. Serveren må hente imaget og opprette containeren fra den ønskede versjonen i et eget steg, manuelt eller med separat automatisering.

Når workflowen er ferdig, skjer dette hver gang du pusher til en branch:

flowchart LR
    P[Push til branch] --> C[GitHub Actions<br/>henter kildekoden]
    C --> B[Docker bygger image<br/>fra Dockerfile]
    B --> R[Publiser til<br/>GitHub Container Registry]
    R --> T{Hvilken branch?}
    T -->|main eller master| L[Tagg: latest]
    T -->|andre brancher| E[Tagg: edge]

Info

I denne workflowen brukes edge for utvikling og testing, mens latest bygges fra main eller master. Dette er valg vi gjør her, ikke faste betydninger i Docker. Begge taggene kan flyttes til et nytt image; bruk en bestemt digest hvis du trenger nøyaktig samme bygg senere.

Før du begynner

Du må ha:

  • et GitHub-repository med en fungerende Dockerfile
  • en applikasjon som kan bygges uten lokale filer eller sensitiv informasjon
  • en GitHub-konto med tilgang til repositoryet

Kontroller først at docker build virker lokalt på VM-en, som vist i Bygg et image med Dockerfile. Kontroller også .dockerignore og Git-sporing før du deler imaget. Du må kunne lagre en fil i .github/workflows/, registrere endringen med Git og sende den til GitHub. Workflow-filer og tilgangstokener viser plassering, filopprettelse, kjøring og innstillingene for et personlig tilgangstoken. Hent oppskriften der hvis dette er nytt.

Workflowen bruker GITHUB_TOKEN. Du trenger derfor ikke lage et eget passord eller lagre en personlig access token i repositoryet.

Ny på CI/CD?

⚙️ CI/CD-introduksjonen i Automatisering-emnet viser konseptet med et enklere eksempel først.

Ny på Git i terminalen?

🌱 Git i terminalen viser de grunnleggende kommandoene før du lager en egen workflow-fil.

Ny på YAML?

📄 YAML forklarer nøkkel-verdi-par, lister og innrykk før du lager workflow-filen under.

Lag workflow-filen

Lag filen .github/workflows/publish-container.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
name: Publish container

on:
  # Bygg og publiser ved push til alle brancher.
  push:
  # Gjør det også mulig å starte workflowen manuelt.
  workflow_dispatch:

env:
  # GitHub Container Registry.
  REGISTRY: ghcr.io
  # Bygg imaget for både vanlige servere og ARM-enheter.
  PLATFORMS: linux/amd64,linux/arm64/v8

jobs:
  build-and-push:
    name: Build and publish
    runs-on: ubuntu-latest
    permissions:
      # Workflowen trenger å lese kildekoden og skrive til GHCR.
      contents: read
      packages: write

    steps:
      - name: Checkout repository
        # Henter kildekoden slik at workflowen kan bygge Dockerfile.
        uses: actions/checkout@v7

      - name: Set up QEMU
        # Gjør det mulig å bygge images for andre CPU-arkitekturer enn runneren.
        uses: docker/setup-qemu-action@v4

      - name: Set up Docker Buildx
        # Buildx støtter multi-platform builds og avansert caching.
        uses: docker/setup-buildx-action@v4

      - name: Set image name
        id: image
        # GITHUB_REPOSITORY er en innebygd GitHub-variabel med eier/repository.
        run: echo "name=${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT"

      - name: Log in to GitHub Container Registry
        # Bruker GitHub Actions-tokenet som allerede finnes i secrets.GITHUB_TOKEN.
        # Tokenet får skrive image til GHCR gjennom packages: write over.
        uses: docker/login-action@v4
        with:
          registry: ${{ env.REGISTRY }}
          # github.actor er brukeren eller boten som startet workflowen.
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract Docker metadata
        id: meta
        # Lager image-tags og labels basert på branch og repository.
        uses: docker/metadata-action@v6
        with:
          images: ${{ env.REGISTRY }}/${{ steps.image.outputs.name }}
          # main og master bruker produksjonstaggen (:latest).
          # Alle andre brancher bruker utviklingstaggen (:edge).
          tags: |
            type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' }}
            type=raw,value=edge,enable=${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/master' }}

      - name: Build and push image
        # Bygger Dockerfile, lager images for plattformene over og publiserer dem.
        uses: docker/build-push-action@v7
        with:
          context: .
          file: ./Dockerfile
          platforms: ${{ env.PLATFORMS }}
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          # Gjenbruk lag fra tidligere kjøringer for raskere bygging.
          cache-from: type=gha
          cache-to: type=gha,mode=max

OBS!

Workflowen bruker push og publiserer derfor et nytt image ved hver endring. I en mer kontrollert produksjonsflyt kan du heller starte publisering fra en GitHub Release. Her er publisering ved hver endring valgt for å gjøre flyten enkel.

Hvorfor bruke et containerregister?

Et containerregister er et sentralt lager for Docker-images. GitHub Container Registry (GHCR) er koblet til GitHub-repositoryet og gjør at både workflows og servere kan hente samme image.

Dette er nyttig fordi:

  • serveren trenger Docker Engine, men trenger ikke kildekoden eller å bygge imaget selv
  • samme image kan testes i ett miljø og kjøres i et annet
  • versjoner kan skilles med tagger som latest, edge eller en versjon
  • workflowen bygger imaget én gang, slik at miljøene kan bruke samme publiserte bygg
  • imaget kan deles mellom workflowen og serveren

Hvis workflowen kjører i repositoryet example-org/example-app, blir image-navnet:

ghcr.io/example-org/example-app:latest

Kontroller publiseringen

Push workflow-filen til den branchen du vil bygge. Åpne Actions, velg kjøringen og les det første steget som feiler hvis resultatet er rødt. Når kjøringen er grønn, åpner du pakken under Packages på eierens GitHub-side og finner taggen: latest fra main eller master, ellers edge.

Vis hvilken commit som utløste byggingen, den vellykkede kjøringen og det fulle image-navnet med tagg. Forklar hvorfor en grønn kjøring ikke betyr at en server er oppdatert. Ny GHCR-pakke er privat som standard; du må ha pakketilgang for å hente den fra serveren.

Problem Kontroller
Workflowen starter ikke Filplassering i .github/workflows/, gyldig YAML og at GitHub Actions er aktivert i repositoryet.
Byggingen feiler Første røde steg, Dockerfile og om prosjektet kan bygges lokalt.
Publiseringen gir tilgangsfeil packages: write, organisasjonens regler og at pakken tillater workflowens repository.
Feil tagg Hvilken branch som utløste kjøringen. latest og edge er bevisste valg i denne filen.

Neste steg

Fortsett med Kjør et image fra GHCR når imaget finnes i GHCR. Den øvelsen kontrollerer pakketilgang og oppdatering av en container på Linux-serveren.


Serverkommandoene står nå på Kjør et image fra GHCR.

Kilde: GitHub Container Registry: publisering og tilgang.