How to install PeerTube on Ubuntu
PeerTube is a self-hosted video streaming platform, with various social networking features that I am not using. I need this to host training videos for SENAITE.
I first installed it using caprover/caprover: Scalable PaaS (automated Docker+nginx) - aka Heroku on Steroids which was pretty easy, but later took down that VM to reduce my Günstige Dedicated Server, Cloud & Hosting aus Deutschland costs. The following instructions are for installing PeerTube on Ubuntu 24.04.
I first created an Ubuntu LXC on Proxmox on my home server. I am mainly using free Cloudflare Tunnels to expose self-hosted web services to the public Internet, and Cloudflare doesn’t like you using a lot of bandwidth for these, but I don’t think it will be high volume.
I gave the instance 4GB RAM and 30GB storage. It got an IP address from DHCP.
Log into the instance. The following code installs Docker and other software required, then creates a user and then switches to being that user for the subsequent steps.
apt update
apt install apt-transport-https vim ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt-cache policy docker-ce
apt install docker-ce
systemctl enable docker
systemctl status docker
useradd -m paul -s /bin/bash
passwd paul # use a strong password
usermod -aG sudo paul
usermod -aG docker paul
su - paulThen I create a folder to keep things tidy and in that folder I create two files: docker-compose.yml and .env. The content of these files will be different if you are not using Cloudflare Tunnels - this stage repeatedly caught me out, but this is the configuration that ultimately worked for me.
mkdir docker
cd docker
vim docker-compose.yml
vim .envdocker-compose.yml: use your own secure password for the database (this password should be the same in both config files)
version: '3.7'
services:
peertube:
image: chocobozzz/peertube:production-bookworm
container_name: peertube
ports:
- "9000:9000"
volumes:
- ./data/config:/config
- ./data/storage:/data
- ./data/logs:/logs
env_file:
- .env
depends_on:
- postgres
- redis
restart: unless-stopped
postgres:
image: postgres:13
environment:
POSTGRES_USER: peertube
POSTGRES_PASSWORD: xxxxxxxxxxxxxx
POSTGRES_DB: peertube
volumes:
- ./data/db:/var/lib/postgresql/data
restart: unless-stopped
redis:
image: redis:6
restart: unless-stopped.env: add your database password and webserver hostname; add the IP address of the container/VM to the trusted proxies; create a secret using the suggested command; add your email address
# Database / Postgres service configuration
POSTGRES_USER=peertube
POSTGRES_PASSWORD=xxxxxxxxxxxxxx
# Postgres database name "peertube"
POSTGRES_DB=peertube
# The database name used by PeerTube will be PEERTUBE_DB_NAME (only if set) *OR* 'peertube'+PEERTUBE_DB_SUFFIX
#PEERTUBE_DB_NAME=<MY POSTGRES DB NAME>
#PEERTUBE_DB_SUFFIX=_prod
# Database username and password used by PeerTube must match Postgres', so they are copied:
PEERTUBE_DB_USERNAME=$POSTGRES_USER
PEERTUBE_DB_PASSWORD=$POSTGRES_PASSWORD
PEERTUBE_DB_SSL=false
# Default to Postgres service name "postgres" in docker-compose.yml
PEERTUBE_DB_HOSTNAME=postgres
# PeerTube server configuration
# If you test PeerTube in local: use "peertube.localhost" and add this domain to your host file resolving on 127.0.0.1
PEERTUBE_WEBSERVER_HOSTNAME=xxxxxxxx.xxxxxxxxxx.xxx
# If you just want to test PeerTube on local
#PEERTUBE_WEBSERVER_PORT=9000
#PEERTUBE_WEBSERVER_HTTPS=false
# If you need more than one IP as trust_proxy
# pass them as a comma separated array:
PEERTUBE_TRUST_PROXY=["127.0.0.1", "loopback", "xxx.xxx.x.xxx/24"]
# Generate one using `openssl rand -hex 32`
PEERTUBE_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# E-mail configuration
# If you use a Custom SMTP server
#PEERTUBE_SMTP_USERNAME=
#PEERTUBE_SMTP_PASSWORD=
# Default to Postfix service name "postfix" in docker-compose.yml
# May be the hostname of your Custom SMTP server
# PEERTUBE_SMTP_HOSTNAME=postfix
# PEERTUBE_SMTP_PORT=25
# PEERTUBE_SMTP_FROM=noreply@<MY DOMAIN>
# PEERTUBE_SMTP_TLS=false
# PEERTUBE_SMTP_DISABLE_STARTTLS=false
PEERTUBE_ADMIN_EMAIL=xxxxxxx@xxxxxxxxxx.xxx
# Postfix service configuration
# POSTFIX_myhostname=<MY DOMAIN>
# If you need to generate a list of sub/DOMAIN keys
# pass them as a whitespace separated string <DOMAIN>=<selector>
# OPENDKIM_DOMAINS=<MY DOMAIN>=peertube
# see https://github.com/wader/postfix-relay/pull/18
# OPENDKIM_RequireSafeKeys=no
# If you want to enable object storage for PeerTube, set the following variables.
#PEERTUBE_OBJECT_STORAGE_ENABLED=
#PEERTUBE_OBJECT_STORAGE_ENDPOINT=
#PEERTUBE_OBJECT_STORAGE_REGION=
#PEERTUBE_OBJECT_STORAGE_CREDENTIALS_ACCESS_KEY_ID=
#PEERTUBE_OBJECT_STORAGE_CREDENTIALS_SECRET_ACCESS_KEY=
#PEERTUBE_OBJECT_STORAGE_STREAMING_PLAYLISTS_BUCKET_NAME=
#PEERTUBE_OBJECT_STORAGE_STREAMING_PLAYLISTS_PREFIX=
#PEERTUBE_OBJECT_STORAGE_STREAMING_PLAYLISTS_BASE_URL=
#PEERTUBE_OBJECT_STORAGE_WEB_VIDEOS_BUCKET_NAME=
#PEERTUBE_OBJECT_STORAGE_WEB_VIDEOS_PREFIX=
#PEERTUBE_OBJECT_STORAGE_WEB_VIDEOS_BASE_URL=
#PEERTUBE_OBJECT_STORAGE_USER_EXPORTS_BUCKET_NAME=
#PEERTUBE_OBJECT_STORAGE_USER_EXPORTS_PREFIX=
#PEERTUBE_OBJECT_STORAGE_USER_EXPORTS_BASE_URL=
#PEERTUBE_OBJECT_STORAGE_ORIGINAL_VIDEO_FILES_BUCKET_NAME=
#PEERTUBE_OBJECT_STORAGE_ORIGINAL_VIDEO_FILES_PREFIX=
#PEERTUBE_OBJECT_STORAGE_ORIGINAL_VIDEO_FILES_BASE_URL=
#PEERTUBE_OBJECT_STORAGE_CAPTIONS_BUCKET_NAME=
#PEERTUBE_OBJECT_STORAGE_CAPTIONS_PREFIX=
#PEERTUBE_OBJECT_STORAGE_CAPTIONS_BASE_URL=
# Comment these variables if your S3 provider does not support object ACL
PEERTUBE_OBJECT_STORAGE_UPLOAD_ACL_PUBLIC="public-read"
PEERTUBE_OBJECT_STORAGE_UPLOAD_ACL_PRIVATE="private"
#PEERTUBE_LOG_LEVEL=info
# /!\ Prefer to use the PeerTube admin interface to set the following configurations /!\
#PEERTUBE_SIGNUP_ENABLED=true
#PEERTUBE_TRANSCODING_ENABLED=true
#PEERTUBE_CONTACT_FORM_ENABLED=trueThen fire up the containers:
docker compose up -dIf it is not working you can check the Docker logs for clues to what you have done wrong. Look out for the web login details in the Docker output.
I then pointed a Cloudflare Tunnel at http://<IP address>:9000 - job done.