Offerman PeerTube server

Three years ago I installed PeerTube for the first time on my CentOS 8 server (now CentOS 8 Stream). Red Hat frustrated the installation of Docker on this system, so I had to use podman and podman-compose instead.

Over the years podman and podman-compose evolved and the existing install deteriorated, resulting in a PeerTube server that had issues starting up using podman-compose due to a new network setup and PeerTube somehow was no longer offering the administrator functionality. Since I had hardly published any movies, I decided to completely start over with a fresh install.

Even though I did this setup on my (now slightly outdated) CentOS 8 Stream server, the same procedure should work for other and more recent RHEL, CentOS Stream, AlmaLinux and Rocky Linux systems.

Starting point

What I already had:

  • a user peertube
  • a domain peertube.example.com
  • a DV certificate for the domain peertube.example.com
  • a reverse proxy based on Apache (not Nginx, which the project itself uses); see below for its configuration
  • available TCP ports 9000 (the host port for the reverse proxy to connect to) and 1935 (a public host port that serves as an entrance for live video streams)

Docker image & installation guide

Information on the Docker image for PeerTube can be found here:

https://hub.docker.com/r/chocobozzz/peertube

You can use the skopeo command to find out more about this image:

skopeo inspect docker://docker.io/chocobozzz/peertube

