Peertube bad gateway / connection refused

Hey !

I’m trying to run peertube on a VM with Ubuntu server. I want to use a remote reverse proxy with nginx.
When trying to access peertube through the url I get a failed (111: Connection refused) while connecting to upstream on my reverse proxy.

ngnix conf :

server {
  listen 80;
  listen [::]:80;
  server_name video.gafamfree.party;

  access_log /var/log/nginx/video.gafamfree.party.access.log;
  error_log /var/log/nginx/video.gafamfree.party.error.log;

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

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name video.gafamfree.party;

  # For example with certbot (you need a certificate to run https)
  ssl_certificate      /etc/letsencrypt/live/video.gafamfree.party/fullchain.pem;
  ssl_certificate_key  /etc/letsencrypt/live/video.gafamfree.party/privkey.pem;

  # Security hardening (as of 11/02/2018)
  ssl_protocols TLSv1.2; # TLSv1.3, TLSv1.2 if nginx >= 1.13.0
  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';
  # ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0, not compatible with import-videos script
  ssl_session_timeout  10m;
  #ssl_session_cache shared:SSL:10m; #conflit avec deja existant
  ssl_session_tickets off; # Requires nginx >= 1.5.9
  ssl_stapling on; # Requires nginx >= 1.3.7
  ssl_stapling_verify on; # Requires nginx => 1.3.7

  # Configure with your resolvers
  # resolver $DNS-IP-1 $DNS-IP-2 valid=300s;
  # resolver_timeout 5s;

  # Enable compression for JS/CSS/HTML bundle, for improved client load times.
  # It might be nice to compress JSON, but leaving that out to protect against potential
  # compression+encryption information leak attacks like BREACH.
  gzip on;
  gzip_types text/css application/javascript;
  gzip_vary on;

  # Enable HSTS
  # Tells browsers to stick with HTTPS and never visit the insecure HTTP
  # version. Once a browser sees this header, it will only visit the site over
  # HTTPS for the next 2 years: (read more on hstspreload.org)
  #add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";

  access_log /var/log/nginx/peertube.example.com.access.log;
  error_log /var/log/nginx/peertube.example.com.error.log;

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

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

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

  # Bypass PeerTube for performance reasons. Could be removed
  location ~ ^/static/(thumbnails|avatars)/ {
    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;
      add_header 'Content-Type' 'text/plain charset=UTF-8';
      add_header 'Content-Length' 0;
      return 204;
    }

    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';

    # Cache 2 hours
    add_header Cache-Control "public, max-age=7200";

    root /var/www/peertube/storage;

    rewrite ^/static/(thumbnails|avatars)/(.*)$ /$1/$2 break;
    try_files $uri /;
  }

  location / {
    proxy_pass http://192.168.1.76:9000; #ancienne http://127.0.0.1:9000
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # This is the maximum upload size, which roughly matches the maximum size of a video file
    # you can send via the API or the web interface. By default this is 8GB, but administrators
    # can increase or decrease the limit. Currently there's no way to communicate this limit
    # to users automatically, so you may want to leave a note in your instance 'about' page if
    # you change this.
    #
    # 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 8G;

    proxy_connect_timeout       600;
    proxy_send_timeout          600;
    proxy_read_timeout          600;
    send_timeout                600;
  }

  # Bypass PeerTube for performance reasons. Could be removed
  location ~ ^/static/(webseed|redundancy)/ {
    # Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client
    limit_rate 800k;

    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;
      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';

      # Don't spam access log file with byte range requests
      access_log off;
    }

    root /var/www/peertube/storage;

    rewrite ^/static/webseed/(.*)$ /videos/$1 break;
    rewrite ^/static/redundancy/(.*)$ /redundancy/$1 break;

    try_files $uri /;
  }

  # Websocket tracker
  location /tracker/socket {
    # Peers send a message to the tracker every 15 minutes
    # Don't close the websocket before this time
    proxy_read_timeout 1200s;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://127.0.0.1:9000;
  }

  location /socket.io {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;

    proxy_pass http://192.168.1.76:9000;

    # enable WebSockets
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}

peertube config :

listen:
  hostname: 'localhost'
  port: 9000

# Correspond to your reverse proxy server_name/listen configuration
webserver:
  https: true
  hostname: 'video.gafamfree.party'
  port: 443

rates_limit:
  api:
    # 50 attempts in 10 seconds
    window: 10 seconds
    max: 50
  login:
    # 15 attempts in 5 min
    window: 5 minutes
    max: 15
  signup:
    # 2 attempts in 5 min (only succeeded attempts are taken into account)
    window: 5 minutes
    max: 2
  ask_send_email:
    # 3 attempts in 5 min
    window: 5 minutes
    max: 3

