Skip to content

How to Deploy Taiga on a VPS

Updated Sep 2026

verified on Ubuntu 26.04 · Sep 2026
We earn commissions when you shop through the links below. Full disclosure →

Self-host Taiga on a VPS with the official taiga-docker stack — generated secrets, a non-interactive admin account, the gateway kept on loopback, HTTPS and WebSockets through Caddy.

Before you start
  • A VPS with at least 2 GB RAM
  • A fresh Ubuntu 24.04 or 26.04 server with root/sudo SSH access
  • A domain or subdomain you can point at the server
  • Docker Engine + Compose installed (see the base guide below)
  • git
Need a box for this guide? Kamatera's free tier lets you spin one up now.Start free on Kamatera → (opens in new tab)

What Taiga is

Taiga is an open-source agile project management platform built around Scrum and Kanban: backlogs, sprints, epics, user stories, issue tracking and a wiki. The backend is Python (Django), the frontend AngularJS, the database PostgreSQL. It is licensed MPL-2.0 and rated 3 / 5 to deploy.

Self-hosting is the same open-source code as Taiga's hosted product, with no project, member or storage caps and no feature gate. What you pay for, if anything, is the hosted service or an optional support contract.

If your team doesn't work in sprints, a general-purpose tool may fit better — see Deploy Plane on a VPS or Deploy OpenProject on a VPS.

Server sizing

taiga-docker runs nine containers: the backend, an async worker, the frontend, the events (WebSocket) server, the protected-attachments service, two RabbitMQ instances, PostgreSQL and an nginx gateway.

  • Minimum: 2 GB RAM — the catalog's floor for the stack.
  • Measured: on a GCP e2-standard-2 running Ubuntu 26.04 with Docker 29.8.1, the idle stack used ~722 MB of RAM and ~2.9 GB of disk for images and data (September 2026).

The two RabbitMQ instances are a large share of the idle memory. On a 2 GB box that leaves room for Caddy and the operating system, but not much else; move to 4 GB if the server also hosts other apps.

Prepare the server

This guide assumes Docker Engine and the Compose plugin are installed, along with a non-root deploy user and a ufw firewall. If not, work through Docker & Compose on Ubuntu first.

sudo ufw allow OpenSSH
sudo ufw allow 80
sudo ufw allow 443
sudo ufw --force enable
sudo apt-get install -y git
Where to host itaffiliate disclosure
Hetzner Cloudrun it on
2 vCPU · 4 GB RAM · 80 GB SSD · $23.59/mo
Get Hetzner Cloud (opens in new tab)
Kamaterafree trial
1 vCPU · 1 GB RAM · 20 GB SSD · $4.00/mo
Start free on Kamatera → (opens in new tab)
DigitalOceanalso works on
1 vCPU · 1 GB RAM · 25 GB SSD · $6.00/mo
Deploy on DigitalOcean → (opens in new tab)

Paid link — we earn a commission if you shop through it.

Install Taiga (taiga-docker)

Clone upstream's taiga-docker repository on its stable branch:

cd ~
[ -d taiga ] || git clone https://github.com/taigaio/taiga-docker.git --branch stable --depth=1 taiga
cd ~/taiga && git log -1 --format='%h %cd' --date=short

A heads-up before you go further: upstream's compose file pins postgres:12.3, rabbitmq:3.8-management-alpine and nginx:1.19-alpine — all past end of life — and the Taiga images themselves on latest. This guide keeps upstream's file as published, because that is what Taiga tests; moving to newer infrastructure images is a change to research and test on your own before a production deploy.

Configure .env

All basic settings live in .env, and upstream says to change the security ones. Four groups:

  • URLs: TAIGA_SCHEME=https, TAIGA_DOMAIN your domain, and WEBSOCKETS_SCHEME=wss — upstream's subdomain example.
  • SECRET_KEY ships as "taiga-secret-key", used for cryptographic signing.
  • Passwords: POSTGRES_PASSWORD, RABBITMQ_PASS and RABBITMQ_ERLANG_COOKIE ship as taiga, taiga and secret-erlang-cookie.
  • Telemetry: ENABLE_TELEMETRY=True by default sends anonymous usage data; set it to False to opt out.
cd ~/taiga
if grep -q '^SECRET_KEY="taiga-secret-key"' .env; then
  sed -i \
    -e "s|^SECRET_KEY=.*|SECRET_KEY=\"$(openssl rand -hex 32)\"|" \
    -e "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -hex 16)|" \
    -e "s|^RABBITMQ_PASS=.*|RABBITMQ_PASS=$(openssl rand -hex 16)|" \
    -e "s|^RABBITMQ_ERLANG_COOKIE=.*|RABBITMQ_ERLANG_COOKIE=$(openssl rand -hex 16)|" \
    .env
fi
sed -i \
  -e 's|^TAIGA_SCHEME=.*|TAIGA_SCHEME=https|' \
  -e 's|^TAIGA_DOMAIN=.*|TAIGA_DOMAIN=taiga.example.com|' \
  -e 's|^WEBSOCKETS_SCHEME=.*|WEBSOCKETS_SCHEME=wss|' \
  -e 's|^ENABLE_TELEMETRY=.*|ENABLE_TELEMETRY=False|' \
  .env