And this is the Production Guide we used as the base for this setup (although we'll see further on that some additional tweaking was required to get this Docker image to run using podman and podman-compose, which is the reason for the existence of this hands-on article):

https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/production.md
https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/docker.md
https://docs.joinpeertube.org/install/docker

Preparing the directory structure & configuration files

We start the installation by creating the directory structure and downloading the default configuration files. And we do so as the user peertube:

su - peertube
mkdir podman-peertube.example.com/
cd podman-peertube.example.com/
curl https://raw.githubusercontent.com/chocobozzz/PeerTube/master/support/docker/production/docker-compose.yml > docker-compose.yml
curl https://raw.githubusercontent.com/Chocobozzz/PeerTube/master/support/docker/production/.env > .env

This is also a good moment to create the directory structure that is used by the various containers:

mkdir -p docker-volume/nginx/
curl https://raw.githubusercontent.com/Chocobozzz/PeerTube/master/support/nginx/peertube > docker-volume/nginx/peertube
mkdir -p docker-volume/certbot/
mkdir -p docker-volume/certbot/conf/
mkdir -p docker-volume/db/
mkdir -p docker-volume/redis/
mkdir -p docker-volume/opendkim/keys/
mkdir -p docker-volume/data/
mkdir -p docker-volume/config/

Note, however, that we will not be using Nginx as a reverse proxy, as we will be using an Apache based front-end. And we will not be using certbot, as we already have a dedicated DV certificate for the domain peertube.example.com.

Editing the docker-compose.yml configuration file

Next step is to adjust the default configuration files .env and docker-compose.yml we downloaded previously to our specific setup.

So we start with docker-compose.yml, in which we outcomment the whole of the webserver and certbot services.

Disabling the webserver service, however, requires us to enable TCP port 9000 on the host, so the Apache-based reverse proxy has an entrance point to connect to:

ports:
  - "1935:1935" # Comment if you don't want to use the live feature
  - "9000:9000" # Uncomment if you use another webserver/proxy or test PeerTube in local, otherwise not suitable for production

Note that TCP port 1935 also will be made available on the host, and further on also through the firewall, since that port serves as a public entrance for live video streams.

Also note that there is a network specification in there for 172.18.0.0/16. Podman-compose now creates its own networks automatically, so you should comment these definitions out (at two places):

#networks:
#  default:
#    ipv4_address: 172.18.0.42
networks:
  default:
    ipam:
      driver: default
      config:
#     - subnet: 172.18.0.0/16
Error: requested static ip 172.18.0.42 not in any subnet on network podman-peertubeexamplecom_default
exit code: 126
podman start podman-peertubeexamplecom_peertube_1
Error: unable to start container "48ec87c08f7d243438dc8901e1d37caaaa442f972a0805beaa0505a9f8d561fb": requested static ip 172.18.0.42 not in any subnet on network podman-peertubeexamplecom_default
exit code: 125

Editing the .env configuration file

Next is the .env file, in which we set the environment variables specific to this host and instance:

POSTGRES_USER=peertube
POSTGRES_PASSWORD=************
PEERTUBE_DB_USERNAME=peertube
PEERTUBE_DB_PASSWORD=************
PEERTUBE_WEBSERVER_HOSTNAME=peertube.example.com
PEERTUBE_SECRET=****************************************************************
PEERTUBE_SMTP_FROM=Dit e-mailadres wordt beveiligd tegen spambots. JavaScript dient ingeschakeld te zijn om het te bekijken.
PEERTUBE_ADMIN_EMAIL=Dit e-mailadres wordt beveiligd tegen spambots. JavaScript dient ingeschakeld te zijn om het te bekijken.
POSTFIX_myhostname=example.com
OPENDKIM_DOMAINS=example.com=peertube

Note that we repeated the database user and password for PEERTUBE_DB_USERNAME and PEERTUBE_DB_PASSWORD, since the original configuration using variable expansion somehow doesn't work when using podman-compose.

[peertube.offerman.com:443] 2024-06-13 10:35:07.213 error: Unable to connect to PostgreSQL database. {
...
"message": "password authentication failed for user \"$POSTGRES_USER\"",

To generate the PEERTUBE_SECRET, we used this command:

openssl rand -hex 32

Adjusting the SELinux context

Before we can start up the PeerTube image, we need to adjust the SELinux context of the newly created directory tree, allowing the running instance access to the files in there. So we switch back to the root account and run the following commands:

semanage fcontext -a -t container_file_t "/home/peertube/podman-peertube.example.com/docker-volume(/.*)?"
restorecon -vRF /home/peertube/podman-peertube.example.com/docker-volume/

Downloading and running the Docker image

Now we download the Docker image for PeerTube:

podman pull docker.io/chocobozzz/peertube

And start it up like this:

podman-compose up -d

This should download all dependencies and start a bunch of containers.

If you want to see the podman commands generated by podman-compose first, you can add the '--dry-run' option like this:

podman-compose --dry-run up -d

Setting the root password

The old command to get the automatically created root password is no longer working:

docker-compose logs peertube | grep -A1 root
[root@system podman-peertube.example.com]# podman-compose logs peertube | grep -A1 root
podman-compose version: 1.0.6
['podman', '--version', '']
using podman version: 4.9.4-dev
podman logs podman-peertubeexamplecom_peertube_1
exit code: 0

Now you need to create a new (or updated) password like this:

podman-compose exec -u peertube peertube npm run reset-password -- -u root
[root@system podman-peertube.example.com]# podman-compose exec -u peertube peertube npm run reset-password -- -u root
podman-compose version: 1.0.6
['podman', '--version', '']
using podman version: 4.9.4-dev
podman exec --interactive --user peertube --tty podman-peertubeexamplecom_peertube_1 npm run reset-password -- -u root

> peertube@6.1.0 reset-password
> node ./dist/scripts/reset-password.js -u root

New password?
User password updated.
exit code: 0

Publishing the DKIM record

Next is to publish the DKIM record for the new domain name by adding it to you zone file.

cat ./docker-volume/opendkim/keys/*/*.txt
peertube._domainkey.example.com.    IN    TXT    ( "v=DKIM1; h=sha256; k=rsa; "
    "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAugDtb44MhagNumQzoILFCkzzaVVAgXSGqIN2b6UY1xaSLtgcPozDkOfkM25D2af/mg8s02OCrGDccHTxPaAWAzI6GrZuDzHgP6mfWaNpDEUm5TYbdh93LTyMoqyQ04SsDpqEuNh9vAUNoPKgplzRnW98z1DCP5Usx80iTmKQC/pWrhZI3aTK4ldp2uM+Zw8sZdb5HHKgCuTaRL"
    "W5JB/XeC4k7RnKleNFiUUk1KzH2VL0Kcvartqd2uyFw9QQJOg0kEYbCKG2KJMln/iqZo6koqH2A1j7faj+XxdZd+21X1wEkVwHdFXorwoZQugl5X/Bq/rGFtL5VFRorWRhyFGyuQIDAQAB" )  ; ----- DKIM key peertube for example.com

Configuring a reverse proxy for Apache

In this final step we define a reverse proxy for the Apache web server that serves as the front-end for PeerTube (instead of Nginx). Here is what our virtual host configuration looks like:

<VirtualHost *:80>
ServerName peertube.example.com:80
ServerAdmin Dit e-mailadres wordt beveiligd tegen spambots. JavaScript dient ingeschakeld te zijn om het te bekijken.
SuexecUserGroup peertube peertube
DocumentRoot /home/peertube/web-peertube.example.com
<Directory /home/peertube/web-peertube.example.com>
  Require all granted
  Options FollowSymLinks
  AllowOverride AuthConfig FileInfo Options=Indexes Indexes Limit
  </Directory>
CustomLog /var/log/httpd/peertube/peertube.example.com-access_log combined
ErrorLog /var/log/httpd/peertube/peertube.example.com-error_log

# redirect to PeerTube over HTTPS
Redirect permanent "/" "https://peertube.example.com/"

</VirtualHost>
<VirtualHost 192.0.2.162:443>
ServerName peertube.example.com:443

LimitRequestBody 104857600

AllowEncodedSlashes NoDecode
ProxyPass / http://127.0.0.1:9000/ max=20 ttl=120 retry=300 timeout=120
ProxyPassReverse / http://127.0.0.1:9000/
ProxyPreserveHost on
RequestHeader set X-Forwarded-Port "443"
RequestHeader set X-Forwarded-Proto "https"

SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/peertube_example_com.crt
SSLCertificateKeyFile /etc/pki/tls/private/peertube.example.com.key
SSLCertificateChainFile /etc/pki/tls/certs/peertube_example_com.ca-bundle

</VirtualHost>
<VirtualHost [2001:db8::0113]:443>
ServerName peertube.example.com:443

LimitRequestBody 104857600

AllowEncodedSlashes NoDecode
ProxyPass / http://127.0.0.1:9000/ max=20 ttl=120 retry=300 timeout=120
ProxyPassReverse / http://127.0.0.1:9000/
ProxyPreserveHost on
RequestHeader set X-Forwarded-Port "443"
RequestHeader set X-Forwarded-Proto "https"

SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/peertube_example_com.crt
SSLCertificateKeyFile /etc/pki/tls/private/peertube.example.com.key
SSLCertificateChainFile /etc/pki/tls/certs/peertube_example_com.ca-bundle

</VirtualHost>

Accessing the PeerTube server

After all of this, the PeerTube site should be available here:

https://peertube.example.com/

And allow you to log in using the root password you created before.

Offerman PeerTube server

Making your PeerTube instance known to the Fediverse

After verifying that everything works as planned, this would also be a good time to make the existence of your new server known to the Fediverse by submitting it here:

https://instances.joinpeertube.org/instances

Plaats reactie

Security code Vernieuwen

Verstuur