Creating a Hestia template for Pertube

Hi everyone, I want to host PeerTube with Hestia , but I got a few difficulties with Nginx, in a simple way, my Peertube domain opens as one of the site domains in Hestia. I continue to test(I will change the domain, before that I used a subdomain, one domain with sites). I just decided to ask if it’s worth putting anything with Hestia at all? Thanks
I want to note that I don’t want to install PeerTube with Docker

Hi everyone, I tried different methods of Docker Peertube+Hestia, and didn’t get the result I want. In a simple way, I stop Nginx in Hestia to connect Peertube. And I changed the ports and forwarded them. But I don’t want Docker, I would like Hestia+Peertube to interact in the classic version of the installation. Now I installed Hestia+Peertube on the test server, but I get a page that is not secure http://angeltales.angellife.ru/. I added this domain to the Hestia panel, and I think that it looks like it’s worth creating a template for peertube(this is just a thought for now) so that peertube starts loading its page normally, and Hestia does its job.
As I can see during the classic Peertube installation a certificate was issued

Certificate is saved at: /etc/letsencrypt/live/angeltales.angellife.ru/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/angeltales.angellife.ru/privkey.pem
This certificate expires on 2025-07-23.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
2025-04-25 02:12:19,432:DEBUG:certbot._internal.display.obj:Notifying user: If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le

Additional folders were also created and the site(peertube) was enabled, with its config

ls /etc/nginx
conf.d  fastcgi_params  mime.types  modules  modules-enabled  nginx.conf  scgi_params  sites-available  sites-enabled  uwsgi_params
config peertube nginx
##лимит по колличество запросов, 1000 мс*60 сек(мин) делим на 300(rate=300r/m) = 200 мс(или 5 запросов в секунду)
limit_req_zone $limit_key zone=peertube:10m rate=300r/m;

## лимит подключения пo домену
limit_conn_zone $server_name zone=oservers:10m;

## ограничение количества соединений(по идее с 1 ip 1 соединение но В HTTP/2 и HTTP/3 каждый параллельный запрос считается отдельным соединением)
limit_conn_zone $limit_key zone=oaddr:10m;


geo $limit {
    default 1;               # По умолчанию — применять лимиты
    213.108.6.232 0;         # Для IP 213.108.6.232 — не применять лимиты
}

map $limit $limit_key {
    0 "";                     # Если $limit = 0, то limit_key пустой (разрешить)
    1 $binary_remote_addr;    # Если $limit = 1, то использовать IP-адрес клиента
}

quic_retry 					    on; #Эта директива включает механизм проверки адреса клиента при установлении соединения через QUIC. Если включено, сервер отправляет клиенту Retry-пакет, чтобы убедиться, что клиент действительно владеет указанным IP-адресом. Это помогает предотвратить атаки с подделкой IP-адресов (IP spoofing).
quic_gso on; #GSO позволяет объединять несколько пакетов в один большой сегмент, который затем разбивается на уровне сетевого драйвера

server {
  listen 80;
  listen [::]:80;
  server_name angeltales.angellive.ru;

  #nginx-ultimate-bad-bot-blocker
  include /etc/nginx/bots.d/blockbots.conf;
  include /etc/nginx/bots.d/ddos.conf;
      return 301 https://angeltales.angellive.ru$request_uri;


  location /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /var/www/certbot;
  }
  location / { return 301 https://$host$request_uri; }
}

upstream backend {
  server 127.0.0.1:9000;
}

