From b32d8c2472337e096b023e90e62e348ad76191f8 Mon Sep 17 00:00:00 2001 From: Frank Engel Date: Thu, 21 May 2026 09:09:51 +0200 Subject: [PATCH] =?UTF-8?q?exercises:=20ex16-19=20hinzugef=C3=BCgt,=20comm?= =?UTF-8?q?ands.sh=20=E2=86=92=20commands.txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ex16: lokale Registry + VisitCounter pushen - ex17: vollständiger Update-Zyklus (edit → build → push → restart) - ex18: VisitCounter mit Quadlets deployen - ex19: Container schrittweise härten (read-only, cap-drop, no-new-priv) - alle commands.sh umbenannt in commands.txt, Shebang entfernt Co-Authored-By: Claude Sonnet 4.6 --- .../{commands.sh => commands.txt} | 1 - .../{commands.sh => commands.txt} | 1 - .../{commands.sh => commands.txt} | 1 - .../{commands.sh => commands.txt} | 1 - .../{commands.sh => commands.txt} | 1 - .../{commands.sh => commands.txt} | 1 - .../ex14-push/{commands.sh => commands.txt} | 1 - .../{commands.sh => commands.txt} | 1 - .../ex16-local-registry/commands.txt | 19 ++++++ .../exercises/ex17-update-cycle/commands.txt | 18 ++++++ listings/exercises/ex18-quadlets/commands.txt | 31 +++++++++ listings/exercises/ex19-harden/commands.txt | 64 +++++++++++++++++++ 12 files changed, 132 insertions(+), 8 deletions(-) rename listings/exercises/ex05-networking/{commands.sh => commands.txt} (97%) mode change 100755 => 100644 rename listings/exercises/ex06-bind-mount/{commands.sh => commands.txt} (97%) mode change 100755 => 100644 rename listings/exercises/ex07-named-volume/{commands.sh => commands.txt} (97%) mode change 100755 => 100644 rename listings/exercises/ex08-persistence/{commands.sh => commands.txt} (97%) mode change 100755 => 100644 rename listings/exercises/ex09-env-variables/{commands.sh => commands.txt} (97%) mode change 100755 => 100644 rename listings/exercises/ex13-multistage/{commands.sh => commands.txt} (93%) mode change 100755 => 100644 rename listings/exercises/ex14-push/{commands.sh => commands.txt} (96%) mode change 100755 => 100644 rename listings/exercises/ex15-registry-api/{commands.sh => commands.txt} (96%) mode change 100755 => 100644 create mode 100644 listings/exercises/ex16-local-registry/commands.txt create mode 100644 listings/exercises/ex17-update-cycle/commands.txt create mode 100644 listings/exercises/ex18-quadlets/commands.txt create mode 100644 listings/exercises/ex19-harden/commands.txt diff --git a/listings/exercises/ex05-networking/commands.sh b/listings/exercises/ex05-networking/commands.txt old mode 100755 new mode 100644 similarity index 97% rename from listings/exercises/ex05-networking/commands.sh rename to listings/exercises/ex05-networking/commands.txt index 303f210..9c24c00 --- a/listings/exercises/ex05-networking/commands.sh +++ b/listings/exercises/ex05-networking/commands.txt @@ -1,4 +1,3 @@ -#!/bin/bash # Exercise 5 — Container Networking podman network create appnet diff --git a/listings/exercises/ex06-bind-mount/commands.sh b/listings/exercises/ex06-bind-mount/commands.txt old mode 100755 new mode 100644 similarity index 97% rename from listings/exercises/ex06-bind-mount/commands.sh rename to listings/exercises/ex06-bind-mount/commands.txt index 39954b4..d42b409 --- a/listings/exercises/ex06-bind-mount/commands.sh +++ b/listings/exercises/ex06-bind-mount/commands.txt @@ -1,4 +1,3 @@ -#!/bin/bash # Exercise 6 — Bind Mounts # Terminal 1: write dates to /tmp/output (detached) diff --git a/listings/exercises/ex07-named-volume/commands.sh b/listings/exercises/ex07-named-volume/commands.txt old mode 100755 new mode 100644 similarity index 97% rename from listings/exercises/ex07-named-volume/commands.sh rename to listings/exercises/ex07-named-volume/commands.txt index c637232..3fadbb2 --- a/listings/exercises/ex07-named-volume/commands.sh +++ b/listings/exercises/ex07-named-volume/commands.txt @@ -1,4 +1,3 @@ -#!/bin/bash # Exercise 7 — Named Volumes (shared between containers) podman volume create pizza diff --git a/listings/exercises/ex08-persistence/commands.sh b/listings/exercises/ex08-persistence/commands.txt old mode 100755 new mode 100644 similarity index 97% rename from listings/exercises/ex08-persistence/commands.sh rename to listings/exercises/ex08-persistence/commands.txt index 9a06c55..7ef4609 --- a/listings/exercises/ex08-persistence/commands.sh +++ b/listings/exercises/ex08-persistence/commands.txt @@ -1,4 +1,3 @@ -#!/bin/bash # Exercise 8 — Volume Persistence (data survives container removal) podman volume create pasta diff --git a/listings/exercises/ex09-env-variables/commands.sh b/listings/exercises/ex09-env-variables/commands.txt old mode 100755 new mode 100644 similarity index 97% rename from listings/exercises/ex09-env-variables/commands.sh rename to listings/exercises/ex09-env-variables/commands.txt index 835bac7..fa90f77 --- a/listings/exercises/ex09-env-variables/commands.sh +++ b/listings/exercises/ex09-env-variables/commands.txt @@ -1,4 +1,3 @@ -#!/bin/bash # Exercise 9 — Environment Variables # Single variables via -e diff --git a/listings/exercises/ex13-multistage/commands.sh b/listings/exercises/ex13-multistage/commands.txt old mode 100755 new mode 100644 similarity index 93% rename from listings/exercises/ex13-multistage/commands.sh rename to listings/exercises/ex13-multistage/commands.txt index d72e272..8dfe0b4 --- a/listings/exercises/ex13-multistage/commands.sh +++ b/listings/exercises/ex13-multistage/commands.txt @@ -1,4 +1,3 @@ -#!/bin/bash # Exercise 13 — Multi-stage Build # Build diff --git a/listings/exercises/ex14-push/commands.sh b/listings/exercises/ex14-push/commands.txt old mode 100755 new mode 100644 similarity index 96% rename from listings/exercises/ex14-push/commands.sh rename to listings/exercises/ex14-push/commands.txt index 478bab0..47a44c7 --- a/listings/exercises/ex14-push/commands.sh +++ b/listings/exercises/ex14-push/commands.txt @@ -1,4 +1,3 @@ -#!/bin/bash # Exercise 14 — Push image to local registry # Tag and push diff --git a/listings/exercises/ex15-registry-api/commands.sh b/listings/exercises/ex15-registry-api/commands.txt old mode 100755 new mode 100644 similarity index 96% rename from listings/exercises/ex15-registry-api/commands.sh rename to listings/exercises/ex15-registry-api/commands.txt index 78c27d0..b1c7119 --- a/listings/exercises/ex15-registry-api/commands.sh +++ b/listings/exercises/ex15-registry-api/commands.txt @@ -1,4 +1,3 @@ -#!/bin/bash # Exercise 15 — Query the local registry API # List all repositories in the registry diff --git a/listings/exercises/ex16-local-registry/commands.txt b/listings/exercises/ex16-local-registry/commands.txt new file mode 100644 index 0000000..bd77409 --- /dev/null +++ b/listings/exercises/ex16-local-registry/commands.txt @@ -0,0 +1,19 @@ +# Exercise 16 — Start a local registry and push the VisitCounter + +# Start the registry container +podman run -d --name local-registry -p 5000:5000 registry:2 + +# Build the VisitCounter image +cd listings/visitcounter/app +podman build -t localhost:5000/visitcounter:latest . + +# Push to the local registry +podman push --tls-verify=false localhost:5000/visitcounter:latest + +# Verify: list all repositories +curl http://localhost:5000/v2/_catalog +# → {"repositories":["visitcounter"]} + +# Verify: list tags +curl http://localhost:5000/v2/visitcounter/tags/list +# → {"name":"visitcounter","tags":["latest"]} diff --git a/listings/exercises/ex17-update-cycle/commands.txt b/listings/exercises/ex17-update-cycle/commands.txt new file mode 100644 index 0000000..43e76b2 --- /dev/null +++ b/listings/exercises/ex17-update-cycle/commands.txt @@ -0,0 +1,18 @@ +# Exercise 17 — Full update cycle (edit → build → push → restart) + +# 1. Change the page title in main.go +sed -i 's|

