Skip Navigation

Question on selfhosting Mastodon (docker or not, reverse proxy and how to easily update)

I finally managed to selfhost Lemmy and Matrix, now it is time to also get a selfhosted Mastodon instance up. A few questions before I start:

I did some research into the topic and it seems that Mastodon doesn't like to run behind an existing reverse proxy and there are quite a few tweaks necessary to get it running - can someone confirm this? Or is this something easily set up?

I'm currently leaning to run it on a dedicated VPS (due to the issue above and also because it seems to need quite a bit of disk space) - this opens up to do a non-docker installation and follow the official install path. Do you think this will make it easier to keep it updated to new releases in the future?

If going with a docker install there seem to be quite a few problems with updating (at least a lot of threads discussing failed update procedures sprung up when I googles "mastodon docker update") - can someone confirm? Are there easy to follow guides for a docker based update routine?

Right now it seems the easiest would be to run on a dedicated server, follow the native installation procedure and use the templates provided for nginx, certbot, .... thoughts?

9

You're viewing a single thread.

9 comments
  • It's actually not hard to get Mastodon running behind an existing reverse proxy. It's also not hard to run it in a docker container. I run mine in a docker container with no issues. When version 4.1.4 was released, I just ran a docker-compose pull, and voila, my instant was upgraded. I can share my configs with you if you want. What is your existing reverse proxy server?

    • I run Nginx with Nginx Proxy Manager web-ui, which makes setting up proxy hosts and handling letsencrypt certificates really easy. I also use Portainer to manage my docker containers. This works well for the stuff I mentioned above (Nextcloud, Matrix, Lemmy mostly)

      If I can get Mastodon into the same setup, it'd be neat. I just found a lot of discussion with problems, so I thought I'll ask about it before I spend a few hours in vain :)

      • NGINX Proxy Manager makes things even easier! All you have to do is make certain that you have websockets enabled for the proxy settings to go to your Mastodon instance and don't forward via SSL because NPM is your SSL termination point. On your Mastodon instance's NGINX configuration, change the port to listen on port 80, comment out all of the SSL related options, and in the @proxy section change the proxy_set_header X-Forwarded-Proto $scheme; to proxy_set_header X-Forwarded-Proto https; This is just telling Mastodon a small lie so it thinks the traffic is encrypted. This is necessary to prevent a redirection loop which will break things.

    • Is there a good guide for Mastodon in Docker? I’ve followed a few but they all get stuck at various points.

      • You need to actually piece together those few to come up with one cohesive working instance. I can share with you the docker-compose.yml file that worked for me, if that will help.

        version: '3'
        services:
          db:
            restart: always
            image: postgres:14-alpine
            shm_size: 256mb
            networks:
              - internal_network
            healthcheck:
              test: ['CMD', 'pg_isready', '-U', 'postgres']
            volumes:
              - ./postgres14:/var/lib/postgresql/data
            environment:
              - 'POSTGRES_HOST_AUTH_METHOD=trust'
        
          redis:
            restart: always
            image: redis:7-alpine
            networks:
              - internal_network
            healthcheck:
              test: ['CMD', 'redis-cli', 'ping']
            volumes:
              - ./redis:/data
        
          # es:
          #   restart: always
          #   image: docker.elastic.co/elasticsearch/elasticsearch:7.17.4
          #   environment:
          #     - "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true"
          #     - "xpack.license.self_generated.type=basic"
          #     - "xpack.security.enabled=false"
          #     - "xpack.watcher.enabled=false"
          #     - "xpack.graph.enabled=false"
          #     - "xpack.ml.enabled=false"
          #     - "bootstrap.memory_lock=true"
          #     - "cluster.name=es-mastodon"
          #     - "discovery.type=single-node"
          #     - "thread_pool.write.queue_size=1000"
          #   networks:
          #      - external_network
          #      - internal_network
          #   healthcheck:
          #      test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
          #   volumes:
          #      - ./elasticsearch:/usr/share/elasticsearch/data
          #   ulimits:
          #     memlock:
          #       soft: -1
          #       hard: -1
          #     nofile:
          #       soft: 65536
          #       hard: 65536
          #   ports:
          #     - '127.0.0.1:9200:9200'
        
          web:
            #build: .
            #image: ghcr.io/mastodon/mastodon
            image: tootsuite/mastodon:latest
            restart: always
            env_file: .env.production
            command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
            networks:
              - external_network
              - internal_network
            healthcheck:
              # prettier-ignore
              test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1']
            ports:
              - '127.0.0.1:3000:3000'
            depends_on:
              - db
              - redis
              # - es
            volumes:
              - ./public/system:/mastodon/public/system
        
          streaming:
            #build: .
            #image: ghcr.io/mastodon/mastodon
            image: tootsuite/mastodon:latest
            restart: always
            env_file: .env.production
            command: node ./streaming
            networks:
              - external_network
              - internal_network
            healthcheck:
              # prettier-ignore
              test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1']
            ports:
              - '127.0.0.1:4000:4000'
            depends_on:
              - db
              - redis
        
          sidekiq:
            #build: .
            #image: ghcr.io/mastodon/mastodon
            image: tootsuite/mastodon:latest
            restart: always
            env_file: .env.production
            command: bundle exec sidekiq
            depends_on:
              - db
              - redis
            networks:
              - external_network
              - internal_network
            volumes:
              - ./public/system:/mastodon/public/system
            healthcheck:
              test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
        
          ## Uncomment to enable federation with tor instances along with adding the following ENV variables
          ## http_proxy=http://privoxy:8118
          ## ALLOW_ACCESS_TO_HIDDEN_SERVICE=true
          # tor:
          #   image: sirboops/tor
          #   networks:
          #      - external_network
          #      - internal_network
          #
          # privoxy:
          #   image: sirboops/privoxy
          #   volumes:
          #     - ./priv-config:/opt/config
          #   networks:
          #     - external_network
          #     - internal_network
        
        networks:
          external_network:
          internal_network:
            internal: true
        
      • Maybe tell me where you're stuck and I can help?

You've viewed 9 comments.