CD ja GHCR — Labor
Kestus: 4 tundi
Eeldused: Loeng antud (CI vs CD, register, tagid). Nädal 5 repo (Flask + Dockerfile) + nädal 7 pipeline (.github/workflows/ci.yml roheline). Kui udu — tagasi loengusse.
Keskkond: kood VS Code'is, pipeline GitHubi runneris. Serveri-samm (Osa 6): sinu sihtmärk (kodus valitud, koolis Proxmox).
Õpiväljundid
Selle labi lõpuks sa:
- Laiendad nädal 7 pipeline'i
build-and-pushjob'iga - Diagnoosid
403 permission_deniedja parandadpermissions-iga - Leiad ehitatud image'i GHCR-ist (Packages) kahe tagiga
- Tõmbad image'i serverisse ja käivitad — ring sulgub
- Selgitad miks build jookseb ainult
main-il, mitte PR-idel
Labi loogika: baas (CI) → laienda → viga (403) → paranda → laienda (server) → taasta. Ehitad CD osa nädal 7 pipeline'i otsa, tekitad õigustevea ise, sulged ringi serverini. Fragmendid, mitte terve fail (kontrolliks terve fail on Osa 3 lõpus kollapsi taga).
Osa 1 · Eeltöö — CI roheline, image ehitub
Ava repo VS Code'is (code .). Kontrolli et nädal 7 CI on roheline (Actions tab) ja Dockerfile ehitub lokaalselt:
http://localhost:5000 vastab? Koristus:
Kui Dockerfile on alamkaustas (nt app/), pane kirja — läheb hiljem context: väärtuseks.
Tip
Kui image lokaalselt ei ehitu, lahenda enne. CD ei saa ehitada seda, mis su masinaski katki. (Meenuta: "works on my machine" — kui isegi su masinas ei tööta, on lugu hull.)
Osa 2 · Trigger + build job ilma õigusteta
Ava .github/workflows/ci.yml. Lisa main-push trigger (fragment, on: alla):
Lisa build-and-push job olemasoleva test job'i järele, jobs: all samal tasemel — teadlikult ilma permissions blokita (tekitame vea):
build-and-push:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:${{ github.sha }}
ghcr.io/${{ github.repository }} — automaatne, kujul kasutaja/repo. Sa ei kirjuta oma nime kuhugi. needs: test = build ainult pärast roheliseid teste. if: main = ainult main-il.
Commit ja push otse main-i (täna erand, et CD käivituks):
Osa 3 · Viga — 403 permission_denied
Actions tab — test roheline, build-and-push punane. Ava build-and-push → build-push samm. Veateade: denied: permission_denied või 403.
Diagnoosi enne kui parandad
Workflow saab vaikimisi koodi ainult lugeda. GHCR on pakett — sinna kirjutamiseks on vaja luba, mida sa ei andnud. Mis blokk annab workflow'ile kirjutusõiguse pakettidesse?
Paranda — lisa permissions blokk workflow tasandil (pärast on:, enne jobs:):
Kontrolli ka repo seadeid: Settings → Actions → General → Workflow permissions → Read and write permissions.
Push uuesti:
Nüüd build-and-push roheline.
Terve fail kontrolliks (ava kui tahad võrrelda)
name: CI/CD
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
packages: write
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install -r requirements.txt
- run: pytest
build-and-push:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:${{ github.sha }}
test job oma rakendusele (Python versioon, test-käsk).
Osa 4 · Kontrolli GHCR-i
Repo pealehel paremal → Packages. Näed oma image'it (repo nimega). Kliki → näed tage: latest ja commit hash.
Mõtle
Miks on kasulik, et sama image on korraga tagitud nii latest kui commit hash'iga? Kumba kasutaks server tootmises ja miks?
Osa 5 · Viga — PR ei tohi buildida
Kontrolli et if: main päriselt kaitseb. Loo haru, muuda midagi, ava PR:
git switch -c test-pr
echo "# test" >> README.md
git add README.md && git commit -m "test: pr ei tohi buildida"
git push -u origin test-pr
Ava PR GitHubis. Actions tab — PR-il jookseb ainult test, build-and-push on skipped (hall).
Diagnoosi
Miks build-and-push PR-il ei jooksnud? Mis rida job'is selle otsustas? Mis juhtuks, kui selle rea eemaldaksid — ja miks annaks see PR-il vea?
Sulge PR (või merge, kui tahad). Naase main-ile:
Osa 6 · Ring sulgub — server pull + run
Image on GHCR-is. Nüüd server tõmbab selle. Serveriks on sinu sihtmärk — kodus valitud (vt Töökeskkond), koolis Proxmox. Ühenda:
GHCR-ist tõmbamiseks logi serveril sisse (vajab GitHub Personal Access Tokenit read:packages õigusega — GitHub → Settings → Developer Settings → Personal access tokens → Tokens (classic)):
Tõmba ja käivita:
docker pull ghcr.io/<sinu-github-nimi>/<repo>:latest
docker run -d -p 5000:5000 ghcr.io/<sinu-github-nimi>/<repo>:latest
curl http://localhost:5000
Rakenduse vastus tuleb — kood GitHubis → CI testis → CD ehitas ja pushis → server käivitas. Sina ei puutunud serverit koodiga, ainult käivitasid valmis paki.
Mõtle
Nädal 13 automatiseerime ka selle viimase sammu (server tõmbab ise). Praegu tegid pull + run käsitsi. Mis on risk, kui see samm jääb igaveseks käsitsi — kes selle reedel õhtul unustab?
Osa 7 · Taasta
Serveril koristus:
Lokaalselt: kustuta test-pr haru kui tegid.
Lõppkontroll — oskad ilma juhendita
-
.github/workflows/ci.ymlsisaldabtest+build-and-pushjob'i -
permissions: packages: writeon olemas -
403nägemisel tead kohe kust luba tuleb - Image GHCR-is kahe tagiga (
latest+ hash) -
build-and-pushjooksebmain-il, on skipped PR-il - Image käivitub serveril,
curlannab vastuse - Selgitad
needs: testjaif: mainrolli
Lisaülesanded (kui jõuad ette)
Trivy — haavatavuse skanner. Lisa build'i järele:
- uses: aquasecurity/trivy-action@master
with:
image-ref: ghcr.io/${{ github.repository }}:${{ github.sha }}
format: table
exit-code: 1
severity: CRITICAL
exit-code: 1 = CRITICAL haavatavus katab pipeline'i. Testimiseks pane ajutiselt FROM python:3.6-slim (vana, haavatav) — pipeline peaks katkema. Siis taasta.
Veaotsing
| Veateade | Põhjus | Lahendus |
|---|---|---|
denied: permission_denied / 403 |
packages: write puudub |
Lisa permissions blokk + repo seaded |
failed to read dockerfile |
Dockerfile vales kohas | Kontrolli context: |
unauthorized |
Login samm kukkus | registry: ghcr.io täpselt, username: ${{ github.actor }} |
| Image ehitatakse enne teste | needs: puudub |
needs: test build job'ile |
build-and-push jookseb PR-il |
if: puudub |
if: github.ref == 'refs/heads/main' |
Server pull → unauthorized |
Serveril pole GHCR login'i | docker login ghcr.io tokeniga |
Tabel 8.1. Iga rida on viga, mille sa selles labis ise tekitasid või kohtad.
Allikad
| Allikas | URL | Miks |
|---|---|---|
| GHCR | https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry | Register |
| build-push-action | https://github.com/docker/build-push-action | Build + push |
| login-action | https://github.com/docker/login-action | GHCR login |
| GITHUB_TOKEN | https://docs.github.com/en/actions/security-guides/automatic-token-authentication | Automaatne token |
| Trivy action | https://github.com/aquasecurity/trivy-action | Haavatavuse skann |