# Proxies to trust to get real client IP
# If you run PeerTube just behind a local proxy (nginx), keep 'loopback'
# If you run PeerTube behind a remote proxy, add the proxy IP address (or subnet)
trust_proxy:
  - 'loopback'      
  - 192.168.1.36

# Your database name will be "peertube"+database.suffix
database:
  hostname: 'localhost'
  port: 5432
  suffix: '_prod'
  username: 'peertube'
  password: 'mdrxbar'
  pool:
    max: 5

# Redis server for short time storage
# You can also specify a 'socket' path to a unix socket but first need to
# comment out hostname and port
redis:
  hostname: 'localhost'
  port: 6379
  auth: null
  db: 0

# SMTP server to send emails
smtp:
  hostname: null
  port: 465 # If you use StartTLS: 587
  username: null
  password: null
  tls: true # If you use StartTLS: false
  disable_starttls: false
  ca_file: null # Used for self signed certificates
  from_address: 'admin@example.com'

email:
  body:
    signature: "PeerTube"
  subject:
    prefix: "[PeerTube]"

# From the project root directory
storage:
  tmp: '/var/www/peertube/storage/tmp/' # Used to download data (imports etc), store uploaded files before processing...
  avatars: '/var/www/peertube/storage/avatars/'
  videos: '/var/www/peertube/storage/videos/'
  streaming_playlists: '/var/www/peertube/storage/streaming-playlists/'
  redundancy: '/var/www/peertube/storage/videos/'
  logs: '/var/www/peertube/storage/logs/'
  previews: '/var/www/peertube/storage/previews/'
  thumbnails: '/var/www/peertube/storage/thumbnails/'
  torrents: '/var/www/peertube/storage/torrents/'
  captions: '/var/www/peertube/storage/captions/'
  cache: '/var/www/peertube/storage/cache/'
  plugins: '/var/www/peertube/storage/plugins/'

log:
  level: 'info' # debug/info/warning/error
  rotation:
    enabled : true

search:
  # Add ability to fetch remote videos/actors by their URI, that may not be federated with your instance
  # If enabled, the associated group will be able to "escape" from the instance follows
  # That means they will be able to follow channels, watch videos, list videos of non followed instances
  remote_uri:
    users: true
    anonymous: false

trending:
  videos:
    interval_days: 7 # Compute trending videos for the last x days

# Cache remote videos on your server, to help other instances to broadcast the video
# You can define multiple caches using different sizes/strategies
# Once you have defined your strategies, choose which instances you want to cache in admin -> manage follows -> following
redundancy:
  videos:
    check_interval: '1 hour' # How often you want to check new videos to cache
    strategies: # Just uncomment strategies you want
      -
        size: '10GB'
        # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)
        min_lifetime: '48 hours'
        strategy: 'most-views' # Cache videos that have the most views
        #     -
#        size: '10GB'
#        # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)
#        min_lifetime: '48 hours'
#        strategy: 'trending' # Cache trending videos
#      -
#        size: '10GB'
#        # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)
#        min_lifetime: '48 hours'
#        strategy: 'recently-added' # Cache recently added videos
#        min_views: 10 # Having at least x views

csp:
  enabled: false
  report_only: true # CSP directives are still being tested, so disable the report only mode at your own risk!
  report_uri:

tracker:
  # If you disable the tracker, you disable the P2P aspect of PeerTube
  enabled: true
  # Only handle requests on your videos.
  # If you set this to false it means you have a public tracker.
  # Then, it is possible that clients overload your instance with external torrents
  private: true
  # Reject peers that do a lot of announces (could improve privacy of TCP/UDP peers)
  reject_too_many_announces: false

history:
  videos:
    # If you want to limit users videos history
    # -1 means there is no limitations
    # Other values could be '6 months' or '30 days' etc (PeerTube will periodically delete old entries from database)
    max_age: -1

views:
  videos:
    # PeerTube creates a database entry every hour for each video to track views over a period of time
    # This is used in particular by the Trending page
    # PeerTube could remove old remote video views if you want to reduce your database size (video view counter will not be altered)
    # -1 means no cleanup
    # Other values could be '6 months' or '30 days' etc (PeerTube will periodically delete old entries from database)
    remote:
      max_age: -1

