diff --git a/README.md b/README.md index 062a59e..ccaefb9 100644 --- a/README.md +++ b/README.md @@ -338,6 +338,39 @@ podman run -d -p 5000:5000 -v flaskpaste-data:/app/data flaskpaste See `Containerfile` for container build configuration. +### Using Podman Quadlet + +Quadlet integrates rootless containers with systemd. Deploy as a dedicated user: + +```bash +# Create service user and data directory +useradd -r -m -d /home/flaskpaste -s /sbin/nologin flaskpaste +mkdir -p /opt/flaskpaste +chown flaskpaste:flaskpaste /opt/flaskpaste + +# Build image as flaskpaste user +sudo -u flaskpaste podman build -t localhost/flaskpaste:latest . + +# Install Quadlet unit +mkdir -p /home/flaskpaste/.config/containers/systemd +cp flaskpaste.container /home/flaskpaste/.config/containers/systemd/ +chown -R flaskpaste:flaskpaste /home/flaskpaste/.config + +# Enable lingering (start user services at boot) +loginctl enable-linger flaskpaste + +# Start service +systemctl --user -M flaskpaste@ daemon-reload +systemctl --user -M flaskpaste@ start flaskpaste +``` + +Manage with systemctl: +```bash +systemctl --user -M flaskpaste@ status flaskpaste +systemctl --user -M flaskpaste@ restart flaskpaste +journalctl --user -M flaskpaste@ -u flaskpaste +``` + ### Using systemd ```bash # Create service user @@ -391,6 +424,8 @@ flaskpaste/ ├── run.py # Development server ├── wsgi.py # Production WSGI entry ├── Containerfile # Podman/Docker build +├── compose.yaml # Podman/Docker Compose +├── flaskpaste.container # Podman Quadlet unit └── requirements.txt # Dependencies ``` diff --git a/flaskpaste.container b/flaskpaste.container new file mode 100644 index 0000000..3209b84 --- /dev/null +++ b/flaskpaste.container @@ -0,0 +1,38 @@ +# FlaskPaste container unit +# Deploy as flaskpaste user with data in /opt/flaskpaste +# +# Setup: +# useradd -r -m -d /home/flaskpaste -s /sbin/nologin flaskpaste +# mkdir -p /opt/flaskpaste && chown flaskpaste:flaskpaste /opt/flaskpaste +# cp flaskpaste.container /home/flaskpaste/.config/containers/systemd/ +# sudo -u flaskpaste podman build -t localhost/flaskpaste:latest /path/to/source +# loginctl enable-linger flaskpaste +# systemctl --user -M flaskpaste@ daemon-reload +# systemctl --user -M flaskpaste@ start flaskpaste + +[Unit] +Description=FlaskPaste pastebin service +After=local-fs.target + +[Container] +Image=localhost/flaskpaste:latest +ContainerName=flaskpaste +PublishPort=5001:5000 +Volume=/opt/flaskpaste:/app/data:Z +UserNS=keep-id:uid=999,gid=999 + +Environment=FLASK_ENV=production +Environment=FLASKPASTE_URL_PREFIX=/paste +Environment=FLASKPASTE_EXPIRY_ANON=432000 +Environment=FLASKPASTE_MAX_ANON=3145728 +Environment=FLASKPASTE_MAX_AUTH=52428800 + +# Note: Healthcheck defined in Containerfile; Quadlet healthcheck disabled to avoid race +# Resource limits (--memory, --cpus) require cgroup delegation for rootless + +[Service] +Restart=always +TimeoutStartSec=300 + +[Install] +WantedBy=default.target