Recently I’ve setup an invite-only mastodon instance as a private space for
friends and family. While I am still evaluating whether mastodon is the right tool for such a private space, I’d like to share a number of issues I encountered during setup.
Careful with non-official guides
The mastodon documentation focuses on hosting mastodon on a dedicated machine. It is thorough and I would recommend reading through it, even if you do not want to dedicate a separate machine to hosting mastodon. Mastodon also maintains a docker-compose
config file, unfortunately the documentation on setting it up appears lackluster. The best guides I’ve found details are a alibaba cloud guide and a howtoforge guide. Note these guides aren’t perfect: the official docs recommend running the latest tagged releases whereas both guides run from the master branch, generating the necessary secrets is done differently than in the official documentation and I also don’t like how they automate certificate renewal.
Issues related to the db service
After initial tweaking of the .env.production
file I encountered two issues related to the db service. Fortunately I stumbled upon this stackoverflow answer. I recap my findings belows.
Issue #1
rails aborted! PG::ConnectionBad: could not connect to server: No such file or directory
This is caused by the web service being unable to connect to the database. In my case this was due to an invalid value for DB_HOST
in .env.production
. Setting DB_HOST
to mastodon_db_1
solved this issue for me. The resulting postgres section looks as follows:
# PostgreSQL
# ----------
DB_HOST=mastodon_db_1
DB_USER=mastodon
DB_NAME=mastodon_production
DB_PASS=xyz
DB_PORT=5432
In the same vain you’ll want to change REDIS_HOST
from localhost
to mastodon_redis_1
.
Issue #2:
Error: Database is uninitialized and superuser password is not specified. You must specify POSTGRES_PASSWORD to a non-empty value for the superuser
This is caused by the pg_isready
healthcheck failing and can be fixed by setting the necessary env variables in docker-compose.yml
. The resulting db
compose service looks as follows:
db:
restart: always
image: postgres:9.6-alpine
shm_size: 256mb
networks:
- internal_network
healthcheck:
test: ["CMD", "pg_isready", "-U", "mastodon", "-d", "mastodon_production"]
volumes:
- ./postgres:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: xyz
POSTGRES_DB: mastodon_production
POSTGRES_USER: mastodon
Optional features enabled by default
s3 object storage
This is enabled by default in the sample environment file. If you don’t configure it correctly (or forget to turn it off), you’ll notice that media uploads are failing. The failures are accompanied by the following log message: method=POST path=/api/v2/media format=html controller=Api::V2::MediaController action=create status=500 error='Aws::Sigv4::Errors::MissingCredentialsError: missing credentials,provide credentials with one of the following options
.
If you want to store media on local storage, just comment the lines under File Storage in the env file. Do check to ensure that /opt/mastodon/public/system/
in the web container is persisted on the host system (this should be case via the volume defined in the docker-compose.yml
).
elastic search
Elastic search is also enabled by default in the sample env file, while it is commented out in the docker-compose.yml
file. If you don’t have the es
containter running, you’ll notice a large number of sidekiq jobs starting to accumulate in the ‘Retry’ state with the following error message: Faraday::ConnectionFailed: Failed to open TCP connection to localhost:9200 (Cannot assign requested address - connect(2) for "localhost" port 9200)
. Either enable the es
container or comment out ES_ENABLED=true
in the ENV file.
My entire ENV file
For completeness you can find my entire .env.production
file below, where sensitive entries have been redacted. Note I am currently using mailgun as an SMTP server, as I found sendgrid to be blocked by Spam filters.
# This is a sample configuration file. You can generate your configuration # with the `rake mastodon:setup` interactive setup wizard, but to customize # your setup even further, you'll need to edit it manually. This sample does # not demonstrate all available configuration options. Please look at # https://docs.joinmastodon.org/admin/config/ for the full documentation. # Federation # ---------- # This identifies your server and cannot be changed safely later # ---------- LOCAL_DOMAIN=social.vdna.be # Redis # ----- REDIS_HOST=mastodon_redis_1 REDIS_PORT=6379 # PostgreSQL # ---------- DB_HOST=mastodon_db_1 DB_USER=mastodon DB_NAME=mastodon_production DB_PASS=xyz DB_PORT=5432 # ElasticSearch (optional) # ------------------------ # ES_ENABLED=true # ES_HOST=localhost # ES_PORT=9200 # Secrets # ------- # Make sure to use `rake secret` to generate secrets # ------- SECRET_KEY_BASE=xyz OTP_SECRET=xyz # Web Push # -------- # Generate with `rake mastodon:webpush:generate_vapid_key` # -------- VAPID_PRIVATE_KEY=xyz VAPID_PUBLIC_KEY=xyz # Sending mail # ------------ SMTP_SERVER=smtp.eu.mailgun.org SMTP_PORT=587 SMTP_LOGIN=postmaster@mg.social.vdna.be SMTP_PASSWORD=xyz SMTP_FROM_ADDRESS=social@mg.social.vdna.be # File storage (optional) # ----------------------- #S3_ENABLED=true #S3_BUCKET=files.example.com #AWS_ACCESS_KEY_ID= #AWS_SECRET_ACCESS_KEY= #S3_ALIAS_HOST=files.example.com
Thank you very much for this very helpful blog post.
Helped me a lot during initial setup and again for the upgrade to mastodon 4.0.2.
Best regards
Martin