Mastondon ARM64 Docker Deployment
Build Mastodon ARM64 Docker image yourself

1. Intro
Last post of Mastodon Installation on AMD64: https://henrywithu.com/mastodon-installation/
2. Background
Docker is not recommended by Mastodon Official.(dunno why) Till now (202204), Mastodon does not have official docker image on DockerHub, so let’s build it ourselves.
Environment: ARM64, Ubuntu 20.04 LTS
3. Deployment
3.1 Dependencies
Install the required packages
apt -y update
apt -y install curl git nginx python3-certbot-nginx
Install Docker
curl -sSL https://get.docker.com/ | sh
systemctl enable --now nginx docker
Install docker-compose of ARM64
pip3 install docker-compose
3.2 Download Mastodon and edit docker-compose file
Pull files
cd /home/ubuntu/
git clone https://github.com/tootsuite/mastodon.git
cd mastodon/
Copy a configuration file
cp .env.production.sample .env.production
Actually you can rename or delete the default docker-compose.yml that comes with the project. If you use this yml configuration directly, it will definitely not run. There are too many problems beyond explanation, so I won't go into details here.
mv docker-compose.yml docker-compose.yml.bak
3.3 Build Mastodon ARM64 Image
Since Mastodon does not officially release the arm64-based image on DockerHub, we have to build the image ourselves. Fortunately, the official dockerfile directly supports arm64.
Check version
cd /home/ubuntu/mastodon/
git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)
Build image (the duration varies, depending on your CPU & RAM)
docker build -t mastodon .
After building image, you can check it via
docker images
The self-built ARM64 image is named mastodon:latest
3.4 Edit docker-compose file
Create docker-compose file
nano docker-compose.yml
Here I put up an example configuration I am currently using, for your reference
version: '3.8'
services:
mastodon-db:
image: postgres:9.6-alpine
shm_size: 256mb
environment:
POSTGRES_DB: mastodon
POSTGRES_USER: username
POSTGRES_PASSWORD: password
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
volumes:
- ./postgres:/var/lib/postgresql/data
restart: unless-stopped
mastodon-redis:
image: redis:6.0-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
volumes:
- ./redis:/data
restart: unless-stopped
mastodon-es:
image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- "cluster.name=es-mastodon"
- "discovery.type=single-node"
- "bootstrap.memory_lock=true"
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
restart: unless-stopped
mastodon-web:
image: mastodon:latest
env_file: .env.production
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
depends_on:
- mastodon-db
- mastodon-redis
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:3000/health || exit 1"]
ports:
- "127.0.0.1:3000:3000"
volumes:
- ./public/system:/mastodon/public/system
restart: unless-stopped
mastodon-streaming:
image: mastodon:latest
env_file: .env.production
command: node ./streaming
depends_on:
- mastodon-db
- mastodon-redis
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1"]
ports:
- "127.0.0.1:4000:4000"
restart: unless-stopped
mastodon-sidekiq:
image: mastodon:latest
env_file: .env.production
command: bundle exec sidekiq
depends_on:
- mastodon-db
- mastodon-redis
volumes:
- ./public/system:/mastodon/public/system
restart: unless-stopped
Note 1: substitute each tootsuite/mastodon
with mastodon:latest
Note 2: ElasticSearch only supports ARM64 since version 7.8, so let’s modify the default version to a higher version (with your choice)
image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2
3.5 Run configuration wizard
Next, run this command to enter the configuration wizard
docker-compose run --rm mastodon-web bundle exec rake mastodon:setup
Simply follow the instructions below:
Domain name: # fill in your domain
Do you want to enable single user mode? # Yes
Are you using Docker to run Mastodon? # Yes
PostgreSQL host: # mastodon-db
PostgreSQL port: # 5432
Name of PostgreSQL database: # mastodon
Name of PostgreSQL user: # username, match the database username in docker-compose.yml
Password of PostgreSQL user: # password, match the database username in docker-compose.yml
Redis host: # mastodon-redis
Redis port: # 6379
Redis password: # leave blank, press enter directly
Do you want to store uploaded files on the cloud? # No
Do you want to send e-mails from localhost? # Yes
Send a test e-mail with this configuration right now? # No
Save configuration? Yes
Note: This configuration is in single-user mode. that is, registration is not open by default. You can switch it to non-single-user mode as you wish. Secondly, SMTP is not configured because I’m the only user.
Next, it will print out the configuration you filled in, and now you need to copy the configuration you filled in before.
This is a very tricky place. You will see the following prompt:
Prepare the database now? (Y/n)
Important: Don't choose Y or N, just press the keyboard combination Ctrl^C to exit. Then clear the default configuration in the following configuration file:
echo > .env.production
Edit it
nano .env.production
Paste the configuration you copied through the wizard output earlier and save. Then run the wizard again:
docker-compose run --rm mastodon-web bundle exec rake mastodon:setup
The configuration this time must be the same as the last time. When you come to the following prompt again, you can choose Yes:
Prepare the database now? (Y/n) # Yes
Compile the assets now? (Y/n) # Yes
The next step is to create an administrator account. Continue to follow this guide and it will be OK. Don't forget to keep the default admin credential. You'll need to change it later
3.6 Build up the container
Up docker-compose
docker-compose up -d
Now you need to change the owner of the public directory to the one in the container, otherwise you cannot upload avatar later.
chown -R 991:991 public
3.7 Config Nginx
Now make a copy of the Nginx configuration file
cp /home/ubuntu/mastodon/dist/nginx.conf /etc/nginx/conf.d/mastodon.conf
Edit mastodon.conf
nano /etc/nginx/conf.d/mastodon.conf
In this configuration file, the official template has been all set. You only need to edit in the following two server blocks:
server {
listen 80;
listen [::]:80;
server_name example.com; # your domain
root /home/ubuntu/mastodon/public; # absolute path of public directory
...
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com; # your domain
root /home/ubuntu/mastodon/public; # absolute path of public directory
...
}
Use certbot to issue SSL certificates
certbot --nginx
Restart Nginx
systemctl restart nginx
4. Post-Installation
If you want to move your site in the future, just pack the /home/ubuntu/mastodon
directory directly, and upload it to another machine after decompression.
It is the same to change the configuration in .env.production. After changes, you can run docker-compose up -d
.
Copyright statement: Unless otherwise stated, all articles on this blog adopt the CC BY-NC-SA 4.0 license agreement. For non-commercial reprints and citations, please indicate the author: Henry, and original article URL. For commercial reprints, please contact the author for authorization.