All tutorials
14 min read

How to Host a TeamSpeak 6 Server on Ubuntu 24.04 with Docker

Host a TeamSpeak server on Ubuntu 24.04 with the official TeamSpeak 6 Docker image: open UDP 9987 and TCP 30033, claim admin, and secure ServerQuery in 8 steps.

TL;DR:

  • Run TeamSpeak 6 server 6.0.0-beta13.1 from the official teamspeaksystems/teamspeak6-server image with Docker Compose. Server data lives in the teamspeak-data volume.
  • Players need UDP 9987 for voice and TCP 30033 for file transfer. ServerQuery stays on 127.0.0.1:10022 behind an SSH tunnel.
  • The Compose file uses host networking, so UFW filters the TeamSpeak ports. Docker-published ports bypass UFW.
  • The TS6 server is a beta with a built-in 32-slot license that TeamSpeak renews every two months. Larger TS6 licenses are not available yet, and TS3 licenses do not work on TS6.
  • Setting TSSERVER_LICENSE_ACCEPTED=accept accepts TeamSpeak's license agreement, so read it first.
  • The ServerAdmin privilege key prints to the log once, on the first start.

Applies to: Ubuntu 24.04 LTS · TeamSpeak 6 Server 6.0.0-beta13.1 (Docker, amd64) · checked October 2026

TeamSpeak is voice and text chat software from TeamSpeak Systems: users run the TeamSpeak client and connect to a server that hosts channels, permission groups and file transfers. This tutorial hosts a TeamSpeak 6 server on Ubuntu 24.04 with Docker Compose and covers the license setting, the first admin privilege key, firewall rules, ServerQuery over an SSH tunnel, backups and updates. A VPS keeps the server reachable for your group when your own computer is off.

TeamSpeak 6 server beta status and license

TeamSpeak publishes the TeamSpeak 6 server as a beta. As of 2026-10-06, the GitHub README states:

  • "As this is a Beta version, some features are still in development, and you may come across bugs."
  • "The dedicated server software for TeamSpeak 6 is still under active development and is not yet fully feature-complete."
  • "The server includes a 32-slot Beta License that will be renewed every two months throughout the beta/evaluation period, until licensing and pricing are finalized."
  • "TeamSpeak 3 Server licenses are not compatible with TeamSpeak 6 Servers, and currently, there is no migration path available between the two versions."

TeamSpeak's self-hosting article, updated 2026-10-03, adds: "It is not yet possible to obtain or upgrade to a larger license for TeamSpeak 6."

The server does not start until you accept TeamSpeak's license. TeamSpeak's configuration reference says that setting TSSERVER_LICENSE_ACCEPTED to accept confirms "that you have read and accepted the server license agreement". The agreement is the LICENSE.md file in TeamSpeak's repository, titled "Privacy Policy, General Terms and Conditions and Customer Information" and last updated 2025-01-21. Adding that variable in Step 3 accepts those terms, so read them first. Section 4.2 states: "Sublicensing slots or virtual servers to third parties is not permitted." Section 4.1 of the same agreement offers the "Gamer license" "exclusively to non-commercial groups and consumers" and lists a separate "Commercial License" for commercial customers.

The server checks its license with TeamSpeak's accounting server. The accounting document in the beta13.1 release archive says the server contacts accounting2.teamspeak.com on port 443, reports every hour, and is stopped "If the license is expired (date) and no new license is available". New betas carry the renewed default license: the beta11, beta12 and beta13 release notes each list "Updated the default license".

How this TeamSpeak Docker setup works

One container runs the tsserver process, with its working directory /var/tsserver in a Docker volume:

PortProtocolPurposeReachable from
9987UDPVoiceInternet
30033TCPFile transfer (channel files, avatars)Internet
10022TCPServerQuery over SSH127.0.0.1 only
443 (outbound)TCPLicense check to accounting2.teamspeak.comOutgoing only

TeamSpeak 6 servers no longer support the Telnet ServerQuery, so SSH on port 10022 is the command-line admin interface. It is off by default, and this setup turns it on for loopback only.

Prerequisites

  • A VPS running Ubuntu 24.04 LTS or 26.04 LTS (64-bit, x86_64) with SSH access. TeamSpeak's TS6 server documentation lists no CPU or RAM minimum. On Arct Cloud, the Cost Optimized cvm.pico plan has 1 vCPU, 1 GB RAM and 15 GB NVMe, and Linux images include Ubuntu 26.04 LTS.
  • A non-root user with sudo privileges and SSH key login. See How to Generate an SSH Key on Windows, macOS, and Linux.
  • Docker Engine and the Docker Compose plugin, with your user in the docker group and UFW enabled with OpenSSH allowed. Follow How to Install Docker and Docker Compose on Ubuntu 24.04 and 26.04. Its loopback default for published ports does not affect the host networking used here.
  • The TeamSpeak 6 client on your computer, from TeamSpeak's downloads page.

