Podman Rootless Setup

Set up Gordon with Podman in rootless mode for enhanced security.

What You'll Learn

  • Installing Podman for rootless containers
  • Configuring firewall port forwarding
  • Running Gordon as a user service
  • Troubleshooting common issues

Prerequisites

  • Ubuntu 24.04 LTS or Debian 13
  • VPS with root access (for initial setup)
  • Domain pointing to your VPS

Why Rootless?

Rootless containers run without root privileges, providing:

  • Security: Container escapes don't grant root access
  • Isolation: Each user has separate container namespace
  • Simplicity: No Docker daemon required

Steps

1. System Preparation

# Update system
sudo apt update && sudo apt upgrade -y

# Install Podman and firewalld
sudo apt install -y podman firewalld

# Enable firewalld
sudo systemctl enable --now firewalld

2. Configure User Namespaces

# Enable user namespaces
echo 'user.max_user_namespaces=28633' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Setup subuid/subgid for your user
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER

3. Configure Firewall Port Forwarding

Rootless containers can't bind to ports below 1024. Forward 80/443 to high ports:

# Allow HTTP/HTTPS traffic
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

# Forward privileged ports to unprivileged
sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080
sudo firewall-cmd --permanent --add-forward-port=port=443:proto=tcp:toport=8443

# Apply changes
sudo firewall-cmd --reload

# Verify
sudo firewall-cmd --list-all

4. Enable Podman Socket

# Enable user Podman socket
systemctl --user enable --now podman.socket

# Verify
systemctl --user status podman.socket

5. Configure Registry Access

Allow pushing to localhost registry without TLS:

mkdir -p ~/.config/containers
cat > ~/.config/containers/registries.conf <<EOF
[registries.insecure]
registries = ['localhost:5000']
EOF

6. Install Gordon

# Download (choose your architecture)
wget https://github.com/bnema/gordon/releases/latest/download/gordon_linux_amd64.tar.gz
# or for ARM64:
# wget https://github.com/bnema/gordon/releases/latest/download/gordon_linux_arm64.tar.gz

tar -xzf gordon_linux_*.tar.gz
chmod +x gordon
sudo mv gordon /usr/local/bin/

7. Configure Gordon

Generate initial config:

gordon serve
# Press Ctrl+C after config is created

Edit ~/.config/gordon/gordon.toml:

[server]
port = 8080                              # Must match firewall forward (80 → 8080)
registry_port = 5000
gordon_domain = "gordon.mydomain.com"

[routes]
"app.mydomain.com" = "myapp:latest"

8. Create Systemd User Service

mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/gordon.service <<EOF
[Unit]
Description=Gordon Container Platform
After=podman.socket

[Service]
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/gordon serve

[Install]
WantedBy=default.target
EOF

# Enable and start
systemctl --user daemon-reload
systemctl --user enable --now gordon

9. Enable Linger

Keep services running after logout:

sudo loginctl enable-linger $USER

10. Verify Setup

# Check Gordon status
systemctl --user status gordon

# Check logs
journalctl --user -u gordon -f

# Test registry
curl -v http://localhost:5000/v2/

Tailscale Integration

If using Tailscale for management:

# Add Tailscale interface to trusted zone
sudo firewall-cmd --permanent --zone=trusted --add-interface=tailscale0

# Allow Tailscale WireGuard port
sudo firewall-cmd --permanent --add-port=41641/udp

# Apply
sudo firewall-cmd --reload

Common Issues

"permission denied" on podman

# Ensure podman socket is running
systemctl --user status podman.socket

# Restart if needed
systemctl --user restart podman.socket

Containers can't access network

# Check slirp4netns is installed
which slirp4netns

# Install if missing
sudo apt install slirp4netns

Port forwarding not working

# Verify rules
sudo firewall-cmd --list-all

# Check Gordon is using correct port
grep "port =" ~/.config/gordon/gordon.toml

Service stops after logout

# Enable linger
sudo loginctl enable-linger $USER

# Verify
loginctl show-user $USER | grep Linger

Next Steps