server {
  listen 443 ssl;
  listen [::]:443 ssl;
  listen 443 quic reuseport;
  listen [::]:443 quic reuseport;

  server_name angeltales.angellive.ru;

  access_log /var/log/nginx/peertube.access.log; # reduce I/0 with buffer=10m flush=5m
  error_log  /var/log/nginx/peertube.error.log;

  ##Применяем ограничения ко всему серверу, с учетом исключений по IP

  ##лимит по колличество запросов, злая штука для HTTP2 и HTTP3
  limit_req zone=peertube burst=105 nodelay;
  limit_req_dry_run on; #тестовый режим
  limit_req_status 444; # вместо ответа 503
# limit_conn_log_level info | notice | warn | error; #изменить логи

  ##ограничение количества соединений(по IP в зависимости от протокола HTTP/2 и HTTP/3 каждый параллельный запрос считается отдельным соединением)
  limit_conn oaddr 50;
  limit_conn_dry_run on; #тестовый режим

  ## лимит подключения по домену
  limit_conn oservers 1000;
  limit_conn_status 429;#слишком много запросов(применяется ко всему limit_conn)

  ##
  # Certificates
  # you need a certificate to run in production. see https://letsencrypt.org/
  ##
  ssl_certificate     /etc/letsencrypt/live/angeltales.angellive.ru/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/angeltales.angellive.ru/privkey.pem;

  location ^~ '/.well-known/acme-challenge' {
    default_type "text/plain";
    root /var/www/certbot;
  }

  ##
  # Security hardening (as of Nov 15, 2020)
  # based on Mozilla Guideline v5.6
  ##

  ssl_protocols             TLSv1.3;
  ssl_prefer_server_ciphers on;
  ssl_ciphers               ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256; # add ECDHE-RSA-AES256-SHA if you want compatibility with Android 4
  ssl_session_timeout       1d; # defaults to 5m
  ssl_session_cache         shared:SSL:10m; # estimated to 40k sessions
  ssl_session_tickets       off;
  # HSTS (https://hstspreload.org), requires to be copied in 'location' sections that have add_header directives
  #add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";

  # ADD THE NGINX BAD BOT BLOCKER HERE (Please read full setup instructions)
  include /etc/nginx/bots.d/blockbots.conf;
  include /etc/nginx/bots.d/ddos.conf;

  # Advertise HTTP/3 support
  add_header Alt-Svc 'h3=":443"; ma=86400';
  add_header QUIC-Status $http3;

  # TLS 1.3 0-RTT anti-replay
  if ($anti_replay = 307) { return 307 https://$host$request_uri; }
  if ($anti_replay = 425) { return 425; }

  ##
  # Application
  ##

  location @api {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host            $host;
    proxy_set_header X-Real-IP       $remote_addr;

    client_max_body_size  100k; # default is 1M

    proxy_connect_timeout 10m;
    proxy_send_timeout    10m;
    proxy_read_timeout    10m;
    send_timeout          10m;

    proxy_pass http://backend;
  }

  location / {
    try_files /dev/null @api;
  }

  location ~ ^/api/v1/videos/(upload-resumable|([^/]+/source/replace-resumable))$ {
    client_max_body_size    0;
    proxy_request_buffering off;

    try_files /dev/null @api;
  }

  location ~ ^/api/v1/users/[^/]+/imports/import-resumable$ {
    client_max_body_size    0;
    proxy_request_buffering off;

    try_files /dev/null @api;
  }

  location ~ ^/api/v1/videos/(upload|([^/]+/studio/edit))$ {
    limit_except POST HEAD { deny all; }

    # This is the maximum upload size, which roughly matches the maximum size of a video file.
    # Note that temporary space is needed equal to the total size of all concurrent uploads.
    # This data gets stored in /var/lib/nginx by default, so you may want to put this directory
    # on a dedicated filesystem.
    client_max_body_size                      12G; # default is 1M
    add_header            X-File-Maximum-Size 8G always; # inform backend of the set value in bytes before mime-encoding (x * 1.4 >= client_max_body_size)

    try_files /dev/null @api;
  }

  location ~ ^/api/v1/runners/jobs/[^/]+/(update|success)$ {
    client_max_body_size                      12G; # default is 1M
    add_header            X-File-Maximum-Size 8G always; # inform backend of the set value in bytes before mime-encoding (x * 1.4 >= client_max_body_size)

    try_files /dev/null @api;
  }

  location ~ ^/api/v1/(videos|video-playlists|video-channels|users/me) {
    client_max_body_size                      6M; # default is 1M
    add_header            X-File-Maximum-Size 4M always; # inform backend of the set value in bytes before mime-encoding (x * 1.4 >= client_max_body_size)

    try_files /dev/null @api;
  }

  ##
  # Websocket
  ##

  location @api_websocket {
    proxy_http_version 1.1;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   Host            $host;
    proxy_set_header   X-Real-IP       $remote_addr;
    proxy_set_header   Upgrade         $http_upgrade;
    proxy_set_header   Connection      "upgrade";

    proxy_pass http://backend;
  }

  location /socket.io {
    try_files /dev/null @api_websocket;
  }

  location /tracker/socket {
    # Peers send a message to the tracker every 15 minutes
    # Don't close the websocket before then
    proxy_read_timeout 15m; # default is 60s

    try_files /dev/null @api_websocket;
  }

  # Plugin websocket routes
  location ~ ^/plugins/[^/]+(/[^/]+)?/ws/ {
    try_files /dev/null @api_websocket;
  }

  ##
  # Performance optimizations
  # For extra performance please refer to https://github.com/denji/nginx-tuning
  ##

  root /var/www/peertube/storage;

  # Enable compression for JS/CSS/HTML, for improved client load times.
  # It might be nice to compress JSON/XML as returned by the API, but
  # leaving that out to protect against potential BREACH attack.
  gzip              on;
  gzip_vary         on;
  gzip_types        # text/html is always compressed by HttpGzipModule
                    text/css
                    application/javascript
                    font/truetype
                    font/opentype
                    application/vnd.ms-fontobject
                    image/svg+xml
                    application/xml;
  gzip_min_length   1000; # default is 20 bytes
  gzip_buffers      16 8k;
  gzip_comp_level   2; # default is 1

  client_body_timeout       30s; # default is 60
  client_header_timeout     10s; # default is 60
  send_timeout              10s; # default is 60
  keepalive_timeout         10s; # default is 75
  resolver_timeout          10s; # default is 30
  reset_timedout_connection on;
  proxy_ignore_client_abort on;

  tcp_nopush                on; # send headers in one piece
  tcp_nodelay               on; # don't buffer data sent, good for small data bursts in real time

  # If you have a small /var/lib partition, it could be interesting to store temp nginx uploads in a different place
  # See https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_temp_path
  #client_body_temp_path /var/www/peertube/storage/nginx/;

  # Bypass PeerTube for performance reasons. Optional.
  # Should be consistent with client-overrides assets list in client.ts server controller
  location ~ ^/client/(assets/images/(icons/icon-36x36\.png|icons/icon-48x48\.png|icons/icon-72x72\.png|icons/icon-96x96\.png|icons/icon-144x144\.png|icons/icon-192x192\.png|icons/icon-512x512\.png|logo\.svg|favicon\.png|default-playlist\.jpg|default-avatar-account\.png|default-avatar-account-48x48\.png|default-avatar-video-channel\.png|default-avatar-video-channel-48x48\.png))$ {
    add_header Cache-Control "public, max-age=31536000, immutable"; # Cache 1 year

    root /var/www/peertube;

    try_files /storage/client-overrides/$1 /peertube-latest/client/dist/$1 @api;
  }

  # Bypass PeerTube for performance reasons. Optional.
  location ~ ^/client/(.*\.(js|css|png|svg|woff2|otf|ttf|woff|eot))$ {
    add_header Cache-Control "public, max-age=31536000, immutable"; # Cache 1 year

    alias /var/www/peertube/peertube-latest/client/dist/$1;
  }

  location ~ ^(/static/(webseed|web-videos|streaming-playlists/hls)/private/)|^/download {
    # We can't rate limit a try_files directive, so we need to duplicate @api

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host            $host;
    proxy_set_header X-Real-IP       $remote_addr;

    proxy_limit_rate 5M;

    proxy_pass http://backend;
  }

  # Bypass PeerTube for performance reasons. Optional.
  location ~ ^/static/(webseed|web-videos|redundancy|streaming-playlists)/ {
    limit_rate_after            5M;

    set $peertube_limit_rate  5M;

    # Use this line with nginx >= 1.17.0
    limit_rate $peertube_limit_rate;
    # Or this line with nginx < 1.17.0
    # set $limit_rate $peertube_limit_rate;

    if ($request_method = 'OPTIONS') {
      add_header Access-Control-Allow-Origin  '*';
      add_header Access-Control-Allow-Methods 'GET, OPTIONS';
      add_header Access-Control-Allow-Headers 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
      add_header Access-Control-Max-Age       1728000; # Preflight request can be cached 20 days
      add_header Content-Type                 'text/plain charset=UTF-8';
      add_header Content-Length               0;
      return 204;
    }

    if ($request_method = 'GET') {
      add_header Access-Control-Allow-Origin  '*';
      add_header Access-Control-Allow-Methods 'GET, OPTIONS';
      add_header Access-Control-Allow-Headers 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

    }

    # Enabling the sendfile directive eliminates the step of copying the data into the buffer
    # and enables direct copying data from one file descriptor to another.
    sendfile on;
    sendfile_max_chunk 1M; # prevent one fast connection from entirely occupying the worker process. should be > 800k.
    aio threads;

    # web-videos is the name of the directory mapped to the `storage.web_videos` key in your PeerTube configuration
    rewrite ^/static/webseed/(.*)$ /web-videos/$1 break;
    rewrite ^/static/(.*)$         /$1        break;

    try_files $uri @api;
  }
}

If someone is interested in helping me make friends with Hestia+Peertube, I will give you advice, or where to look. I really want to make them together on the same server. Thanks
I think that in order for peertube to function properly, you should create a template and put it in Hestia, or am I thinking wrong?)