chmod 600 .env
grep -E '^(TAIGA_SCHEME|TAIGA_DOMAIN|WEBSOCKETS_SCHEME|ENABLE_TELEMETRY)=' .env

Replace taiga.example.com with your domain. Set the passwords before the first start: Postgres and RabbitMQ only read them when their data volumes are first created.

The gateway publishes port 9000 on every interface. Since Caddy will sit in front of it, bind it to the loopback interface instead:

cd ~/taiga
sed -i 's|- "9000:80"|- "127.0.0.1:9000:80"|' docker-compose.yml
grep -n '9000:80' docker-compose.yml

Start it

launch-taiga.sh is a one-line wrapper around docker compose up -d:

cd ~/taiga
./launch-taiga.sh
timeout 600 bash -c 'until curl -fs http://127.0.0.1:9000/api/v1/ >/dev/null; do sleep 5; done'
docker compose ps --format '{{.Service}}\t{{.Status}}'

The backend applies its database migrations on the first start, so the API can take a minute or two to answer.

Create the admin account

Upstream creates the first admin with Django's createsuperuser through the taiga-manage service. The ./taiga-manage.sh createsuperuser wrapper asks for the details interactively; Django's --noinput mode takes them from arguments and DJANGO_SUPERUSER_PASSWORD instead, which suits a script. The password is generated and kept in a file only you can read:

cd ~/taiga
if [ ! -f .admin-password ]; then
  openssl rand -hex 12 > .admin-password && chmod 600 .admin-password
  docker compose -f docker-compose.yml -f docker-compose-inits.yml run --rm \
    -e DJANGO_SUPERUSER_PASSWORD="$(cat .admin-password)" \
    taiga-manage createsuperuser --noinput --username admin --email admin@example.com
fi

Log in as admin with the password in ~/taiga/.admin-password, then change it in the profile settings and delete the file.

HTTPS + domain

Point an A record for taiga.example.com at the server's public IP, wait for it to resolve, then terminate TLS with Caddy:

taiga.example.com {
    reverse_proxy 127.0.0.1:9000
}

Upstream's nginx example needs a separate location /events block with Upgrade headers and week-long timeouts, because the events server holds a WebSocket open for real-time board updates. Caddy passes WebSocket upgrades through without extra configuration, so the single block covers both. If you use nginx, copy upstream's configuration exactly.

TAIGA_SCHEME=https also matters for the Django admin at /admin/: its session cookies are marked secure, so it only works over HTTPS.

Securing it

  • Registration: public sign-up is disabled by default. Keep it that way and invite people from each project. Turning it on means setting PUBLIC_REGISTER_ENABLED in two places — "True" for the backend, "true" for the frontend — and GitHub/GitLab login buttons only appear when it is on.
  • Email: by default EMAIL_BACKEND=console, so invitation and password-reset emails are printed to the backend log, not sent. Set EMAIL_BACKEND=smtp and the EMAIL_* variables in .env, then run ./launch-taiga.sh again.
  • Attachments are served through the protected service with short-lived tokens (ATTACHMENTS_MAX_AGE, 360 seconds by default).

Backups

Two things hold your data: the PostgreSQL database and the media volume with uploaded attachments.

cd ~/taiga
mkdir -p ~/taiga-backups
set -o pipefail
docker compose exec -T taiga-db sh -c 'pg_dump -U "$POSTGRES_USER" taiga' | gzip > ~/taiga-backups/taiga-db-$(date +%F).sql.gz
docker run --rm -v taiga_taiga-media-data:/data -v ~/taiga-backups:/backup alpine \
  tar czf /backup/taiga-media-$(date +%F).tar.gz -C /data .
ls -lh ~/taiga-backups

The volume name is prefixed with the project directory (taiga_); confirm it with docker volume ls. Copy the archives and .env off the server — without SECRET_KEY, restored sessions and signed links stop working.

Upgrades

The stable branch's compose file tracks latest Taiga images, so an upgrade is a pull and a restart. Back up first:

cd ~/taiga
git checkout -- docker-compose.yml
git pull --ff-only
sed -i 's|- "9000:80"|- "127.0.0.1:9000:80"|' docker-compose.yml
docker compose pull
./launch-taiga.sh
docker compose ps --format '{{.Service}}\t{{.Status}}'

The loopback edit to docker-compose.yml is undone before git pull (so a changed upstream file never blocks the pull) and re-applied after it. Migrations run when the backend starts.

Troubleshooting

The page loads but boards don't update live. The events WebSocket isn't connecting. Check that WEBSOCKETS_SCHEME=wss matches the HTTPS site and that nothing between the browser and Caddy strips upgrade headers.

Login or the Django admin fails over HTTP. Taiga is configured for HTTPS by default. Use the https:// URL; upstream documents SESSION_COOKIE_SECURE and CSRF_COOKIE_SECURE overrides only for deliberate plain-HTTP setups.

