Skip to content

Self-host PeerTube

updated Sep 2026prices checked · Jul 2026Install verified on Ubuntu 26.04 · Sep 2026 · how we test
We earn commissions when you shop through the links below. Full disclosure →

A self-hosted video hosting and live-streaming platform that federates with other PeerTube instances over ActivityPub. It handles uploads, transcoding, channels and playlists.

Key facts

CategoryVideo platform
LicenseAGPL-3.0
StackTypeScript, Node.js, PostgreSQL, Redis
Min RAM1536 MB
Official imageyes
Measured idle RAM210 MB
Difficulty

What you need

  • Any VPS with at least 1536 MB of RAM
  • A domain you control — most self-hosted setups need HTTPS in front of them
  • About an afternoon — budget time for troubleshooting
Where to host itaffiliate disclosure
Hetzner Cloudrun it on
From $23.59/mo · 2 vCPU / 4 GB / 80 GB · EU + US
Get Hetzner Cloud (opens in new tab)
Kamaterafree trial
From $4/mo · 1 vCPU / 1 GB / 20 GB · US + EU + Asia
Start free on Kamatera → (opens in new tab)
DigitalOceanalso works on
From $6/mo · 1 vCPU / 1 GB / 25 GB · US + EU + Asia
Deploy on DigitalOcean → (opens in new tab)

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

Install

Run these commands on your server:

# PeerTube — the official production compose trimmed to PeerTube + PostgreSQL + Redis + Postfix
# (its bundled nginx + certbot services are dropped: bring your own reverse proxy with TLS)
mkdir peertube && cd peertube
# PEERTUBE_WEBSERVER_HOSTNAME is permanent: PeerTube does not support changing it after first start
cat > .env << EOF
POSTGRES_USER=peertube
POSTGRES_PASSWORD=$(openssl rand -hex 16)
POSTGRES_DB=peertube
PEERTUBE_DB_USERNAME=\$POSTGRES_USER
PEERTUBE_DB_PASSWORD=\$POSTGRES_PASSWORD
PEERTUBE_DB_HOSTNAME=postgres
PEERTUBE_DB_SSL=false
PEERTUBE_WEBSERVER_HOSTNAME=video.example.com
PEERTUBE_SECRET=$(openssl rand -hex 32)
PEERTUBE_SMTP_HOSTNAME=postfix
PEERTUBE_SMTP_PORT=25
PEERTUBE_SMTP_FROM=noreply@video.example.com
PEERTUBE_SMTP_TLS=false
PEERTUBE_SMTP_DISABLE_STARTTLS=false
PEERTUBE_ADMIN_EMAIL=admin@video.example.com
POSTFIX_myhostname=video.example.com
OPENDKIM_DOMAINS=video.example.com=peertube
OPENDKIM_RequireSafeKeys=no
EOF
cat > docker-compose.yml << 'EOF'
services:
  peertube:
    image: chocobozzz/peertube:production
    env_file: .env
    ports: ["9000:9000", "1935:1935"]
    volumes: ["./docker-volume/data:/data", "./docker-volume/config:/config"]
    depends_on: [postgres, redis, postfix]
    restart: always
  postgres:
    image: postgres:17-alpine
    env_file: .env
    volumes: ["./docker-volume/db:/var/lib/postgresql/data"]
    restart: always
  redis:
    image: redis:8-alpine
    volumes: ["./docker-volume/redis:/data"]
    restart: always
  postfix:
    image: mwader/postfix-relay
    env_file: .env
    volumes: ["./docker-volume/opendkim/keys:/etc/opendkim/keys"]
    restart: always
EOF
docker compose up -d  #  →  PeerTube on :9000 behind your HTTPS proxy (http://SERVER_IP:9000 for a first look)
# admin login is "root"; its generated password is in: docker compose logs peertube | grep -A1 root

More self-hosted tools

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