Is it not possible to install it properly according to the official guidelines? Let me help you test it out.

Is it still there? You didn’t reply to me. I’m testing and keeping the steps!

I seem to be running successfully, but I’m not using port 9000 and can’t see.

root@debian:/home/peertube/web/demo.gdszjcd.cn/public_html/peertube-latest# sudo journalctl -feu peertube
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "syscall": "connect",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "address": "127.0.0.1",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "port": 6379
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:   }
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]: }
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]: [demo.gdszjcd.cn:443] 2025-04-26 14:20:26.644 error: Error in job queue events videos-views-stats. {
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:   "err": {
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "stack": "Error: connect ECONNREFUSED 127.0.0.1:6379\n    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1611:16)",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "message": "connect ECONNREFUSED 127.0.0.1:6379",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "errno": -111,
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "code": "ECONNREFUSED",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "syscall": "connect",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "address": "127.0.0.1",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "port": 6379
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:   }
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]: }
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]: [demo.gdszjcd.cn:443] 2025-04-26 14:20:26.645 error: Error in job worker videos-views-stats. {
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:   "err": {
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "stack": "Error: connect ECONNREFUSED 127.0.0.1:6379\n    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1611:16)",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "message": "connect ECONNREFUSED 127.0.0.1:6379",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "errno": -111,
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "code": "ECONNREFUSED",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "syscall": "connect",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "address": "127.0.0.1",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "port": 6379
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:   }
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]: }
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]: [demo.gdszjcd.cn:443] 2025-04-26 14:20:26.649 error: Error in job queue events video-file-import. {
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:   "err": {
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "stack": "Error: connect ECONNREFUSED 127.0.0.1:6379\n    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1611:16)",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "message": "connect ECONNREFUSED 127.0.0.1:6379",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "errno": -111,
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "code": "ECONNREFUSED",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "syscall": "connect",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "address": "127.0.0.1",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "port": 6379
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:   }
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]: }
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]: [demo.gdszjcd.cn:443] 2025-04-26 14:20:26.650 error: Error in job queue video-redundancy. {
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:   "err": {
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "stack": "Error: connect ECONNREFUSED 127.0.0.1:6379\n    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1611:16)",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "message": "connect ECONNREFUSED 127.0.0.1:6379",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "errno": -111,
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "code": "ECONNREFUSED",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "syscall": "connect",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "address": "127.0.0.1",
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:     "port": 6379
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]:   }
4月 26 14:20:26 debian.gdszjcd.cn peertube[470632]: }

