exercises: ex16-19 hinzugefügt, commands.sh → commands.txt
- 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 <noreply@anthropic.com>
This commit is contained in:
parent
5ad7435542
commit
b32d8c2472
12 changed files with 132 additions and 8 deletions
1
listings/exercises/ex05-networking/commands.sh → listings/exercises/ex05-networking/commands.txt
Executable file → Normal file
1
listings/exercises/ex05-networking/commands.sh → listings/exercises/ex05-networking/commands.txt
Executable file → Normal file
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/bash
|
|
||||||
# Exercise 5 — Container Networking
|
# Exercise 5 — Container Networking
|
||||||
|
|
||||||
podman network create appnet
|
podman network create appnet
|
||||||
1
listings/exercises/ex06-bind-mount/commands.sh → listings/exercises/ex06-bind-mount/commands.txt
Executable file → Normal file
1
listings/exercises/ex06-bind-mount/commands.sh → listings/exercises/ex06-bind-mount/commands.txt
Executable file → Normal file
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/bash
|
|
||||||
# Exercise 6 — Bind Mounts
|
# Exercise 6 — Bind Mounts
|
||||||
|
|
||||||
# Terminal 1: write dates to /tmp/output (detached)
|
# Terminal 1: write dates to /tmp/output (detached)
|
||||||
1
listings/exercises/ex07-named-volume/commands.sh → listings/exercises/ex07-named-volume/commands.txt
Executable file → Normal file
1
listings/exercises/ex07-named-volume/commands.sh → listings/exercises/ex07-named-volume/commands.txt
Executable file → Normal file
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/bash
|
|
||||||
# Exercise 7 — Named Volumes (shared between containers)
|
# Exercise 7 — Named Volumes (shared between containers)
|
||||||
|
|
||||||
podman volume create pizza
|
podman volume create pizza
|
||||||
1
listings/exercises/ex08-persistence/commands.sh → listings/exercises/ex08-persistence/commands.txt
Executable file → Normal file
1
listings/exercises/ex08-persistence/commands.sh → listings/exercises/ex08-persistence/commands.txt
Executable file → Normal file
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/bash
|
|
||||||
# Exercise 8 — Volume Persistence (data survives container removal)
|
# Exercise 8 — Volume Persistence (data survives container removal)
|
||||||
|
|
||||||
podman volume create pasta
|
podman volume create pasta
|
||||||
1
listings/exercises/ex09-env-variables/commands.sh → listings/exercises/ex09-env-variables/commands.txt
Executable file → Normal file
1
listings/exercises/ex09-env-variables/commands.sh → listings/exercises/ex09-env-variables/commands.txt
Executable file → Normal file
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/bash
|
|
||||||
# Exercise 9 — Environment Variables
|
# Exercise 9 — Environment Variables
|
||||||
|
|
||||||
# Single variables via -e
|
# Single variables via -e
|
||||||
1
listings/exercises/ex13-multistage/commands.sh → listings/exercises/ex13-multistage/commands.txt
Executable file → Normal file
1
listings/exercises/ex13-multistage/commands.sh → listings/exercises/ex13-multistage/commands.txt
Executable file → Normal file
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/bash
|
|
||||||
# Exercise 13 — Multi-stage Build
|
# Exercise 13 — Multi-stage Build
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
1
listings/exercises/ex14-push/commands.sh → listings/exercises/ex14-push/commands.txt
Executable file → Normal file
1
listings/exercises/ex14-push/commands.sh → listings/exercises/ex14-push/commands.txt
Executable file → Normal file
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/bash
|
|
||||||
# Exercise 14 — Push image to local registry
|
# Exercise 14 — Push image to local registry
|
||||||
|
|
||||||
# Tag and push
|
# Tag and push
|
||||||
1
listings/exercises/ex15-registry-api/commands.sh → listings/exercises/ex15-registry-api/commands.txt
Executable file → Normal file
1
listings/exercises/ex15-registry-api/commands.sh → listings/exercises/ex15-registry-api/commands.txt
Executable file → Normal file
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/bash
|
|
||||||
# Exercise 15 — Query the local registry API
|
# Exercise 15 — Query the local registry API
|
||||||
|
|
||||||
# List all repositories in the registry
|
# List all repositories in the registry
|
||||||
19
listings/exercises/ex16-local-registry/commands.txt
Normal file
19
listings/exercises/ex16-local-registry/commands.txt
Normal file
|
|
@ -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"]}
|
||||||
18
listings/exercises/ex17-update-cycle/commands.txt
Normal file
18
listings/exercises/ex17-update-cycle/commands.txt
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Exercise 17 — Full update cycle (edit → build → push → restart)
|
||||||
|
|
||||||
|
# 1. Change the page title in main.go
|
||||||
|
sed -i 's|<h1>VisitCounter</h1>|<h1>My Counter</h1>|' \
|
||||||
|
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
|
||||||
31
listings/exercises/ex18-quadlets/commands.txt
Normal file
31
listings/exercises/ex18-quadlets/commands.txt
Normal file
|
|
@ -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
|
||||||
64
listings/exercises/ex19-harden/commands.txt
Normal file
64
listings/exercises/ex19-harden/commands.txt
Normal file
|
|
@ -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
|
||||||
Loading…
Add table
Reference in a new issue