plugins:
  # The website PeerTube will ask for available PeerTube plugins
  # This is an unmoderated plugin index, so only install plugins you trust
  index:
    enabled: true
    check_latest_versions_interval: '12 hours' # How often you want to check new plugins/themes versions
    url: 'https://packages.joinpeertube.org'


###############################################################################
#
# From this point, all the following keys can be overridden by the web interface
# (local-production.json file). If you need to change some values, prefer to
# use the web interface because the configuration will be automatically
# reloaded without any need to restart PeerTube.
#
# /!\ If you already have a local-production.json file, the modification of the
# following keys will have no effect /!\.
#
###############################################################################

cache:
  previews:
    size: 500 # Max number of previews you want to cache
  captions:
    size: 500 # Max number of video captions/subtitles you want to cache

admin:
  # Used to generate the root user at first startup
  # And to receive emails from the contact form
  email: 'admin@example.com'

contact_form:
  enabled: true

signup:
  enabled: false
  limit: 10 # When the limit is reached, registrations are disabled. -1 == unlimited
  requires_email_verification: false
  filters:
    cidr: # You can specify CIDR ranges to whitelist (empty = no filtering) or blacklist
      whitelist: []
      blacklist: []

user:
  # Default value of maximum video BYTES the user can upload (does not take into account transcoded files).
  # -1 == unlimited
  video_quota: -1
  video_quota_daily: -1

# If enabled, the video will be transcoded to mp4 (x264) with "faststart" flag
# In addition, if some resolutions are enabled the mp4 video file will be transcoded to these new resolutions.
# Please, do not disable transcoding since many uploaded videos will not work
transcoding:
  enabled: true
  # Allow your users to upload .mkv, .mov, .avi, .flv videos
  allow_additional_extensions: true
  # If a user uploads an audio file, PeerTube will create a video by merging the preview file and the audio file
  allow_audio_files: true
  threads: 1
  resolutions: # Only created if the original video has a higher resolution, uses more storage!
    240p: false
    360p: false
    480p: false
    720p: false
    1080p: false
    2160p: false
  # /!\ EXPERIMENTAL /!\
  # /!\ Requires ffmpeg >= 4
  # Generate HLS playlists and fragmented MP4 files. Better playback than with WebTorrent:
  #     * Resolution change is smoother
  #     * Faster playback in particular with long videos
  #     * More stable playback (less bugs/infinite loading)
  # /!\ Multiplies videos storage by 2 /!\
  hls:
    enabled: false

import:
  # Add ability for your users to import remote videos (from YouTube, torrent...)
  videos:
    http: # Classic HTTP or all sites supported by youtube-dl https://rg3.github.io/youtube-dl/supportedsites.html
      enabled: false
    torrent: # Magnet URI or torrent file (use classic TCP/UDP/WebSeed to download the file)
      enabled: false

auto_blacklist:
  # New videos automatically blacklisted so moderators can review before publishing
  videos:
    of_users:
      enabled: false

# Instance settings
instance:
  name: 'PeerTube'
  short_description: 'PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.'
  description: '' # Support markdown
  terms: '' # Support markdown
  default_client_route: '/videos/trending'
  # Whether or not the instance is dedicated to NSFW content
  # Enabling it will allow other administrators to know that you are mainly federating sensitive content
  # Moreover, the NSFW checkbox on video upload will be automatically checked by default
  is_nsfw: false
  # By default, "do_not_list" or "blur" or "display" NSFW videos
  # Could be overridden per user with a setting
  default_nsfw_policy: 'do_not_list'
  customizations:
    javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime
    css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime
  # Robot.txt rules. To disallow robots to crawl your instance and disallow indexation of your site, add '/' to "Disallow:'
  robots: |
    User-agent: *
    Disallow:
  # Security.txt rules. To discourage researchers from testing your instance and disable security.txt integration, set this to an empty string.
  securitytxt:
    "# 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:"

services:
  # Cards configuration to format video in Twitter
  twitter:
    username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published
    # If true, a video player will be embedded in the Twitter feed on PeerTube video share
    # If false, we use an image link card that will redirect on your PeerTube instance
    # Test on https://cards-dev.twitter.com/validator to see if you are whitelisted
    whitelisted: false

followers:
  instance:
    # Allow or not other instances to follow yours
    enabled: true
    # Whether or not an administrator must manually validate a new follower
    manual_approval: false

theme:
  default: 'default'

curl video.gafamfree.party :

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

netstat -anp | grep 9000
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 15550/peertube

thx for your help :slight_smile:

1 Like

and
curl 192.168.1.76:9000
curl: (7) Failed to connect to 192.168.1.76 port 9000: Connection refused