Kindly do not share server or your personal details with anyone, especially over private messages. Also, please do not ask anyone for the details.

If you need to check here, if tested under Hestia, please note the /* */ section, it is subject to change

1 Like

Hello, let’s try to solve this problem. If we decide, it will be possible to add a PEERTUBE installation template to Hestia. Here are the steps of the installation

  1. Installation of Hestia in selected elements, but it is possible to complete, the Example.com changes to its
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh && sudo bash hst-install.sh --apache no --phpfpm yes --multiphp no --vsftpd no --proftpd no --named yes --mysql yes --mysql-classic no --postgresql no --exim yes --dovecot yes --sieve no --clamav no --spamassassin yes --iptables yes --fail2ban yes --quota no --api no --interactive yes --with-debs no  --port '2083' --hostname 'hestia.examle.com' --email '[email protected]' --password 'ArB5VYMZxA03IIoX3PJRwrJTb0KOhDWyjcBAtwYCel' --lang 'en' --force
  1. Peertube installation, in progress a. the user password is set, b. Sets the database password. c. changes are made to the file to automatically renew the certificate . Replace with authenticator = webroot
    webroot_path =/var/www/certbot will turn out like this
[renewalparams]
account = dd78b6ccfb47d92447da095c4ced1476
post_hook = systemctl restart nginx
authenticator = webroot
webroot_path = /var/www/certbot
server = https://acme-v02.api.letsencrypt.org/directory
key_type = ecdsa