Commands run as the sudo user. Replace values written in capitals, such as YOUR_SERVER_IP, with your own.

Step 1: Open the firewall for TeamSpeak

TeamSpeak clients need UDP 9987 for voice and TCP 30033 for file transfers. Because the container uses host networking in Step 3, UFW filters these ports like any other service on the server:

sudo ufw allow 9987/udp
sudo ufw allow 30033/tcp
sudo ufw status

The output looks similar to this:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
9987/udp                   ALLOW       Anywhere
30033/tcp                  ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
9987/udp (v6)              ALLOW       Anywhere (v6)
30033/tcp (v6)             ALLOW       Anywhere (v6)

Do not open 10022. If your provider runs a network firewall in front of the server, open UDP 9987 and TCP 30033 there as well. UFW allows outgoing connections by default, which covers the license check on port 443.

Step 2: Create the project directory and secrets

Compose reads variables from a .env file in the project directory. Create the directory:

mkdir -p ~/teamspeak
cd ~/teamspeak

Write the .env file with the pinned image tag and a random ServerQuery admin password. umask 077 inside the parentheses makes the file readable only by your user:

(
umask 077
cat > .env <<EOF
TEAMSPEAK_VERSION=6.0.0-beta13.1
TS_QUERY_PASSWORD=$(openssl rand -hex 16)
EOF
)

TEAMSPEAK_VERSION pins the image to one beta release. TS_QUERY_PASSWORD sets the password of the built-in serveradmin ServerQuery account, which controls every virtual server on this instance.

Step 3: Write the TeamSpeak Docker Compose file

The Compose file defines the container, its settings and the data volume:

nano compose.yaml

Paste this file, then save with Ctrl+O and exit with Ctrl+X:

services:
  teamspeak:
    image: teamspeaksystems/teamspeak6-server:${TEAMSPEAK_VERSION}
    container_name: teamspeak-server
    restart: unless-stopped
    network_mode: host
    environment:
      TSSERVER_LICENSE_ACCEPTED: "accept"
      TSSERVER_DEFAULT_PORT: "9987"
      TSSERVER_FILE_TRANSFER_PORT: "30033"
      TSSERVER_QUERY_SSH_ENABLED: "true"
      TSSERVER_QUERY_SSH_IP: "127.0.0.1"
      TSSERVER_QUERY_SSH_ALLOW_GUEST: "0"
      TSSERVER_QUERY_ADMIN_PASSWORD: "${TS_QUERY_PASSWORD}"
    volumes:
      - teamspeak-data:/var/tsserver

volumes:
  teamspeak-data:
    name: teamspeak-data

What the main settings do:

  • network_mode: host runs the server in the host's network stack. TeamSpeak's own example publishes ports instead, but Docker routes published ports through NAT rules that run before UFW, so UFW cannot filter them. Host networking needs no NAT, so the Step 1 rules apply.
  • Voice and file transfer listen on all IPv4 and IPv6 addresses by default. If your server has a public IPv6 address, clients can connect over it through the (v6) rules.
  • TSSERVER_QUERY_SSH_IP binds ServerQuery to loopback. TSSERVER_QUERY_SSH_ALLOW_GUEST: "0" turns off password-free guest query logins, which beta13 enabled by default.
  • The teamspeak-data volume holds /var/tsserver, where the server writes its SQLite database (tsserver.sqlitedb) and its logs.

Step 4: Start the TeamSpeak server

Pull the image and start the container in the background:

docker compose up -d

Docker downloads the image, creates the teamspeak-data volume and starts teamspeak-server. Confirm that it runs:

docker compose ps --services --status running

The output is teamspeak. If it is empty, read docker compose logs teamspeak and check the troubleshooting table below.

Step 5: Copy the privilege key from the logs

On its first start with an empty volume, the server creates a ServerAdmin privilege key and prints it once. Print the lines that contain it:

docker compose logs --no-log-prefix teamspeak | grep "token="

The key appears a few seconds after start, after the listening on lines. If the command prints nothing right after Step 4, wait 10 seconds and run it again. The output looks similar to this, with your key in place of YOUR_PRIVILEGE_KEY:

...|WARNING |VirtualServer |1  |token=YOUR_PRIVILEGE_KEY
       token=YOUR_PRIVILEGE_KEY

Copy the key after token=. A privilege key works once and adds its user to the Server Admin group of this virtual server. Restarts and updates do not print a new one.

Step 6: Connect and claim admin with the TeamSpeak client

Open the TeamSpeak 6 client on your computer. Enter your server's IP address, such as 203.0.113.10, in the search area at the top left, then select Quick connect or press Enter.