Maybe change ‘localohost’ with some IP Address like 0.0.0.0 ?
because localhost is 127.0.0.1 and nginx seems configured to reach “empty” (or 0.0.0.0) IP…

Wouhou ! That worked thx :slight_smile: Now I have a white blanck page, but the request go through the reverse proxy :slight_smile:

So it explains that too :wink:

But now, this should work. I mean in your local network, with the new config you should be able to see your peertube instance directly by using this IP in your browser : http://192.168.1.76:9000/

I have a problem setting the alias path in ngnix conf :s I get a error on my reverse proxy :

2 open() "/var/www/peertube/storage/fr_F
R/styles.98e367ddd9dfa4275058.css" failed (2: No such file or directory), client
: 193.57.110.13, server: video.gafamfree.party, request: "GET /client/fr_FR/styl
es.98e367ddd9dfa4275058.css HTTP/2.0", host: "video.gafamfree.party", referrer:
"https://video.gafamfree.party/"

storage path in production.yaml are peerture/storage/etc and in the ngnix conf, alias is peertube/storage/$1

the file mozilla want to reach is store in peertube/peertube-latest/dist/

It work when I delete the optimisation part of the ngnix config :smiley:

Is there a way to keep theis optimisation ?

Thx you a lot for your help :smiley: Happy to have a running peertube instance o/

Was about to ask until I saw your answer, worked for me as well. Thanks! :slight_smile:

1 Like

I have a similar problem with the same error in the log, but the sollution did not work for me. My settings are the same, with the the difference that i run it behind a local proxy (nginx) and netstat -anp | grep 9000 does not return anything…

I’m running out of ideas of how to solve the issue.

Acutally… sytemctl status peertube.service reports a snoothly running peertube. But when i run journalctl -feu peertube i see there is a strang loop going on where it restarts wevey 30 seconds.

I’ll investigate this and repport back. Here’s the error log in case it would tickle in someone else’s fingers :slight_smile: <3

Nov 01 18:17:58 set peertube[40726]:   "error": {
Nov 01 18:17:58 set peertube[40726]:     "stack": "Error: Videos redundancy should be an array (you must uncomment lines containing - too)\n    at Object.<anonymous> (/var/www/peertube/versions/peertube-v2.4.0/dist/server.js:39:11)\n    at Module._compile (internal/modules/cjs/loader.js:778:30)\n    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)\n    at Module.load (internal/modules/cjs/loader.js:653:32)\n    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)\n    at Function.Module._load (internal/modules/cjs/loader.js:585:3)\n    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)\n    at startup (internal/bootstrap/node.js:283:19)\n    at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)",

sorry for the noise but that was quick :slight_smile: I had forgotten to uncomment th - in the peertube.yaml file

And now it all works!! \o/ WIHU!

Thanks!

@sakrecoer Glad you found an answer, but please refrain from necroposting in the future and create your own thread instead.

1 Like

Good to know @rigelk. It simply fit my description so well I figured i would be refered to this thread if i made my own thread. But now that i know how this works here, I will keep it in mind for future interactions :slight_smile:

Hello and best wishes to all,

Allow me to reopen the discussion.
I have just updated my Ubuntu 18.04.6 lts distribution to Ubuntu 20.04.5 LTS, and this, without impacting the functioning of Peertube version 3.4.0.

Upgrade from Peertube 3.4.0 to v5.0.0 via upgrade.sh script.
I previously updated:
node >=14.x
yarn >=1,x
postgres >=10.x
redis-server >=5,x
ffmpeg >=4.3.

Following the upgrade to v5.0.0 I find myself with the recurring error in the nginx logs:
« *69 connect() failed (111: Connection refused) while connecting to upstream »

I didn’t change anything to configuration in peertube-latest/config/default.yaml and proxy configuration for nginx.

Link to the github causing the issue HERE

Nginx runs fine but node does not listen on port 9000

Thank you in advance for your answers to the questions.

Maybe that is the problem?
There are configuration differences (nginx and peertube config) in several version between 3.4 and 5.0.
Please read all changelogs between these 2 version (there are also manual scripts to run), and use the diff command to find changes that are necessary in configuration (see here)

Note: you have to change /var/www/peertube/config/production.yaml, not peertube-latest/config/default.yaml

Hello,

Thank you for your feedback and responsiveness.
I followed the recommendations only for version 5 on the github because I went from version 3 to 5 Peertube.
Always the error 502 Bad Gateway
I think I have a problem with nginx and node.js listening on port 9000.
Thanks