The difference from the standard installation is adding folders for nginx, Hestia does not add them when installing. Replace peertube.example.com

sudo apt-get update && sudo apt-get upgrade -y && sudo apt full-upgrade && sudo sudo apt autoremove -y && sudo apt install lsb-release wget gnupg && echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/pgdg.gpg > /dev/null && sudo apt install nano && sudo dpkg-reconfigure locales && nano /etc/ssh/sshd_config && service ssh restart && fallocate -l 256M /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile && echo '/swapfile none swap sw 0 0' | tee -a /etc/fstab && sysctl vm.swappiness=10 && sysctl vm.vfs_cache_pressure=50 && echo -e "vm.swappiness = 10\nvm.vfs_cache_pressure = 50" | sudo tee -a /etc/sysctl.conf && sudo sysctl -p && apt-get install curl sudo unzip -y && curl -fsSL https://deb.nodesource.com/setup_20.x -o nodesource_setup.sh && sudo -E bash nodesource_setup.sh && sudo apt-get install nodejs -y && npm install --global yarn && sudo apt update -y && sudo apt install python3-dev python3-pip python-is-python3 -y && sudo apt update -y && sudo apt install certbot nginx ffmpeg postgresql postgresql-contrib openssl g++ make redis-server git cron wget -y && sudo systemctl start redis postgresql && sudo useradd -m -d /var/www/peertube -s /bin/bash -p peertube peertube && sudo passwd peertube && cd /var/www/peertube && sudo -u postgres createuser -P peertube && sudo -u postgres createdb -O peertube -E UTF8 -T template0 peertube_prod && sudo -u postgres psql -c "CREATE EXTENSION pg_trgm;" peertube_prod && sudo -u postgres psql -c "CREATE EXTENSION unaccent;" peertube_prod && VERSION=$(curl -s https://api.github.com/repos/chocobozzz/peertube/releases/latest | grep tag_name | cut -d '"' -f 4) && echo "Latest Peertube version is $VERSION" && sudo -u peertube mkdir config storage versions && sudo -u peertube chmod 750 config/ && cd /var/www/peertube/versions && sudo -u peertube wget -q "https://github.com/Chocobozzz/PeerTube/releases/download/${VERSION}/peertube-${VERSION}.zip" && sudo -u peertube unzip -q peertube-${VERSION}.zip && sudo -u peertube rm peertube-${VERSION}.zip && cd /var/www/peertube && sudo -u peertube ln -s versions/peertube-${VERSION} ./peertube-latest && cd ./peertube-latest && sudo -H -u peertube yarn install --production --pure-lockfile && cd /var/www/peertube && sudo -u peertube cp peertube-latest/config/default.yaml config/default.yaml && sudo -u peertube cp peertube-latest/config/production.yaml.example config/production.yaml && cd && sudo mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled && sudo cp /var/www/peertube/peertube-latest/support/nginx/peertube /etc/nginx/sites-available/peertube && sudo sed -i 's/${WEBSERVER_HOST}/peertube.example.com/g' /etc/nginx/sites-available/peertube && sudo sed -i 's/${PEERTUBE_HOST}/127.0.0.1:9000/g' /etc/nginx/sites-available/peertube && sudo ln -s /etc/nginx/sites-available/peertube /etc/nginx/sites-enabled/peertube && sudo systemctl stop nginx && sudo certbot certonly --standalone --post-hook "systemctl restart nginx" && sudo systemctl restart nginx && sudo nano /etc/letsencrypt/renewal/peertube.example.com.conf && sudo cp /var/www/peertube/peertube-latest/support/sysctl.d/30-peertube-tcp.conf /etc/sysctl.d/ && sudo sysctl -p /etc/sysctl.d/30-peertube-tcp.conf && sudo cp /var/www/peertube/peertube-latest/support/systemd/peertube.service /etc/systemd/system/ && sudo nano /etc/systemd/system/peertube.service && sudo systemctl daemon-reload && sudo systemctl enable peertube && sudo systemctl start peertube && sudo chmod -R 775 /var/www/peertube && echo "vm.overcommit_memory = 1" | sudo tee -a /etc/sysctl.conf && sudo sysctl -p && sudo apt-get clean && sudo apt-get autoclean
  1. Fix and put the PEERTUBE file with a configuration on the server, replace Example.com with your own, the database password coincides with the installed, and mail sending your letters to make your configuration production.yaml
    and put it in /var/www/peertube/config
    37 KB file on MEGA

