Running TeamSpeak 6 Server with Podman Rootless & Auto-Updates

rwxd February 23, 2026 #podman #systemd #rootless #quadlets #teamspeak

This guide shows how to run a TeamSpeak 6 server using rootless Podman with Quadlets and automatic container updates.

Why containers?

Why Podman rootless?


Architecture

TeamSpeak 6 Podman Architecture

Prerequisites

Create Podman User

Create a dedicated user for running containers:

# Create podman user if it doesn't exist
if ! id -u podman &> /dev/null; then
    sudo useradd -r -m -d /home/podman -s /bin/bash podman
fi

Install Podman

Ubuntu:

sudo apt-get update
sudo apt-get install -y podman

AlmaLinux:

sudo dnf install -y podman

Enable Lingering

Enable lingering to allow rootless containers to run without an active user session:

sudo loginctl enable-linger podman

Setup

All following commands should be run as the podman user:

sudo -iu podman

We will do the following:

Create Directory Structure

mkdir -p ~/.config/containers/systemd

Create Network Quadlet

We need a new network to run the container in with enabled IPv6.

Create ~/.config/containers/systemd/teamspeak.network:

cat > ~/.config/containers/systemd/teamspeak.network <<'EOF'
[Network]
IPv6=true

[Service]
ExecStop=/usr/bin/podman network rm teamspeak

[Unit]
Description=Podman network for teamspeak
EOF

Create Volume Quadlet

To persist the teamspeak database we need a new volume.

Create ~/.config/containers/systemd/teamspeak-data.volume:

cat > ~/.config/containers/systemd/teamspeak-data.volume <<'EOF'
[Volume]

[Service]

[Unit]
Description=Podman volume for teamspeak data
EOF

Create Container Quadlet

Create ~/.config/containers/systemd/teamspeak.container:

cat > ~/.config/containers/systemd/teamspeak.container <<'EOF'
[Container]
AutoUpdate=registry
Environment=TSSERVER_DATABASE_PLUGIN=sqlite3
Environment=TSSERVER_LICENSE_ACCEPTED=accept
Environment=TSSERVER_QUERY_HTTP_ENABLED=1
Image=docker.io/teamspeaksystems/teamspeak6-server:latest
Network=teamspeak.network
PublishPort=9987:9987/udp
PublishPort=30033:30033/tcp
PublishPort=10080:10080/tcp
Volume=teamspeak-data.volume:/var/tsserver

[Service]
Restart=always
TimeoutStartSec=900

[Unit]
Description=Podman teamspeak container
EOF

Port mapping:

Enable and Start

# Reload systemd to recognize new or changed Quadlets
systemctl --user daemon-reload

# Enable auto-start on boot
systemctl --user enable teamspeak

# Start the service
systemctl --user start teamspeak

# Check status
systemctl --user status teamspeak

Auto-Updates

Enable automatic container updates with a systemd timer:

# Enable auto-update timer
systemctl --user enable --now podman-auto-update.timer

This checks for image updates daily and restarts updated containers with AutoUpdate=registry.

To manually trigger an update:

podman auto-update

Firewall Configuration

Open required ports:

Ubuntu (ufw):

sudo ufw allow 9987/udp comment 'TeamSpeak Voice'
sudo ufw allow 30033/tcp comment 'TeamSpeak Filetransfer'
sudo ufw allow 10080/tcp comment 'TeamSpeak HTTP Query'

AlmaLinux (firewalld):

sudo firewall-cmd --permanent --add-port=9987/udp
sudo firewall-cmd --permanent --add-port=30033/tcp
sudo firewall-cmd --permanent --add-port=10080/tcp
sudo firewall-cmd --reload

First-Time Setup

On first run, TeamSpeak generates an admin token. Retrieve it from the logs:

podman logs teamspeak | grep -i "token"

Connect to your server at <your-ip> and use the token to claim admin privileges.

Troubleshooting

Check Service Status

# Check if service is running
systemctl --user status teamspeak

# Check if container is running
podman ps -a | grep teamspeak

Logs

# Get logs on failing start
journalctl --user -xeu teamspeak

# Follow logs
journalctl --user -feu teamspeak

# Get logs with podman
podman logs -f teamspeak

Port Binding Issues

If ports are already in use:

# Check what's using the ports
sudo ss -tulpn | grep -E '9987|30033|10080'

Permission Issues

Ensure the podman user has proper subuid/subgid mappings:

# Check mappings
grep podman /etc/subuid /etc/subgid

# If missing, add them (as root)
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 podman

To view and modify real UIDs/GIDs of files in volumes, use podman unshare:

# Check which user runs the TeamSpeak process
podman exec teamspeak ps aux
## USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
## tsserver       1  0.9  0.1 2417440 19996 ?       Ssl  Feb18  65:56 tsserver
## tsserver      52  0.0  0.0   7064  2864 pts/0    Rs+  19:09   0:00 ps aux

# Find the UID/GID used inside the container
podman exec teamspeak id tsserver
## uid=9987(tsserver) gid=9987(tsserver) groups=9987(tsserver)

# Enter user namespace to see real UIDs/GIDs
podman unshare

# Now you can see and change ownership to the teamspeak user in the container
ls -ln ~/.local/share/containers/storage/volumes/teamspeak-data/_data/
chown -R 9987:9987 ~/.local/share/containers/storage/volumes/teamspeak-data/_data/

# Exit namespace
exit