VisitCounter

|

My Counter

|' \ + listings/visitcounter/app/main.go + +# 2. Rebuild +cd listings/visitcounter/app +podman build -t localhost:5000/visitcounter:latest . + +# 3. Push +podman push --tls-verify=false localhost:5000/visitcounter:latest + +# 4. Restart the Quadlet service +systemctl --user restart visitcounter-app.service + +# 5. Verify — new title should appear +curl localhost:8080 diff --git a/listings/exercises/ex18-quadlets/commands.txt b/listings/exercises/ex18-quadlets/commands.txt new file mode 100644 index 0000000..40d72c5 --- /dev/null +++ b/listings/exercises/ex18-quadlets/commands.txt @@ -0,0 +1,31 @@ +# Exercise 18 — Deploy VisitCounter via Quadlets + +# Create the Quadlet directory +mkdir -p ~/.config/containers/systemd/ + +# Copy all Quadlet unit files +cp listings/visitcounter/quadlets/* ~/.config/containers/systemd/ + +# Reload systemd to pick up the new units +systemctl --user daemon-reload + +# Check that units were generated +systemctl --user list-unit-files | grep visitcounter +# → visitcounter-app.service generated +# → visitcounter-db.service generated +# → visitcounter-proxy.service generated + +# Start only the proxy — systemd resolves After= dependencies automatically +systemctl --user start visitcounter-proxy.service + +# Verify all three services are running +systemctl --user status visitcounter-db.service +systemctl --user status visitcounter-app.service +systemctl --user status visitcounter-proxy.service + +# Test +curl localhost:8080 + +# Bonus: kill the app container and watch systemd restart it +podman stop systemd-visitcounter-app +systemctl --user status visitcounter-app.service diff --git a/listings/exercises/ex19-harden/commands.txt b/listings/exercises/ex19-harden/commands.txt new file mode 100644 index 0000000..5935680 --- /dev/null +++ b/listings/exercises/ex19-harden/commands.txt @@ -0,0 +1,64 @@ +# Exercise 19 — Harden a container step by step + +# Baseline — works fine +podman run -d --name insecure -p 8080:80 nginx:1.27 +curl localhost:8080 +podman rm -f insecure + +# Step 1: read-only filesystem +podman run -d --name step1 -p 8080:80 --read-only nginx:1.27 +podman logs step1 +# → fails: mkdir /var/cache/nginx/client_temp: Read-only file system +podman rm -f step1 + +podman run -d --name step1 -p 8080:80 \ + --read-only \ + --tmpfs /var/cache/nginx \ + --tmpfs /var/run \ + nginx:1.27 +curl localhost:8080 +podman rm -f step1 + +# Step 2: no-new-privileges +podman run -d --name step2 -p 8080:80 \ + --read-only \ + --tmpfs /var/cache/nginx \ + --tmpfs /var/run \ + --security-opt no-new-privileges \ + nginx:1.27 +curl localhost:8080 +podman rm -f step2 + +# Step 3: drop all capabilities +podman run -d --name step3 -p 8080:80 \ + --read-only \ + --tmpfs /var/cache/nginx \ + --tmpfs /var/run \ + --security-opt no-new-privileges \ + --cap-drop ALL \ + nginx:1.27 +podman logs step3 +# → fails: bind() to 0.0.0.0:80 failed (13: Permission denied) +podman rm -f step3 + +# Step 4: add back only what nginx needs +podman run -d --name secure -p 8080:80 \ + --read-only \ + --tmpfs /var/cache/nginx \ + --tmpfs /var/run \ + --security-opt no-new-privileges \ + --cap-drop ALL \ + --cap-add CHOWN \ + --cap-add SETUID \ + --cap-add SETGID \ + --cap-add NET_BIND_SERVICE \ + nginx:1.27 + +curl localhost:8080 +# → 200 OK + +# Inspect the final capability set +podman inspect secure \ + --format 'Add: {{.HostConfig.CapAdd}} Drop: {{.HostConfig.CapDrop}}' + +podman rm -f secure