I dont think peertube should be installed along hestia, if there is a docker, it would probaly make more sense - so you can just adjust proxy_path to it.

But the question is if you can install a self signed certificate or skip the lets encrypt part as this is usualy handled by hestia.

But over all, it probaly makes sense to install it on a dedicated vps.

1 Like

The fact is that this would be very good, since in DoCker Peertube is very limited, for example Nginx there is no way to configure as I would like. The classical version of the installation is recommended, and this is justified, as it gives much more the possibility of setting up for itself.

Yes, this is just an experiment out of interest). Rather, the user will have to be tied to PEERTUBE from Hestia, or maybe not, while I think)

Looks like Hestia is running successfully, please check the installation log I provided for details
@bestperson

Hestia and I have perfectly starting, but there is no access to Peertube, the Pertube server itself is in order, but Nginx proxy does not make it possible to combine all the difficulty in this.

You need to adjust and modify the nginx configuration of /home/peertube/conf/web/domain/, please refer to the installation log document I posted! Otherwise it doesn’t make any sense!

please do not suggest such thing, read the first 4 lines of your the configs you’re editing. It once again doesnt make sense.

There is no template loading for your domain, this is the default success message when you try to access the ip or there is no config for that specific domain. But as written, probaly better to install separated.

I understand, and yesterday I already tried to do it, but without successfully. I created a site in Hesatia, released a certificate and prescribed a new config /home/use/conf/web/angeltales.angellife.ru

server {
  listen 80;
  listen [::]:80;
  server_name angeltales.angellive.ru;


  location /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /var/www/certbot;
  }
  location / { return 301 https://$host$request_uri; }
}

upstream backend {
  server 127.0.0.1:9000;
}

