Tag 2 Materialien: Exercises ex05-ex15 + Ubuntu 24.04 Setup
- listings/exercises/ex05-ex15: alle Übungsdateien für Tag 2 (Networking, Bind Mounts, Volumes, Env Variables, Compose, Build, Push, Registry) - setup/setup-ubuntu2404.sh: Prep-Script für Ubuntu 24.04 (Noble) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e1e118bf4e
commit
bd046e626d
17 changed files with 341 additions and 0 deletions
19
listings/exercises/ex05-networking/commands.sh
Executable file
19
listings/exercises/ex05-networking/commands.sh
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
# Exercise 5 — Container Networking
|
||||
|
||||
podman network create appnet
|
||||
|
||||
podman run -d --name backend --network appnet nginx:1.27
|
||||
podman run -d --name frontend --network appnet -p 8080:80 nginx:1.27
|
||||
|
||||
podman network inspect appnet
|
||||
|
||||
# Container-to-container (DNS im appnet)
|
||||
podman exec -ti frontend curl backend
|
||||
|
||||
# Host-to-container (Port-Mapping)
|
||||
curl localhost:8080
|
||||
|
||||
# Cleanup
|
||||
podman rm -f frontend backend
|
||||
podman network rm appnet
|
||||
12
listings/exercises/ex06-bind-mount/commands.sh
Executable file
12
listings/exercises/ex06-bind-mount/commands.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
# Exercise 6 — Bind Mounts
|
||||
|
||||
# Terminal 1: write dates to /tmp/output
|
||||
podman run -v /tmp:/data --rm -ti busybox \
|
||||
sh -c 'while true; do sleep 1; date >> /data/output; done'
|
||||
|
||||
# Terminal 2: watch the output
|
||||
podman run -v /tmp:/data --rm busybox tail -f /data/output
|
||||
|
||||
# Cleanup
|
||||
rm -f /tmp/output
|
||||
14
listings/exercises/ex07-named-volume/commands.sh
Executable file
14
listings/exercises/ex07-named-volume/commands.sh
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
# Exercise 7 — Named Volumes (shared between containers)
|
||||
|
||||
podman volume create pizza
|
||||
|
||||
# Terminal 1: write dates into the volume
|
||||
podman run -v pizza:/data --rm -ti busybox \
|
||||
sh -c 'while true; do sleep 1; date >> /data/output; done'
|
||||
|
||||
# Terminal 2: watch the output
|
||||
podman run -v pizza:/data --rm busybox tail -f /data/output
|
||||
|
||||
# Cleanup
|
||||
podman volume rm pizza
|
||||
18
listings/exercises/ex08-persistence/commands.sh
Executable file
18
listings/exercises/ex08-persistence/commands.sh
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
# Exercise 8 — Volume Persistence (data survives container removal)
|
||||
|
||||
podman volume create pasta
|
||||
|
||||
# Create a file inside the container
|
||||
podman run -v pasta:/data --name pasta --rm -ti busybox \
|
||||
sh -c 'touch /data/hello && echo "file created"'
|
||||
|
||||
# Container is gone — volume still exists
|
||||
podman volume inspect pasta
|
||||
|
||||
# New container, same volume (different mountpoint)
|
||||
podman run -v pasta:/mnt --name pasta2 --rm -ti busybox \
|
||||
ls -la /mnt
|
||||
|
||||
# Cleanup
|
||||
podman volume rm pasta
|
||||
3
listings/exercises/ex09-env-variables/app.env
Normal file
3
listings/exercises/ex09-env-variables/app.env
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
POSTGRES_DB=myapp
|
||||
POSTGRES_USER=app
|
||||
POSTGRES_PASSWORD=secret
|
||||
24
listings/exercises/ex09-env-variables/commands.sh
Executable file
24
listings/exercises/ex09-env-variables/commands.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
# Exercise 9 — Environment Variables
|
||||
|
||||
# Single variables via -e
|
||||
podman run -d --name mydb \
|
||||
-e POSTGRES_DB=myapp \
|
||||
-e POSTGRES_USER=app \
|
||||
-e POSTGRES_PASSWORD=secret \
|
||||
postgres:16-alpine
|
||||
|
||||
# Verify
|
||||
podman exec -ti mydb psql -U app myapp -c "\l"
|
||||
|
||||
podman rm -f mydb
|
||||
|
||||
# Via env-file
|
||||
podman run -d --name mydb \
|
||||
--env-file app.env \
|
||||
postgres:16-alpine
|
||||
|
||||
podman exec -ti mydb psql -U app myapp -c "\l"
|
||||
|
||||
# Cleanup
|
||||
podman rm -f mydb
|
||||
21
listings/exercises/ex10-compose-basic/docker-compose.yml
Normal file
21
listings/exercises/ex10-compose-basic/docker-compose.yml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
services:
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
POSTGRES_DB: myapp
|
||||
POSTGRES_USER: app
|
||||
POSTGRES_PASSWORD: secret
|
||||
networks:
|
||||
- backend
|
||||
|
||||
web:
|
||||
image: nginx:1.27-alpine
|
||||
ports:
|
||||
- "8080:80"
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- backend
|
||||
|
||||
networks:
|
||||
backend:
|
||||
26
listings/exercises/ex11-compose-volume/docker-compose.yml
Normal file
26
listings/exercises/ex11-compose-volume/docker-compose.yml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
services:
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
POSTGRES_DB: myapp
|
||||
POSTGRES_USER: app
|
||||
POSTGRES_PASSWORD: secret
|
||||
volumes:
|
||||
- db-data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- backend
|
||||
|
||||
web:
|
||||
image: nginx:1.27-alpine
|
||||
ports:
|
||||
- "8080:80"
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- backend
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
|
||||
networks:
|
||||
backend:
|
||||
2
listings/exercises/ex12-build-inspect/Containerfile
Normal file
2
listings/exercises/ex12-build-inspect/Containerfile
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
FROM docker.io/library/nginx:1.27
|
||||
COPY index.html /usr/share/nginx/html/index.html
|
||||
5
listings/exercises/ex12-build-inspect/docker-compose.yml
Normal file
5
listings/exercises/ex12-build-inspect/docker-compose.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
services:
|
||||
nginx:
|
||||
build: ./
|
||||
ports:
|
||||
- "80:80"
|
||||
4
listings/exercises/ex12-build-inspect/index.html
Normal file
4
listings/exercises/ex12-build-inspect/index.html
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<html>
|
||||
<head><title>DEMO</title></head>
|
||||
<body>Nothing to see here!</body>
|
||||
</html>
|
||||
8
listings/exercises/ex13-multistage/Containerfile
Normal file
8
listings/exercises/ex13-multistage/Containerfile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
FROM golang:1.24-alpine AS build
|
||||
WORKDIR /src
|
||||
COPY go.mod main.go .
|
||||
RUN go build -o /bin/hello .
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /bin/hello /bin/hello
|
||||
CMD ["/bin/hello"]
|
||||
3
listings/exercises/ex13-multistage/go.mod
Normal file
3
listings/exercises/ex13-multistage/go.mod
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module hello
|
||||
|
||||
go 1.24
|
||||
7
listings/exercises/ex13-multistage/main.go
Normal file
7
listings/exercises/ex13-multistage/main.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("hello, world")
|
||||
}
|
||||
13
listings/exercises/ex14-push/commands.sh
Executable file
13
listings/exercises/ex14-push/commands.sh
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
# Exercise 14 — Push image to local registry
|
||||
|
||||
# Tag and push
|
||||
podman build -t localhost:5000/hello:latest .
|
||||
# OR tag an existing image:
|
||||
# podman tag hello:latest localhost:5000/hello:latest
|
||||
|
||||
podman push --tls-verify=false localhost:5000/hello:latest
|
||||
|
||||
# Verify
|
||||
curl http://localhost:5000/v2/_catalog
|
||||
curl http://localhost:5000/v2/hello/tags/list
|
||||
12
listings/exercises/ex15-registry-api/commands.sh
Executable file
12
listings/exercises/ex15-registry-api/commands.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
# Exercise 15 — Query the local registry API
|
||||
|
||||
# List all repositories in the registry
|
||||
curl http://localhost:5000/v2/_catalog
|
||||
|
||||
# List tags for a specific image
|
||||
curl http://localhost:5000/v2/hello/tags/list
|
||||
|
||||
# Inspect a specific manifest (optional)
|
||||
curl http://localhost:5000/v2/hello/manifests/latest \
|
||||
-H "Accept: application/vnd.docker.distribution.manifest.v2+json"
|
||||
150
setup/setup-ubuntu2404.sh
Executable file
150
setup/setup-ubuntu2404.sh
Executable file
|
|
@ -0,0 +1,150 @@
|
|||
#!/bin/bash
|
||||
# Container Training — Ubuntu 24.04 (Noble) Setup
|
||||
# Als root oder mit sudo ausführen: sudo bash setup-ubuntu2404.sh
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
ok() { echo -e "${GREEN}[OK]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
fail() { echo -e "${RED}[FEHLER]${NC} $*"; exit 1; }
|
||||
|
||||
[ "$(id -u)" -eq 0 ] || fail "Bitte als root oder mit sudo ausführen."
|
||||
|
||||
# Ubuntu 24.04 prüfen
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
if [ "$ID" != "ubuntu" ] || [ "$VERSION_CODENAME" != "noble" ]; then
|
||||
warn "Dieses Script ist für Ubuntu 24.04 (Noble) geschrieben — läuft auf: $PRETTY_NAME"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "================================================"
|
||||
echo " Container-Schulung — Setup (Ubuntu 24.04)"
|
||||
echo "================================================"
|
||||
echo ""
|
||||
|
||||
# Trainingsuser ermitteln
|
||||
TRAINING_USER=${SUDO_USER:-""}
|
||||
if [ -z "$TRAINING_USER" ]; then
|
||||
warn "SUDO_USER nicht gesetzt — Linger wird nicht konfiguriert."
|
||||
warn "Ggf. manuell ausführen: loginctl enable-linger <username>"
|
||||
fi
|
||||
|
||||
# -------------------------------------------------------
|
||||
echo ""
|
||||
echo "[1/5] Basis-Tools..."
|
||||
# -------------------------------------------------------
|
||||
apt-get update -q
|
||||
apt-get install -y \
|
||||
iputils-ping \
|
||||
iproute2 \
|
||||
net-tools \
|
||||
dnsutils \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
vim \
|
||||
jq \
|
||||
bash-completion
|
||||
ok "Basis-Tools installiert."
|
||||
|
||||
# -------------------------------------------------------
|
||||
echo ""
|
||||
echo "[2/5] Podman + rootless-Abhängigkeiten..."
|
||||
# -------------------------------------------------------
|
||||
# Ubuntu 24.04 liefert Podman >= 4.9 aus dem universe-Repo — kein Fremdrepo nötig
|
||||
add-apt-repository -y universe
|
||||
apt-get update -q
|
||||
apt-get install -y \
|
||||
podman \
|
||||
slirp4netns \
|
||||
fuse-overlayfs \
|
||||
uidmap \
|
||||
dbus-user-session \
|
||||
systemd-container
|
||||
|
||||
PODMAN_VER=$(podman --version | awk '{print $3}')
|
||||
PODMAN_MINOR=$(echo "$PODMAN_VER" | cut -d. -f2)
|
||||
PODMAN_MAJOR=$(echo "$PODMAN_VER" | cut -d. -f1)
|
||||
|
||||
if [ "$PODMAN_MAJOR" -gt 4 ] || { [ "$PODMAN_MAJOR" -eq 4 ] && [ "$PODMAN_MINOR" -ge 4 ]; }; then
|
||||
ok "Podman $PODMAN_VER — Quadlets werden unterstützt."
|
||||
else
|
||||
warn "Podman $PODMAN_VER — Quadlets brauchen >= 4.4! Tag 3 könnte Probleme machen."
|
||||
fi
|
||||
|
||||
# -------------------------------------------------------
|
||||
echo ""
|
||||
echo "[3/5] Registry-Konfiguration..."
|
||||
# -------------------------------------------------------
|
||||
# Drop-in statt Hauptdatei überschreiben — sauber und updatefest
|
||||
mkdir -p /etc/containers/registries.conf.d
|
||||
cat > /etc/containers/registries.conf.d/10-unqualified-search.conf << 'EOF'
|
||||
# Kurzname-Auflösung: docker.io und quay.io werden automatisch durchsucht
|
||||
unqualified-search-registries = ['docker.io', 'quay.io']
|
||||
EOF
|
||||
ok "unqualified-search-registries konfiguriert (docker.io, quay.io)."
|
||||
|
||||
# -------------------------------------------------------
|
||||
echo ""
|
||||
echo "[4/5] podman-compose + trivy..."
|
||||
# -------------------------------------------------------
|
||||
apt-get install -y podman-compose 2>/dev/null \
|
||||
|| pip3 install --quiet podman-compose
|
||||
ok "podman-compose installiert."
|
||||
|
||||
# trivy
|
||||
curl -fsSL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \
|
||||
| sh -s -- -b /usr/local/bin latest
|
||||
ok "trivy installiert: $(trivy --version | head -1)"
|
||||
|
||||
# -------------------------------------------------------
|
||||
echo ""
|
||||
echo "[5/5] Benutzer-Setup ($TRAINING_USER)..."
|
||||
# -------------------------------------------------------
|
||||
if [ -n "$TRAINING_USER" ]; then
|
||||
loginctl enable-linger "$TRAINING_USER"
|
||||
ok "Linger aktiviert für $TRAINING_USER — systemctl --user überlebt Logout."
|
||||
|
||||
# subuid/subgid für rootless Container
|
||||
if ! grep -q "^${TRAINING_USER}:" /etc/subuid 2>/dev/null; then
|
||||
usermod --add-subuids 100000-165535 "$TRAINING_USER"
|
||||
usermod --add-subgids 100000-165535 "$TRAINING_USER"
|
||||
ok "subuid/subgid konfiguriert."
|
||||
else
|
||||
ok "subuid/subgid bereits vorhanden."
|
||||
fi
|
||||
|
||||
# podman socket für den User aktivieren (für podman compose)
|
||||
systemctl enable --now podman.socket 2>/dev/null || true
|
||||
su - "$TRAINING_USER" -c "systemctl --user enable --now podman.socket" 2>/dev/null || true
|
||||
ok "Podman socket aktiviert."
|
||||
else
|
||||
warn "Kein Trainingsuser — Linger, subuid/subgid und socket übersprungen."
|
||||
fi
|
||||
|
||||
# -------------------------------------------------------
|
||||
echo ""
|
||||
echo "================================================"
|
||||
echo " Zusammenfassung"
|
||||
echo "================================================"
|
||||
podman --version
|
||||
podman-compose --version 2>/dev/null | head -1 || true
|
||||
trivy --version | head -1
|
||||
echo ""
|
||||
echo "Registry-Konfiguration:"
|
||||
cat /etc/containers/registries.conf.d/10-unqualified-search.conf
|
||||
echo ""
|
||||
|
||||
if [ -n "$TRAINING_USER" ]; then
|
||||
echo "Benutzer: $TRAINING_USER"
|
||||
echo "Linger: $(loginctl show-user "$TRAINING_USER" --property=Linger --value 2>/dev/null || echo 'unbekannt')"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
ok "Setup abgeschlossen. Bitte einmal aus- und wieder einloggen."
|
||||
Loading…
Add table
Reference in a new issue