diff --git a/src/freedombone-app-peertube b/src/freedombone-app-peertube index 3095195c356761ae1c5c9e809b64920b6c70186a..037f1eef2aff3975685169839e0fb88c2717fe49 100755 --- a/src/freedombone-app-peertube +++ b/src/freedombone-app-peertube @@ -34,15 +34,18 @@ VARIANTS="full full-vim media" IN_DEFAULT_INSTALL=0 SHOW_ON_ABOUT=1 NOT_ON_ONION=1 +NOT_ON_ARM=1 PEERTUBE_DOMAIN_NAME= PEERTUBE_CODE= -PEERTUBE_REPO="https://github.com/Chocobozzz/PeerTube" -PEERTUBE_COMMIT='6e5a785b20230ff5457632361a893d814b53c95e' +PEERTUBE_VERSION='v1.0.0' +PEERTUBE_DOWNLOAD_FILENAME="peertube-${PEERTUBE_VERSION}.tar.xz" +PEERTUBE_DOWNLOAD="https://github.com/Chocobozzz/PeerTube/releases/download/${PEERTUBE_VERSION}/peertube-${PEERTUBE_VERSION}.tar.xz" PEERTUBE_ONION_PORT=8136 PEERTUBE_PORT=9004 MESH_PEERTUBE_PORT=8500 PEERTUBE_DIR=/etc/peertube +PEERTUBE_CONFIG_FILE=$PEERTUBE_DIR/config/production.yaml PEERTUBE_SHORT_DESCRIPTION=$'Video broadcast' PEERTUBE_DESCRIPTION=$'Video broadcast' @@ -58,8 +61,8 @@ peertube_variables=(PEERTUBE_DOMAIN_NAME MY_EMAIL_ADDRESS) function peertube_tcp_tuning { - if [ -f "$PEERTUBE_DIR/support/sysctl.d/30-peertube-tcp.conf" ]; then - cp "$PEERTUBE_DIR/support/sysctl.d/30-peertube-tcp.conf" /etc/sysctl.d/ + if [ -f "$PEERTUBE_DIR/peertube-latest/support/sysctl.d/30-peertube-tcp.conf" ]; then + cp "$PEERTUBE_DIR/peertube-latest/support/sysctl.d/30-peertube-tcp.conf" /etc/sysctl.d/ sysctl -p /etc/sysctl.d/30-peertube-tcp.conf fi } @@ -68,12 +71,12 @@ function peertube_setting_registration { allow_registrations="$1" if [[ "$allow_registrations" == '1' ]]; then - sed -i "0,/enabled:.*/s//enabled: false/" $PEERTUBE_DIR/config/production.yaml + sed -i "0,/enabled:.*/s//enabled: false/" ${PEERTUBE_CONFIG_FILE} systemctl restart peertube fi if [[ "$allow_registrations" == '0' ]]; then - sed -i "0,/enabled:.*/s//enabled: true/" $PEERTUBE_DIR/config/production.yaml + sed -i "0,/enabled:.*/s//enabled: true/" ${PEERTUBE_CONFIG_FILE} systemctl restart peertube fi } @@ -111,7 +114,7 @@ function peertube_import_from_syncthing { echo "if [ ! -f \$search_dir/login.txt ]; then"; echo ' exit 0'; echo 'fi'; - echo "import_script=${PEERTUBE_DIR}/dist/server/tools/upload.js"; + echo "import_script=${PEERTUBE_DIR}/peertube-latest/dist/server/tools/upload.js"; echo "if [ ! -f \$import_script ]; then"; echo ' exit 0'; echo 'fi'; @@ -182,6 +185,7 @@ function peertube_create_database { run_system_query_postgresql "CREATE DATABASE peertube OWNER peertube;" run_system_query_postgresql "GRANT ALL PRIVILEGES ON DATABASE peertube to peertube;" run_system_query_postgresql "set statement_timeout to 40000;" + peertube_database_extensions } function logging_on_peertube { @@ -194,7 +198,7 @@ function logging_off_peertube { function remove_user_peertube { echo -n '' -# remove_username="$1" + # remove_username="$1" } function add_user_peertube { @@ -203,8 +207,8 @@ function add_user_peertube { return fi -# new_username="$1" -# new_user_password="$2" + # new_username="$1" + # new_user_password="$2" echo '0' } @@ -235,7 +239,7 @@ function peertube_set_admin_email { 0) peertube_email=$(<"$data") if [[ "$peertube_email" != *' '* && "$peertube_email" != *','* && "$peertube_email" != *';'* && "$peertube_email" == *'@'* && "$peertube_email" == *'.'* ]]; then if [ ${#peertube_email} -gt 8 ]; then - sed -i "s|email:.*|email: '${peertube_email}'|g" $PEERTUBE_DIR/config/production.yaml + sed -i "s|email:.*|email: '${peertube_email}'|g" ${PEERTUBE_CONFIG_FILE} systemctl restart peertube dialog --title $"Set PeerTube administrator email address" \ --msgbox $"Set to $peertube_email" 6 75 @@ -252,8 +256,8 @@ function peertube_disable_signups { --yesno $"\\nDo you wish to disable further PeerTube signups?" 8 75 sel=$? case $sel in - 0) sed -i "0,/enabled:.*/s//enabled: false/" $PEERTUBE_DIR/config/production.yaml;; - 1) sed -i "0,/enabled:.*/s//enabled: true/" $PEERTUBE_DIR/config/production.yaml;; + 0) sed -i "0,/enabled:.*/s//enabled: false/" ${PEERTUBE_CONFIG_FILE};; + 1) sed -i "0,/enabled:.*/s//enabled: true/" ${PEERTUBE_CONFIG_FILE};; 255) return;; esac @@ -306,7 +310,7 @@ function peertube_import_from_file { fi cd $PEERTUBE_DIR || exit 32468356 - import_script=$PEERTUBE_DIR/dist/server/tools/upload.js + import_script=$PEERTUBE_DIR/peertube-latest/dist/server/tools/upload.js if [ ! -f $import_script ]; then dialog --title $"Import videos" \ --msgbox $"upload script was not found" 6 75 @@ -388,7 +392,7 @@ function peertube_import_videos { fi cd $PEERTUBE_DIR || exit 32468356 - import_script=$PEERTUBE_DIR/dist/server/tools/import-videos.js + import_script=$PEERTUBE_DIR/peertube-latest/dist/server/tools/import-videos.js # default to downloading as webm sed -i "s|'.mp4'|'.webm'|g" $import_script @@ -430,7 +434,7 @@ function configure_interactive_peertube { } function change_password_peertube { -# PEERTUBE_USERNAME="$1" + # PEERTUBE_USERNAME="$1" PEERTUBE_PASSWORD="$2" if [ ${#PEERTUBE_PASSWORD} -lt 8 ]; then echo $'Peertube password is too short' @@ -443,11 +447,17 @@ function reconfigure_peertube { echo -n '' } +function peertube_database_extensions { + cd /etc/postgresql || exit 34586356 + sudo -u postgres psql peertube -c 'CREATE EXTENSION IF NOT EXISTS unaccent;' + sudo -u postgres psql peertube -c 'CREATE EXTENSION IF NOT EXISTS pg_trgm;' +} + function upgrade_peertube { peertube_import_from_syncthing - CURR_PEERTUBE_COMMIT=$(get_completion_param "peertube commit") - if [[ "$CURR_PEERTUBE_COMMIT" == "$PEERTUBE_COMMIT" ]]; then + CURR_PEERTUBE_VERSION=$(get_completion_param "peertube version") + if [[ "$CURR_PEERTUBE_VERSION" == "$PEERTUBE_VERSION" ]]; then return fi @@ -455,51 +465,41 @@ function upgrade_peertube { systemctl stop peertube cd "$PEERTUBE_DIR" || exit 7824552627 - function_check set_repo_commit - set_repo_commit $PEERTUBE_DIR "peertube commit" "$PEERTUBE_COMMIT" $PEERTUBE_REPO - if ! npm install -g yarn@1.10.1; then echo $'Failed to install yarn' exit 79353234 fi - yarn add -D webpack --network-concurrency 1 - if ! yarn install; then - echo $'Failed to run yarn install' - exit 63754235 - fi - if ! npm install -g npm@4; then - # https://github.com/KraigM/homebridge-harmonyhub/issues/119 - echo $'Failed to downgrade npm' - npm install -g "npm@${NPM_VERSION}" - cp /root/.npm-global/bin/npm /usr/local/bin/npm - exit 3476835 - fi - cp /root/.npm-global/bin/npm /usr/local/bin/npm - if ! npm install; then - echo $'Failed to install peertube' - npm install -g "npm@${NPM_VERSION}" - cp /root/.npm-global/bin/npm /usr/local/bin/npm - exit 7835243 - fi - if ! npm install -g "npm@${NPM_VERSION}"; then - echo $'Failed to restore npm after downgrade' - exit 5737583 + + mkdir -p $PEERTUBE_DIR + cd $PEERTUBE_DIR || exit 356835 + cd versions || exit 3576835 + + wget -q "$PEERTUBE_DOWNLOAD" -O "$PEERTUBE_DOWNLOAD_FILENAME" + if [ ! -f "$PEERTUBE_DOWNLOAD_FILENAME" ]; then + exit 56874674 fi - cp /root/.npm-global/bin/npm /usr/local/bin/npm - npm run build + unxz "$PEERTUBE_DOWNLOAD_FILENAME" + rm "$PEERTUBE_DOWNLOAD_FILENAME" + + cd ../ || exit 356385 + ln -s "versions/peertube-${VERSION}" ./peertube-latest + cd ./peertube-latest || exit 35685 + chown -R peertube:peertube $PEERTUBE_DIR + + sudo -H -u peertube yarn install --production --pure-lockfile + + peertube_tcp_tuning # This doesn't appear to work #sudo -u peertube ./upgrade.sh $PEERTUBE_DIR chown -R peertube:peertube $PEERTUBE_DIR - cd /etc/postgresql || exit 34586356 - sudo -u postgres psql peertube -c 'CREATE EXTENSION IF NOT EXISTS unaccent;' - sudo -u postgres psql peertube -c 'CREATE EXTENSION IF NOT EXISTS pg_trgm;' - - peertube_tcp_tuning + peertube_database_extensions systemctl start peertube + + set_completion_param "peertube version" "$PEERTUBE_VERSION" } function backup_local_peertube { @@ -514,7 +514,7 @@ function backup_local_peertube { backup_database_to_usb peertube systemctl start peertube - peertube_path=$PEERTUBE_DIR/videos + peertube_path=$PEERTUBE_DIR/storage/videos if [ -d $peertube_path ]; then suspend_site "${PEERTUBE_DOMAIN_NAME}" systemctl stop peertube @@ -540,10 +540,10 @@ function restore_local_peertube { function_check restore_directory_from_usb restore_directory_from_usb $temp_restore_dir peertubevideos if [ -d $temp_restore_dir ]; then - if [ -d $temp_restore_dir$PEERTUBE_DIR/videos ]; then - cp -r $temp_restore_dir$PEERTUBE_DIR/videos/* $PEERTUBE_DIR/videos/ + if [ -d $temp_restore_dir$PEERTUBE_DIR/storage/videos ]; then + cp -r $temp_restore_dir$PEERTUBE_DIR/storage/videos/* $PEERTUBE_DIR/storage/videos/ else - cp -r $temp_restore_dir/* $PEERTUBE_DIR/videos/ + cp -r $temp_restore_dir/* $PEERTUBE_DIR/storage/videos/ fi chown -R peertube:peertube $PEERTUBE_DIR rm -rf $temp_restore_dir @@ -575,6 +575,9 @@ function remove_peertube { function_check remove_nodejs remove_nodejs peertube + rm /etc/sysctl.d/30-peertube-tcp.conf + sysctl -p -q + read_config_param "PEERTUBE_DOMAIN_NAME" nginx_dissite "$PEERTUBE_DOMAIN_NAME" remove_certs "${PEERTUBE_DOMAIN_NAME}" @@ -620,34 +623,98 @@ function peertube_setup_web { { echo 'server {'; echo ' listen 80;'; echo ' listen [::]:80;'; - echo " server_name $PEERTUBE_DOMAIN_NAME;"; - echo " rewrite ^ https://\$server_name\$request_uri? permanent;"; + echo " server_name ${PEERTUBE_DOMAIN_NAME};"; + echo ''; + echo " access_log /var/log/nginx/${PEERTUBE_DOMAIN_NAME}.access.log;"; + echo " error_log /var/log/nginx/${PEERTUBE_DOMAIN_NAME}.error.log;"; + echo ''; + echo " location / { return 301 https://\$host\$request_uri; }"; echo '}'; echo ''; echo 'server {'; echo ' listen 443 ssl http2;'; - echo ' #listen [::]:443 ssl http2;'; - echo " server_name $PEERTUBE_DOMAIN_NAME;"; - echo ''; } > "$peertube_nginx_file" - function_check nginx_ssl - nginx_ssl "$PEERTUBE_DOMAIN_NAME" mobile - - function_check nginx_security_options - nginx_security_options "$PEERTUBE_DOMAIN_NAME" - - { echo ' add_header Strict-Transport-Security max-age=15768000;'; + echo ' listen [::]:443 ssl http2;'; + echo " server_name ${PEERTUBE_DOMAIN_NAME};"; + echo ''; + echo ' # For example with certbot (you need a certificate to run https)'; + echo " ssl_certificate /etc/letsencrypt/live/${PEERTUBE_DOMAIN_NAME}/fullchain.pem;"; + echo " ssl_certificate_key /etc/letsencrypt/live/${PEERTUBE_DOMAIN_NAME}/privkey.pem;"; + echo ''; + echo ' ssl_protocols TLSv1.2; # TLSv1.3, TLSv1.2 if nginx >= 1.13.0'; + echo ' ssl_prefer_server_ciphers on;'; + echo " 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';"; + echo ' ssl_ecdh_curve secp384r1;'; + echo ' ssl_session_timeout 10m;'; + echo ' ssl_session_cache shared:SSL:10m;'; + echo ' ssl_session_tickets off;'; + echo ''; + echo ' # Enable compression for JS/CSS/HTML bundle, for improved client load times.'; + echo ' # It might be nice to compress JSON, but leaving that out to protect against potential'; + echo ' # compression+encryption information leak attacks like BREACH.'; + echo ' gzip on;'; + echo ' gzip_types text/css text/html application/javascript;'; + echo ' gzip_vary on;'; + echo ''; + echo ' # Enable HSTS' + echo ' # Tells browsers to stick with HTTPS and never visit the insecure HTTP'; + echo ' # version. Once a browser sees this header, it will only visit the site over'; + echo ' # HTTPS for the next 2 years: (read more on hstspreload.org)'; + echo ' add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";'; + echo ''; + echo ' access_log /dev/null;'; + echo ' error_log /dev/null;'; + echo ''; + echo ' # Bypass PeerTube for performance reasons. Could be removed'; + echo " location ~ ^/client/(.*\\.(js|css|woff2|otf|ttf|woff|eot))\$ {"; + echo " add_header Cache-Control \"public, max-age=31536000, immutable\";"; + echo ''; + echo " alias $PEERTUBE_DIR/peertube-latest/client/dist/\$1;"; + echo ' }'; + echo ''; + echo ' # Bypass PeerTube for performance reasons. Could be removed'; + echo ' location ~ ^/static/(thumbnails|avatars)/ {'; + echo " if (\$request_method = 'OPTIONS') {"; + echo " add_header 'Access-Control-Allow-Origin' '*';"; + echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; + echo " add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';"; + echo " add_header 'Access-Control-Max-Age' 1728000;"; + echo " add_header 'Content-Type' 'text/plain charset=UTF-8';"; + echo " add_header 'Content-Length' 0;"; + echo ' return 204;'; + echo ' }'; + echo ''; + echo " add_header 'Access-Control-Allow-Origin' '*';"; + echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; + echo " add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';"; + echo ''; + echo ' # Cache 2 hours'; + echo ' add_header Cache-Control "public, max-age=7200";'; + echo ''; + echo " root $PEERTUBE_DIR/storage;"; + echo ''; + echo " rewrite ^/static/(thumbnails|avatars)/(.*)\$ /\$1/\$2 break;"; + echo " try_files \$uri /;"; + echo ' }'; echo ''; echo ' location / {'; - echo " proxy_pass http://localhost:${PEERTUBE_PORT};"; + echo " proxy_pass http://localhost:$PEERTUBE_PORT;"; echo " proxy_set_header X-Real-IP \$remote_addr;"; echo " proxy_set_header Host \$host;"; echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"; echo ''; - echo ' # For the video upload'; - echo ' client_max_body_size 2G;'; + echo ' # Hard limit, PeerTube does not support videos > 8GB'; + echo ' client_max_body_size 8G;'; + echo ' proxy_connect_timeout 600;'; + echo ' proxy_send_timeout 600;'; + echo ' proxy_read_timeout 600;'; + echo ' send_timeout 600;'; echo ' }'; echo ''; + echo ' # Bypass PeerTube for performance reasons. Could be removed'; echo ' location /static/webseed {'; + echo ' # Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client'; + echo ' limit_rate 800k;'; + echo ''; echo " if (\$request_method = 'OPTIONS') {"; echo " add_header 'Access-Control-Allow-Origin' '*';"; echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; @@ -662,9 +729,12 @@ function peertube_setup_web { echo " add_header 'Access-Control-Allow-Origin' '*';"; echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; echo " add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';"; + echo ''; + echo ' # Dont spam access log file with byte range requests'; + echo ' access_log off;'; echo ' }'; echo ''; - echo " alias $PEERTUBE_DIR/videos;"; + echo " alias $PEERTUBE_DIR/storage/videos;"; echo ' }'; echo ''; echo ' # Websocket tracker'; @@ -673,13 +743,13 @@ function peertube_setup_web { echo ' # Dont close the websocket before this time'; echo ' proxy_read_timeout 1200s;'; echo " proxy_set_header Upgrade \$http_upgrade;"; - echo ' proxy_set_header Connection "upgrade";'; + echo " proxy_set_header Connection \"upgrade\";"; echo ' proxy_http_version 1.1;'; echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"; echo " proxy_set_header Host \$host;"; - echo " proxy_pass http://localhost:${PEERTUBE_PORT};"; + echo " proxy_pass http://localhost:$PEERTUBE_PORT;"; echo ' }'; - echo '}'; } >> "$peertube_nginx_file" + echo '}'; } > "$peertube_nginx_file" else echo -n '' > "$peertube_nginx_file" fi @@ -688,17 +758,25 @@ function peertube_setup_web { echo ' port_in_redirect off;'; echo " server_name $PEERTUBE_ONION_HOSTNAME;"; echo ''; - echo ' location / {'; - echo " proxy_pass http://localhost:${PEERTUBE_PORT};"; - echo " proxy_set_header X-Real-IP \$remote_addr;"; - echo " proxy_set_header Host \$host;"; - echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"; + echo ' # Enable compression for JS/CSS/HTML bundle, for improved client load times.'; + echo ' # It might be nice to compress JSON, but leaving that out to protect against potential'; + echo ' # compression+encryption information leak attacks like BREACH.'; + echo ' gzip on;'; + echo ' gzip_types text/css text/html application/javascript;'; + echo ' gzip_vary on;'; echo ''; - echo ' # For the video upload'; - echo ' client_max_body_size 2G;'; + echo ' access_log /dev/null;'; + echo ' error_log /dev/null;'; + echo ''; + echo ' # Bypass PeerTube for performance reasons. Could be removed'; + echo " location ~ ^/client/(.*\\.(js|css|woff2|otf|ttf|woff|eot))\$ {"; + echo " add_header Cache-Control \"public, max-age=31536000, immutable\";"; + echo ''; + echo " alias $PEERTUBE_DIR/peertube-latest/client/dist/\$1;"; echo ' }'; echo ''; - echo ' location /static/webseed {'; + echo ' # Bypass PeerTube for performance reasons. Could be removed'; + echo ' location ~ ^/static/(thumbnails|avatars)/ {'; echo " if (\$request_method = 'OPTIONS') {"; echo " add_header 'Access-Control-Allow-Origin' '*';"; echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; @@ -709,59 +787,38 @@ function peertube_setup_web { echo ' return 204;'; echo ' }'; echo ''; - echo " if (\$request_method = 'GET') {"; - echo " add_header 'Access-Control-Allow-Origin' '*';"; - echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; - echo " add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';"; - echo ' }'; + echo " add_header 'Access-Control-Allow-Origin' '*';"; + echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; + echo " add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';"; echo ''; - echo " alias $PEERTUBE_DIR/videos;"; - echo ' }'; + echo ' # Cache 2 hours'; + echo ' add_header Cache-Control "public, max-age=7200";'; echo ''; - echo ' # Websocket tracker'; - echo ' location /tracker/socket {'; - echo ' # Peers send a message to the tracker every 15 minutes'; - echo ' # Dont close the websocket before this time'; - echo ' proxy_read_timeout 1200s;'; - echo " proxy_set_header Upgrade \$http_upgrade;"; - echo ' proxy_set_header Connection "upgrade";'; - echo ' proxy_http_version 1.1;'; - echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"; - echo " proxy_set_header Host \$host;"; - echo " proxy_pass http://localhost:${PEERTUBE_PORT};"; + echo " root $PEERTUBE_DIR/storage;"; + echo ''; + echo " rewrite ^/static/(thumbnails|avatars)/(.*)\$ /\$1/\$2 break;"; + echo " try_files \$uri /;"; echo ' }'; - echo '}'; } >> "$peertube_nginx_file" - - # CSP currently causes an error - sed -i '/Content-Security-Policy/d' "$peertube_nginx_file" - - function_check create_site_certificate - create_site_certificate "$PEERTUBE_DOMAIN_NAME" 'yes' - - function_check nginx_ensite - nginx_ensite "$PEERTUBE_DOMAIN_NAME" -} - -function mesh_peertube_setup_web { - # shellcheck disable=SC2154 - peertube_nginx_file=$rootdir/etc/nginx/sites-available/peertube - - { echo 'server {'; - echo " listen $MESH_PEERTUBE_PORT http2;"; - echo " listen [::]:\$MESH_PEERTUBE_PORT http2;"; - echo " server_name \$HOSTNAME;"; echo ''; echo ' location / {'; - echo " proxy_pass http://localhost:${PEERTUBE_PORT};"; + echo " proxy_pass http://localhost:$PEERTUBE_PORT;"; echo " proxy_set_header X-Real-IP \$remote_addr;"; echo " proxy_set_header Host \$host;"; echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"; echo ''; - echo ' # For the video upload'; - echo ' client_max_body_size 2G;'; + echo ' # Hard limit, PeerTube does not support videos > 8GB'; + echo ' client_max_body_size 8G;'; + echo ' proxy_connect_timeout 600;'; + echo ' proxy_send_timeout 600;'; + echo ' proxy_read_timeout 600;'; + echo ' send_timeout 600;'; echo ' }'; echo ''; + echo ' # Bypass PeerTube for performance reasons. Could be removed'; echo ' location /static/webseed {'; + echo ' # Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client'; + echo ' limit_rate 800k;'; + echo ''; echo " if (\$request_method = 'OPTIONS') {"; echo " add_header 'Access-Control-Allow-Origin' '*';"; echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; @@ -776,9 +833,12 @@ function mesh_peertube_setup_web { echo " add_header 'Access-Control-Allow-Origin' '*';"; echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; echo " add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';"; + echo ''; + echo ' # Dont spam access log file with byte range requests'; + echo ' access_log off;'; echo ' }'; echo ''; - echo " alias $PEERTUBE_DIR/videos;"; + echo " alias $PEERTUBE_DIR/storage/videos;"; echo ' }'; echo ''; echo ' # Websocket tracker'; @@ -791,35 +851,46 @@ function mesh_peertube_setup_web { echo ' proxy_http_version 1.1;'; echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"; echo " proxy_set_header Host \$host;"; - echo " proxy_pass http://localhost:${PEERTUBE_PORT};"; + echo " proxy_pass http://localhost:$PEERTUBE_PORT;"; echo ' }'; - echo '}'; } > "$peertube_nginx_file" + echo '}'; } >> "$peertube_nginx_file" + + function_check create_site_certificate + create_site_certificate "$PEERTUBE_DOMAIN_NAME" 'yes' + + function_check nginx_ensite + nginx_ensite "$PEERTUBE_DOMAIN_NAME" +} + +function mesh_peertube_setup_web { + # TODO + echo -n '' } function peertube_create_config { - peertube_prefix=$1 + peertube_prefix= - peertube_config_file=$peertube_prefix$PEERTUBE_DIR/config/production.yaml + new_peertube_config_file=$peertube_prefix${PEERTUBE_CONFIG_FILE} { echo 'listen:'; echo " port: $PEERTUBE_PORT"; echo ''; echo '# Correspond to your reverse proxy "listen" configuration'; - echo 'webserver:'; } > "$peertube_config_file" + echo 'webserver:'; } > "$new_peertube_config_file" if [ ! "$peertube_prefix" ]; then if [[ "$ONION_ONLY" == 'no' ]]; then { echo ' https: true'; echo " hostname: '$PEERTUBE_DOMAIN_NAME'"; - echo ' port: 443'; } >> "$peertube_config_file" + echo ' port: 443'; } >> "$new_peertube_config_file" else { echo ' https: false'; echo " hostname: '$PEERTUBE_ONION_HOSTNAME'"; - echo ' port: 80'; } >> "$peertube_config_file" + echo ' port: 80'; } >> "$new_peertube_config_file" fi else { echo ' https: false'; echo " hostname: ''"; - echo " port: $MESH_PEERTUBE_PORT"; } >> "$peertube_config_file" + echo " port: $MESH_PEERTUBE_PORT"; } >> "$new_peertube_config_file" fi { echo ''; echo '# Your database name will be "peertube"+database.suffix'; @@ -827,22 +898,51 @@ function peertube_create_config { echo " hostname: 'localhost'"; echo ' port: 5432'; echo " suffix: ''"; - echo " username: 'peertube'"; } >> "$peertube_config_file" + echo " username: 'peertube'"; } >> "$new_peertube_config_file" if [ ! "$peertube_prefix" ]; then - echo " password: '$PEERTUBE_ADMIN_PASSWORD'" >> "$peertube_config_file" + echo " password: '$PEERTUBE_ADMIN_PASSWORD'" >> "$new_peertube_config_file" else - echo " password: ''" >> "$peertube_config_file" + echo " password: ''" >> "$new_peertube_config_file" fi { echo ''; - echo '# From the project root directory'; + echo '# Redis server for short time storage'; + echo "# You can also specify a 'socket' path to a unix socket but first need to"; + echo '# comment out hostname and port'; + echo 'redis:'; + echo " hostname: 'localhost'"; + echo ' port: 6379'; + echo ' auth: null'; + echo ' db: 0'; + echo ''; + echo '# SMTP server to send emails'; + echo 'smtp:'; + echo ' hostname: localhost'; + echo ' port: 25'; + echo ' username: null'; + echo ' password: null'; + echo ' tls: false'; + echo ' disable_starttls: false'; + echo ' ca_file: null'; + echo " from_address: '$MY_EMAIL_ADDRESS'"; + echo ''; + echo 'signup:'; + echo ' enabled: true'; + echo ' limit: 1 # When the limit is reached, registrations are disabled. -1 == unlimited'; + echo ' requires_email_verification: false'; + echo ' filters:'; + echo ' cidr: # You can specify CIDR ranges to whitelist (empty = no filtering) or blacklist'; + echo ' whitelist: []'; + echo ' blacklist: []'; + echo ''; echo 'storage:'; - echo " certs: 'certs/'"; - echo " videos: 'videos/'"; - echo " logs: 'logs/'"; - echo " previews: 'previews/'"; - echo " thumbnails: 'thumbnails/'"; - echo " torrents: 'torrents/'"; - echo " cache: 'cache/'"; + echo " avatars: '$PEERTUBE_DIR/storage/avatars/'"; + echo " videos: '$PEERTUBE_DIR/storage/videos/'"; + echo " logs: '$PEERTUBE_DIR/storage/logs/'"; + echo " previews: '$PEERTUBE_DIR/storage/previews/'"; + echo " thumbnails: '$PEERTUBE_DIR/storage/thumbnails/'"; + echo " torrents: '$PEERTUBE_DIR/storage/torrents/'"; + echo " captions: '$PEERTUBE_DIR/storage/captions/'"; + echo " cache: '$PEERTUBE_DIR/storage/cache/'"; echo ''; echo 'cache:'; echo ' previews:'; @@ -871,7 +971,70 @@ function peertube_create_config { echo ' 360p: false'; echo ' 480p: false'; echo ' 720p: false'; - echo ' 1080p: false'; } >> "$peertube_config_file" + echo ' 1080p: false'; + echo ''; + echo 'import:'; + echo '# Add ability for your users to import remote videos (from YouTube, torrent...)'; + echo ' videos:'; + echo ' http: # Classic HTTP or all sites supported by youtube-dl https://rg3.github.io/youtube-dl/supportedsites.html'; + echo ' enabled: false'; + echo ' torrent: # Magnet URI or torrent file (use classic TCP/UDP/WebSeed to download the file)'; + echo ' enabled: false'; + echo 'instance:'; + echo " name: 'PeerTube'"; + echo " short_description: 'PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.'"; + echo " description: '' # Support markdown"; + echo " terms: '' # Support markdown"; + echo " default_client_route: '/videos/trending'"; + echo ' # By default, "do_not_list" or "blur" or "display" NSFW videos'; + echo ' # Could be overridden per user with a setting'; + echo " default_nsfw_policy: 'do_not_list'"; + echo ' customizations:'; + echo " javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime"; + echo " css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime"; + echo " # Robot.txt rules. To disallow robots to crawl your instance and disallow indexation of your site, add '/' to 'Disallow:'"; + echo ' robots: |'; + echo ' User-agent: *'; + echo ' Disallow:'; + echo ' # Security.txt rules. To discourage researchers from testing your instance and disable security.txt integration, set this to an empty string.'; + echo ' securitytxt:'; + echo " \"# If you would like to report a security issue\n# you may report it to:\nContact: https://github.com/Chocobozzz/PeerTube/blob/develop/SECURITY.md\nContact: mailto:\""; + echo ''; + echo 'log:'; + echo " level: 'error' # debug/info/warning/error"; + echo ''; + echo 'search:'; + echo ' remote_uri: # Add ability to search remote videos/actors by URI, that may not be federated with your instance'; + echo ' users: true'; + echo ' anonymous: false'; + echo ''; + echo 'trending:'; + echo ' videos:'; + echo ' interval_days: 7 # Compute trending videos for the last x days'; + echo ''; + echo '# Cache remote videos on your server, to help other instances to broadcast the video'; + echo '# You can define multiple caches using different sizes/strategies'; + echo '# Once you have defined your strategies, choose which instances you want to cache in admin -> manage follows -> following'; + echo 'redundancy:'; + echo ' videos:'; + echo " check_interval: '1 hour' # How often you want to check new videos to cache"; + echo ' strategies:'; + echo ' -'; + echo " size: '1GB'"; + echo ' # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)'; + echo " min_lifetime: '48 hours'"; + echo " strategy: 'most-views' # Cache videos that have the most views"; + echo ' -'; + echo " size: '1GB'"; + echo ' # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)'; + echo " min_lifetime: '48 hours'"; + echo " strategy: 'trending' # Cache trending videos"; + echo ' -'; + echo " size: '1GB'"; + echo ' # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)'; + echo " min_lifetime: '48 hours'"; + echo " strategy: 'recently-added' # Cache recently added videos"; + echo ' min_views: 10 # Having at least x views'; } >> "$new_peertube_config_file" } function mesh_install_peertube { @@ -883,101 +1046,7 @@ function mesh_install_peertube { return fi - # shellcheck disable=SC2086 - chroot "$rootdir" $INSTALL_PACKAGES ffmpeg curl redis-tools redis-server - - function_check install_postgresql - install_postgresql - - if [ -d "$rootdir$PEERTUBE_DIR" ]; then - rm -rf "$rootdir$PEERTUBE_DIR" - fi - - git clone "$PEERTUBE_REPO" "$rootdir$PEERTUBE_DIR" - - chroot "$rootdir" groupadd peertube - chroot "$rootdir" useradd -c "PeerTube system account" -d $PEERTUBE_DIR -m -r -g peertube peertube - - cd "$rootdir$PEERTUBE_DIR" || exit 246824524 - git checkout $PEERTUBE_COMMIT -b $PEERTUBE_COMMIT - - get_npm_arch - - cat <<EOF > "$rootdir/usr/bin/install_peertube" -#!/bin/bash -cd $PEERTUBE_DIR -curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - -echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list -$UPDATE_PACKAGES -$INSTALL_PACKAGES yarn - -#if ! npm install --arch=$NPM_ARCH -g yarn@1.10.1; then -# echo $'PeerTube Failed to install yarn' -# exit 79353234 -#fi -#if ! npm install --arch=$NPM_ARCH webpack@3.10.0 --no-optional; then -# echo $'PeerTube failed to install webpack' -# exit 68386353 -#fi -yarn install -yarn run build:prod -if ! yarn add -D webpack; then - echo $'PeerTube failed to add webpack' - exit 67342823 -fi -if ! yarn install --ignore-optional; then - echo $'PeerTube failed to run yarn install' - exit 63754235 -fi -if ! npm install --arch=$NPM_ARCH -g npm@4; then - # https://github.com/KraigM/homebridge-harmonyhub/issues/119 - echo $'Failed to downgrade npm' - exit 3476835 -fi -cp /root/.npm-global/bin/npm /usr/local/bin/npm -if ! npm install --arch=$NPM_ARCH; then - echo $'PeerTube failed to install peertube' - exit 7835243 -fi -if ! npm install --arch=$NPM_ARCH -g "npm@${NPM_VERSION}"; then - echo $'Failed to restore npm after downgrade' - exit 5737583 -fi -cp /root/.npm-global/bin/npm /usr/local/bin/npm -if ! npm run build --arch=$NPM_ARCH; then - echo $'PeerTube failed to build peertube' - exit 5293593 -fi -EOF - chmod +x "$rootdir/usr/bin/install_peertube" - if ! chroot "$rootdir" /usr/bin/install_peertube; then - echo $'PeerTube install failed' - exit 735638 - fi - - { echo '[Unit]'; - echo 'Description=PeerTube Decentralized video streaming platform'; - echo 'After=syslog.target'; - echo 'After=network.target'; - echo ''; - echo '[Service]'; - echo 'User=peertube'; - echo 'Group=peertube'; - echo "WorkingDirectory=$PEERTUBE_DIR"; - echo "ExecStart=/usr/local/bin/npm start"; - echo "ExecStop=/usr/local/bin/npm stop"; - echo 'StandardOutput=syslog'; - echo 'StandardError=syslog'; - echo 'SyslogIdentifier=peertube'; - echo 'Restart=always'; - echo "Environment=NODE_ENV=production"; - echo ''; - echo '[Install]'; - echo 'WantedBy=multi-user.target'; } > "$rootdir/etc/systemd/system/peertube.service" - - peertube_create_config "$rootdir" - - chroot "$rootdir" chown -R peertube:peertube $PEERTUBE_DIR + # TODO mesh_peertube_setup_web } @@ -1000,7 +1069,7 @@ function install_peertube { exit 783523 fi - $INSTALL_PACKAGES ffmpeg redis-tools redis-server + $INSTALL_PACKAGES ffmpeg redis-tools redis-server xz-utils function_check install_postgresql install_postgresql @@ -1021,69 +1090,35 @@ function install_peertube { function_check install_nodejs install_nodejs peertube - if [ -d /repos/peertube ]; then - mkdir -p $PEERTUBE_DIR - cp -r -p /repos/peertube/. $PEERTUBE_DIR - cd "$PEERTUBE_DIR" || exit 642874682 - git pull - else - function_check git_clone - git_clone $PEERTUBE_REPO $PEERTUBE_DIR - fi - - cd "$PEERTUBE_DIR" || exit 27492742 - git checkout $PEERTUBE_COMMIT -b $PEERTUBE_COMMIT - set_completion_param "peertube commit" "$PEERTUBE_COMMIT" - - peertube_tcp_tuning - if ! npm install -g yarn@1.10.1; then echo $'Failed to install yarn' exit 79353234 fi - yarn add -D webpack --network-concurrency 1 - if ! yarn install; then - echo $'Failed to run yarn install' - exit 63754235 - fi - if ! npm install -g npm@4; then - # https://github.com/KraigM/homebridge-harmonyhub/issues/119 - echo $'Failed to downgrade npm' - exit 3476835 - fi - cp /root/.npm-global/bin/npm /usr/local/bin/npm - if ! npm install; then - echo $'Failed to install peertube' - exit 7835243 - fi - if ! npm install -g "npm@${NPM_VERSION}"; then - echo $'Failed to restore npm after downgrade' - exit 5737583 + + mkdir -p $PEERTUBE_DIR + cd $PEERTUBE_DIR || exit 356835 + mkdir config storage versions + cd versions || exit 3576835 + + wget -q "$PEERTUBE_DOWNLOAD" -O "$PEERTUBE_DOWNLOAD_FILENAME" + if [ ! -f "$PEERTUBE_DOWNLOAD_FILENAME" ]; then + exit 56874674 fi - cp /root/.npm-global/bin/npm /usr/local/bin/npm - npm run build + unxz "$PEERTUBE_DOWNLOAD_FILENAME" + rm "$PEERTUBE_DOWNLOAD_FILENAME" + + cd ../ || exit 356385 + ln -s "versions/peertube-${VERSION}" ./peertube-latest + cd ./peertube-latest || exit 35685 + chown -R peertube:peertube $PEERTUBE_DIR + + sudo -H -u peertube yarn install --production --pure-lockfile + + peertube_tcp_tuning PEERTUBE_ONION_HOSTNAME=$(add_onion_service peertube 80 ${PEERTUBE_ONION_PORT}) - { echo '[Unit]'; - echo 'Description=PeerTube Decentralized video streaming platform'; - echo 'After=syslog.target'; - echo 'After=network.target'; - echo ''; - echo '[Service]'; - echo 'User=peertube'; - echo 'Group=peertube'; - echo "WorkingDirectory=$PEERTUBE_DIR"; - echo "ExecStart=/usr/local/bin/npm start"; - echo "ExecStop=/usr/local/bin/npm stop"; - echo 'StandardOutput=syslog'; - echo 'StandardError=syslog'; - echo 'SyslogIdentifier=peertube'; - echo 'Restart=always'; - echo "Environment=NODE_ENV=production"; - echo ''; - echo '[Install]'; - echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/peertube.service + cp "$PEERTUBE_DIR/peertube-latest/support/systemd/peertube.service" /etc/systemd/system/peertube.service peertube_create_config @@ -1105,10 +1140,11 @@ function install_peertube { sleep 10 # update the admin email address after creation of the database - sed -i "s|email: .*|email: '$MY_EMAIL_ADDRESS'|g" $PEERTUBE_DIR/config/production.yaml + sed -i "s|email: .*|email: '$MY_EMAIL_ADDRESS'|g" ${PEERTUBE_CONFIG_FILE} peertube_import_from_syncthing + set_completion_param "peertube version" "$PEERTUBE_VERSION" set_completion_param "peertube domain" "$PEERTUBE_DOMAIN_NAME" APP_INSTALLED=1 }