server {
  listen 443 ssl;
  listen [::]:443 ssl;
  listen 443 quic;
  listen [::]:443 quic;

  server_name angeltales.angellive.ru;

  access_log /var/log/nginx/peertube.access.log; # reduce I/0 with buffer=10m flush=5m
  error_log  /var/log/nginx/peertube.error.log;

  ##Применяем ограничения ко всему серверу, с учетом исключений по IP

  ##лимит по колличество запросов, злая штука для HTTP2 и HTTP3
  limit_req zone=peertube burst=105 nodelay;
  limit_req_dry_run on; #тестовый режим
  limit_req_status 444; # вместо ответа 503
# limit_conn_log_level info | notice | warn | error; #изменить логи

  ##ограничение количества соединений(по IP в зависимости от протокола HTTP/2 и HTTP/3 каждый параллельный запрос считается отдельным соединением)
  limit_conn oaddr 50;
  limit_conn_dry_run on; #тестовый режим

  ## лимит подключения по домену
  limit_conn oservers 1000;
  limit_conn_status 429;#слишком много запросов(применяется ко всему limit_conn)

  ##
  # Certificates
  # you need a certificate to run in production. see https://letsencrypt.org/
  ##
   ssl_certificate     /home/Wm8kzUA53c8yteD/conf/web/angeltales.angellife.ru/ssl/angeltales.angellife.ru.pem;
   ssl_certificate_key /home/Wm8kzUA53c8yteD/conf/web/angeltales.angellife.ru/ssl/angeltales.angellife.ru.key;

	ssl_stapling        on;
	ssl_stapling_verify on;

	include /home/Wm8kzUA53c8yteD/conf/web/angeltales.angellive.ru/nginx.hsts.conf*;
	include /home/Wm8kzUA53c8yteD/conf/web/angeltales.angellive.ru/nginx.ssl.conf_*;

  location ^~ '/.well-known/acme-challenge' {
    default_type "text/plain";
    root /var/www/certbot;
  }

  ##
  # Security hardening (as of Nov 15, 2020)
  # based on Mozilla Guideline v5.6
  ##

  ssl_protocols             TLSv1.3;
  ssl_prefer_server_ciphers on;
  ssl_ciphers               ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256; # add ECDHE-RSA-AES256-SHA if you want compatibility with Android 4
  # HSTS (https://hstspreload.org), requires to be copied in 'location' sections that have add_header directives
  #add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";


  # Advertise HTTP/3 support
  add_header Alt-Svc 'h3=":443"; ma=86400';
  add_header QUIC-Status $http3;

  # TLS 1.3 0-RTT anti-replay
  if ($anti_replay = 307) { return 307 https://$host$request_uri; }
  if ($anti_replay = 425) { return 425; }

  ##
  # Application
  ##

  location @api {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host            $host;
    proxy_set_header X-Real-IP       $remote_addr;

    client_max_body_size  100k; # default is 1M

    proxy_connect_timeout 10m;
    proxy_send_timeout    10m;
    proxy_read_timeout    10m;
    send_timeout          10m;

    proxy_pass http://backend;
  }

  location / {
    try_files /dev/null @api;
  }

  location ~ ^/api/v1/videos/(upload-resumable|([^/]+/source/replace-resumable))$ {
    client_max_body_size    0;
    proxy_request_buffering off;

    try_files /dev/null @api;
  }

  location ~ ^/api/v1/users/[^/]+/imports/import-resumable$ {
    client_max_body_size    0;
    proxy_request_buffering off;

    try_files /dev/null @api;
  }

  location ~ ^/api/v1/videos/(upload|([^/]+/studio/edit))$ {
    limit_except POST HEAD { deny all; }

    # This is the maximum upload size, which roughly matches the maximum size of a video file.
    # Note that temporary space is needed equal to the total size of all concurrent uploads.
    # This data gets stored in /var/lib/nginx by default, so you may want to put this directory
    # on a dedicated filesystem.
    client_max_body_size                      12G; # default is 1M
    add_header            X-File-Maximum-Size 8G always; # inform backend of the set value in bytes before mime-encoding (x * 1.4 >= client_max_body_size)

    try_files /dev/null @api;
  }

  location ~ ^/api/v1/runners/jobs/[^/]+/(update|success)$ {
    client_max_body_size                      12G; # default is 1M
    add_header            X-File-Maximum-Size 8G always; # inform backend of the set value in bytes before mime-encoding (x * 1.4 >= client_max_body_size)

    try_files /dev/null @api;
  }

  location ~ ^/api/v1/(videos|video-playlists|video-channels|users/me) {
    client_max_body_size                      6M; # default is 1M
    add_header            X-File-Maximum-Size 4M always; # inform backend of the set value in bytes before mime-encoding (x * 1.4 >= client_max_body_size)

    try_files /dev/null @api;
  }

  ##
  # Websocket
  ##

  location @api_websocket {
    proxy_http_version 1.1;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   Host            $host;
    proxy_set_header   X-Real-IP       $remote_addr;
    proxy_set_header   Upgrade         $http_upgrade;
    proxy_set_header   Connection      "upgrade";

    proxy_pass http://backend;
  }

  location /socket.io {
    try_files /dev/null @api_websocket;
  }

  location /tracker/socket {
    # Peers send a message to the tracker every 15 minutes
    # Don't close the websocket before then
    proxy_read_timeout 15m; # default is 60s

    try_files /dev/null @api_websocket;
  }

  # Plugin websocket routes
  location ~ ^/plugins/[^/]+(/[^/]+)?/ws/ {
    try_files /dev/null @api_websocket;
  }

  ##
  # Performance optimizations
  # For extra performance please refer to https://github.com/denji/nginx-tuning
  ##

  root /var/www/peertube/storage;

  # Enable compression for JS/CSS/HTML, for improved client load times.
  # It might be nice to compress JSON/XML as returned by the API, but
  # leaving that out to protect against potential BREACH attack.
  gzip              on;
  gzip_vary         on;
  gzip_types        # text/html is always compressed by HttpGzipModule
                    text/css
                    application/javascript
                    font/truetype
                    font/opentype
                    application/vnd.ms-fontobject
                    image/svg+xml
                    application/xml;
  gzip_min_length   1000; # default is 20 bytes
  gzip_buffers      16 8k;
  gzip_comp_level   2; # default is 1

  client_body_timeout       30s; # default is 60
  client_header_timeout     10s; # default is 60
  send_timeout              10s; # default is 60
  keepalive_timeout         10s; # default is 75
  resolver_timeout          10s; # default is 30
  reset_timedout_connection on;
  proxy_ignore_client_abort on;

  tcp_nopush                on; # send headers in one piece
  tcp_nodelay               on; # don't buffer data sent, good for small data bursts in real time

  # If you have a small /var/lib partition, it could be interesting to store temp nginx uploads in a different place
  # See https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_temp_path
  #client_body_temp_path /var/www/peertube/storage/nginx/;

  # Bypass PeerTube for performance reasons. Optional.
  # Should be consistent with client-overrides assets list in client.ts server controller
  location ~ ^/client/(assets/images/(icons/icon-36x36\.png|icons/icon-48x48\.png|icons/icon-72x72\.png|icons/icon-96x96\.png|icons/icon-144x144\.png|icons/icon-192x192\.png|icons/icon-512x512\.png|logo\.svg|favicon\.png|default-playlist\.jpg|default-avatar-account\.png|default-avatar-account-48x48\.png|default-avatar-video-channel\.png|default-avatar-video-channel-48x48\.png))$ {
    add_header Cache-Control "public, max-age=31536000, immutable"; # Cache 1 year

    root /var/www/peertube;

    try_files /storage/client-overrides/$1 /peertube-latest/client/dist/$1 @api;
  }

  # Bypass PeerTube for performance reasons. Optional.
  location ~ ^/client/(.*\.(js|css|png|svg|woff2|otf|ttf|woff|eot))$ {
    add_header Cache-Control "public, max-age=31536000, immutable"; # Cache 1 year

    alias /var/www/peertube/peertube-latest/client/dist/$1;
  }

  location ~ ^(/static/(webseed|web-videos|streaming-playlists/hls)/private/)|^/download {
    # We can't rate limit a try_files directive, so we need to duplicate @api

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host            $host;
    proxy_set_header X-Real-IP       $remote_addr;

    proxy_limit_rate 5M;

    proxy_pass http://backend;
  }

  # Bypass PeerTube for performance reasons. Optional.
  location ~ ^/static/(webseed|web-videos|redundancy|streaming-playlists)/ {
    limit_rate_after            5M;

    set $peertube_limit_rate  5M;

    # Use this line with nginx >= 1.17.0
    limit_rate $peertube_limit_rate;
    # Or this line with nginx < 1.17.0
    # set $limit_rate $peertube_limit_rate;

    if ($request_method = 'OPTIONS') {
      add_header Access-Control-Allow-Origin  '*';
      add_header Access-Control-Allow-Methods 'GET, OPTIONS';
      add_header Access-Control-Allow-Headers 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
      add_header Access-Control-Max-Age       1728000; # Preflight request can be cached 20 days
      add_header Content-Type                 'text/plain charset=UTF-8';
      add_header Content-Length               0;
      return 204;
    }

    if ($request_method = 'GET') {
      add_header Access-Control-Allow-Origin  '*';
      add_header Access-Control-Allow-Methods 'GET, OPTIONS';
      add_header Access-Control-Allow-Headers 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

    }

    # Enabling the sendfile directive eliminates the step of copying the data into the buffer
    # and enables direct copying data from one file descriptor to another.
    sendfile on;
    sendfile_max_chunk 1M; # prevent one fast connection from entirely occupying the worker process. should be > 800k.
    aio threads;

    # web-videos is the name of the directory mapped to the `storage.web_videos` key in your PeerTube configuration
    rewrite ^/static/webseed/(.*)$ /web-videos/$1 break;
    rewrite ^/static/(.*)$         /$1        break;

    try_files $uri @api;
  }
}

You need to know how hestia and templates are working: Web Templates and FastCGI/Proxy Cache | Hestia Control Panel

So you need to create a own template and tske it for the related domain.

That’s right, I initially wrote this in the first post, but I just did not come up with how to create such a template). Thank you

Should be all written in the docs.

1 Like

I’ll look a little later in detail, thanks

If possible! You can ask for help from the community if you need it! For example, a certain section needs to determine the directory where Hestia is located