Emails never arrive. EMAIL_BACKEND is still console. Read docker compose logs taiga-back to see the messages that would have been sent.

The backend can't connect to Postgres or RabbitMQ. The passwords in .env were changed after the volumes were created. Put the old values back, or remove the volumes if they hold nothing you need.

Verification + next steps

You're done when you can: load https://taiga.example.com over a valid certificate, log in as the admin you created, create a Scrum project, move a user story across the board and see the change appear in a second browser without refreshing, and find last night's dump off the server.

From there: configure SMTP, invite your team, and look at the Jira, Trello and GitHub importers in upstream's README if you're migrating. For hosting options, see Best VPS for Docker.

Next steps

How to self-host Taiga →More self-hosted project management tools →Automatic HTTPS with Caddy →Run Claude Code with Ollama on Your Own VPS →Deploy Coolify on a VPS →How to Deploy Actual Budget on a VPS →How to Deploy AnythingLLM on a VPS →How to Deploy Appwrite on a VPS →How to Deploy Audiobookshelf on a VPS →How to Deploy Authelia on a VPS →How to Deploy authentik on a VPS →How to Deploy Baserow on a VPS →How to Deploy Beszel on a VPS →How to Deploy Bitwarden on a VPS →How to Deploy BookStack on a VPS →How to Deploy CapRover on a VPS →How to Deploy Checkmate on a VPS →How to Deploy Directus on a VPS →How to Deploy docker-mailserver on a VPS →How to Deploy Docmost on a VPS →How to Deploy Dokku on a VPS →How to Deploy Dokploy on a VPS →How to Deploy Firefly III on a VPS →How to Deploy Forgejo on a VPS →How to Deploy Gatus on a VPS →How to Deploy Ghostfolio on a VPS →How to Deploy Gitea on a VPS →How to Deploy GitLab on a VPS →How to Deploy GlitchTip on a VPS →How to Deploy Grafana on a VPS →How to Deploy Graylog on a VPS →How to Deploy Headscale on a VPS →How to Deploy Healthchecks on a VPS →How to Deploy Home Assistant on a VPS →How to Deploy Immich on a VPS →How to Deploy Jan on a VPS →How to Deploy Jellyfin on a VPS →How to Deploy Karakeep on a VPS →How to Deploy Keycloak on a VPS →How to Deploy Leantime on a VPS →How to Deploy LibreChat on a VPS →How to Deploy Linkwarden on a VPS →How to Deploy LocalAI on a VPS →How to Deploy Mailcow on a VPS →How to Deploy Mailu on a VPS →How to Deploy Matomo on a VPS →How to Deploy Mattermost on a VPS →How to Deploy Meilisearch on a VPS →How to Deploy Memos on a VPS →How to Deploy n8n on a VPS →How to Deploy Navidrome on a VPS →How to Deploy NetBird on a VPS →How to Deploy Netdata on a VPS →How to Deploy Nextcloud on a VPS →How to Deploy Next.js to a VPS →How to Deploy Nginx Proxy Manager on a VPS →How to Deploy NocoDB on a VPS →How to Deploy ntfy on a VPS →How to Deploy Ollama on a VPS →How to Deploy Open WebUI on a VPS →How to Deploy OpenHands on a VPS →How to Deploy OpenObserve on a VPS →How to Deploy OpenProject on a VPS →How to Deploy Outline on a VPS →How to Deploy Pangolin on a VPS →How to Deploy Paperless-ngx on a VPS →How to Deploy Passbolt on a VPS →How to Deploy Plane on a VPS →How to Deploy Plausible Analytics on a VPS →How to Deploy Pocket ID on a VPS →How to Deploy PocketBase on a VPS →How to Deploy Prometheus on a VPS →How to Deploy Psono on a VPS →How to Deploy Radarr on a VPS →How to Deploy Rocket.Chat on a VPS →How to Deploy SigNoz on a VPS →How to Deploy Sonarr on a VPS →How to Deploy Stalwart on a VPS →How to Deploy Stirling-PDF on a VPS →How to Deploy Supabase on a VPS →How to Deploy Synapse on a VPS →How to Deploy TeamPass on a VPS →How to Deploy Tinyauth on a VPS →How to Deploy Traefik on a VPS →How to Deploy Trilium on a VPS →How to Deploy Twenty CRM on a VPS →How to Deploy Umami on a VPS →How to Deploy Uptime Kuma on a VPS →How to Deploy Vaultwarden on a VPS →How to Deploy Vikunja on a VPS →How to Deploy wg-easy on a VPS →How to Deploy Wiki.js on a VPS →How to Deploy Zabbix on a VPS →How to Deploy Zitadel on a VPS →How to Deploy Zulip on a VPS →Docker & Compose on Ubuntu 26.04 →Building AI Workflows with n8n →Install Open WebUI with Ollama →Adding AI-Powered Insights to Plausible Analytics →Building AI-Powered Apps with Supabase and pgvector →

We use analytics cookies (Google Analytics, PostHog) to see which guides are useful. No ad networks, no cross-site tracking. See our privacy policy.