Once connected, right-click the server, select Use Privilege Key, and paste the key from Step 5. Your client identity joins the Server Admin group.

Step 7: Use ServerQuery through an SSH tunnel

ServerQuery accepts text commands for administration, and it creates new privilege keys if you lose admin rights. It listens on 127.0.0.1:10022, so you reach it from your computer through an SSH tunnel. Open the tunnel in one terminal on your computer and leave it running:

ssh -N -L 10022:127.0.0.1:10022 YOUR_USER@YOUR_SERVER_IP

Replace YOUR_USER with your sudo user and YOUR_SERVER_IP with the server's address. How to Open a Private Dashboard with an SSH Tunnel explains the -L option and Windows clients. In a second terminal on your computer, log in as serveradmin:

ssh -p 10022 [email protected]

Accept the host key on the first connection, then enter the TS_QUERY_PASSWORD value, which grep TS_QUERY_PASSWORD ~/teamspeak/.env shows on the server. Select the first virtual server and check the version:

use 1
version

The server answers each command with error id=0 msg=ok, and version prints a line that starts with version=6.0.0. To require a password for joining, run serveredit virtualserver_password=YOUR_SERVER_PASSWORD with a password that has no spaces. Type quit to leave. On the server itself, ssh -p 10022 [email protected] reaches the same interface without a tunnel.

Step 8: Verify the ports, the license and memory use

List the sockets the TeamSpeak process holds on the server:

cd ~/teamspeak
sudo ss -tulpn | grep tsserver

The Local Address column includes these entries:

Local addressProtocolServiceReachable from outside
0.0.0.0:9987, [::]:9987UDPVoiceYes, through UFW
0.0.0.0:30033, [::]:30033TCPFile transferYes, through UFW
127.0.0.1:10022TCPServerQuery (SSH)No

0.0.0.0:10022 or [::]:10022 means TSSERVER_QUERY_SSH_IP is missing from compose.yaml. Check the license the server loaded:

docker compose logs --no-log-prefix teamspeak | grep -E "max slots|ending date"

The output looks similar to this:

...|INFO    |Accounting    |   |ending date       : ...
...|INFO    |Accounting    |   |max slots         : 32

The ending date line shows when the built-in beta license ends; update the image before that date. From your own computer, confirm that ServerQuery is closed to the internet:

nc -vz -w 5 YOUR_SERVER_IP 10022

The connection fails or times out; a succeeded message means the port is public. On Windows, run Test-NetConnection -ComputerName YOUR_SERVER_IP -Port 10022 in PowerShell; TcpTestSucceeded : False is the expected result. TeamSpeak publishes no memory figure for the TS6 server, so check your instance with a few clients connected:

docker stats --no-stream teamspeak-server

Update the TeamSpeak server

TeamSpeak publishes each beta as a GitHub release and a Docker Hub tag, and its upgrade guide asks you to keep servers up to date. Tags from 6.0.0-beta9 onward have no v prefix, so copy the tag as the Docker Hub tags page lists it. Back up first, then change the version line and recreate the container:

cd ~/teamspeak
grep TEAMSPEAK_VERSION .env
sed -i 's/^TEAMSPEAK_VERSION=.*/TEAMSPEAK_VERSION=YOUR_NEW_VERSION/' .env
docker compose pull
docker compose up -d

Replace YOUR_NEW_VERSION with the new tag. The grep line shows the version you are replacing. Check the startup lines:

docker compose logs --no-log-prefix teamspeak | grep -E "TeamSpeak Server [0-9]|updated permissions"

The first line names the running version. An updated permissions to version line means the server migrated its permission system. Remove the old image with docker image rm teamspeaksystems/teamspeak6-server:YOUR_OLD_VERSION.

Back up the TeamSpeak server

The teamspeak-data volume holds the database, the logs and the ServerQuery SSH host key. Stop the server for a consistent copy of the SQLite database, archive the volume, and start it again. Connected users are disconnected while it is stopped:

mkdir -p ~/teamspeak-backups
cd ~/teamspeak
docker compose stop
sudo tar -czf ~/teamspeak-backups/teamspeak-$(date +%F-%H%M).tar.gz -C /var/lib/docker/volumes/teamspeak-data/_data .
docker compose start
sudo chown "$USER": ~/teamspeak-backups/*.tar.gz
cp .env compose.yaml ~/teamspeak-backups/
chmod -R go-rwx ~/teamspeak-backups

Copy ~/teamspeak-backups to another machine, for example with rsync as shown in How to Copy Files to a VPS with rsync and scp. For server-level copies, see VPS backups. To restore on the same server, empty the stopped volume and extract the archive into it:

cd ~/teamspeak
docker compose stop
BACKUP="$HOME/teamspeak-backups/teamspeak-YOUR_TIMESTAMP.tar.gz"
sudo tar -tzf "$BACKUP" > /dev/null && \
  sudo find /var/lib/docker/volumes/teamspeak-data/_data -mindepth 1 -delete && \
  sudo tar -xzf "$BACKUP" -C /var/lib/docker/volumes/teamspeak-data/_data
docker compose start

Replace YOUR_TIMESTAMP with the date and time in the file name. The find line empties the volume first, so no database journal or file newer than the backup stays next to the restored data. It runs only after tar -tzf has read the archive, so a wrong file name leaves the volume as it was. To move to another machine, stop the old server before you start the restored copy, because TeamSpeak's accounting server lets a virtual server run on one server process at a time. docker volume rm teamspeak-data and docker compose down -v delete all server data.

Troubleshoot common TeamSpeak server errors

SymptomCauseFix
grep "token=" prints nothingThe server is still starting, or the key was printed on an earlier first startWait 10 seconds and run the command again. If it still prints nothing, create a new key in ServerQuery (see the FAQ). Deleting the volume prints a new key but erases all server data
Step 4 prints nothing, docker compose ps shows the container restarting, and the log mentions --accept-licenseTSSERVER_LICENSE_ACCEPTED is missing or misspelledSet it to accept in compose.yaml, then docker compose up -d
Could not bind virtual server address/portAnother process uses UDP 9987Find it in sudo ss -ulpn, then stop it
The client cannot connectUDP 9987 is closed in UFW or a provider firewallsudo ufw status, then open 9987/udp in UFW, and in your provider's network firewall if it runs one
Voice works, file uploads and avatars failTCP 30033 is closedOpen 30033/tcp in UFW, and in your provider's network firewall if it runs one
The server stops after a while or does not startNo HTTPS route to accounting2.teamspeak.com, or the built-in license endedRead the Accounting lines in docker compose logs teamspeak, then update the image
The server refuses to start after several quick restartsTeamSpeak's accounting server locks a license for 15 minutes after repeated start-stop cyclesFix the logged error, run docker compose stop, wait 15 minutes, then docker compose start

TeamSpeak as a self-hosted Discord alternative

Discord servers run on Discord's infrastructure. A self-hosted TeamSpeak server runs on a machine you control and keeps its channels, permission groups and database in the volume from Step 3, while it reports license and slot use to TeamSpeak's accounting server every hour.

FAQ

Is there a TeamSpeak 6 server?

Yes. TeamSpeak publishes the TeamSpeak 6 server as a beta, with Linux and Windows builds on GitHub and the official teamspeaksystems/teamspeak6-server image on Docker Hub. The latest build is 6.0.0-beta13.1, released on 2026-09-22.

How do I install TeamSpeak 6 on Linux?

Run the official Docker image, as this tutorial does, and set TSSERVER_LICENSE_ACCEPTED=accept after you read TeamSpeak's license agreement. TeamSpeak's README recommends Docker. The Linux archive from TeamSpeak's GitHub releases runs with ./tsserver --accept-license, which accepts the same terms.

How much does a TeamSpeak 6 license cost?

TeamSpeak has not published TS6 server license pricing as of October 2026. The beta server includes a 32-slot license that TeamSpeak renews every two months until licensing and pricing are finalized, and larger TS6 licenses cannot be obtained yet. TS3 licenses do not work on TS6 servers.

Is TeamSpeak 3 or 6 better?

Choose a TeamSpeak 3 server if your group needs more than 32 slots now. The TS6 server is a beta with a 32-slot license, while TS3 Gamer licenses for individuals and non-commercial groups range from 64 to 1,024 slots. TS3 licenses do not work on TS6, and TeamSpeak offers no migration path between the two yet.

What are the TeamSpeak server requirements?

TeamSpeak's TS6 server documentation lists no CPU or RAM minimum. The server needs UDP 9987 and TCP 30033 open, outbound HTTPS to accounting2.teamspeak.com for its license check, and a 64-bit system. The amd64 Docker image is a 60 MB download.

Can TeamSpeak 3 users join a TeamSpeak 6 server?

Yes. TeamSpeak's support site states that TeamSpeak 6, TS3 and app users can connect to the same server "providing the server owner has set this up", each limited to the features of their own client. The TeamSpeak 6 client also connects to TS3 servers with TS3 features.

How do I get a new TeamSpeak privilege key?

Log in to ServerQuery as serveradmin, run use 1, then run tokenadd tokentype=0 tokenid1=6 tokenid2=0. Group 6 is the default Server Admin group, and the server answers with a new token= line. Use that key once from the client with Use Privilege Key.

Next steps

Arct Cloud includes DDoS protection on every plan, and Linux images deploy in under 30 seconds with root SSH. Compare plans.

This work is licensed under CC BY-NC-SA 4.0.