Skip to content


Folders and files

Last commit message
Last commit date

Latest commit



17 Commits

Repository files navigation

Table of Contents

Mastodon on Digital Ocean

A budget Mastodon installation that still strives to be productionised and fault-tolerant.



You'll need terraform installed.

Get a Digital Ocean account

Sign up for a Digital Ocean account. Create a personal access token

Get an SMTP account

I used [Mailgun][mailgun], but any provider will work. You'll need the server, port, login, and password.

A domain

You'll need a domain with DNS you control.

SSH Keys

There needs to be a private key, unencrypted, at ~/.ssh/id_rsa and a corresponding public key at ~/.ssh/


  1. install all required Terraform modules:
terraform init terraform/
  1. Fill out your details into terraform.tfvars in the root of the repository:
digital_ocean_token = "< digital ocean token>"
mastodon_domain = "mycool.example"
letsencrypt_email = "<your email address, needed by letsencrypt>"
smtp_login = "<smtp login>"
smtp_password = "<smtp password>"
  1. Then, create a terraform plan to create the floating IP:
terraform plan -target digitalocean_floating_ip.ip -out tf.plan terraform/
  1. If everything looks good, go ahead and and execute the plan:
terraform apply tf.plan
  1. That should give you a stable IP address. create an A record on your domain pointing to that IP.

  2. Let terraform plan out the rest of the infrastrucutre:

terraform plan -out tf.plan terraform/
  1. Apply the changes:
terraform apply tf.plan
  1. Wait 5-10 minutes for all the infrastructure to come up. Don't let your computer go to sleep.


Replacing the droplet.

Updating the salt files won't trigger a replacemet on its own. Instead, you can taint the droplet to trigger a replace:

terraform taint digitalocean_droplet.mastodon terraform/

Then plan and apply infrastructure changes as usual.

Running with a Salt Master

The script provinions the Droplet to work with masterless saltstack, but it can also use a local master.

  1. Set up a master locally.
  1. SSH into the droplet:
ssh -R 4505:localhost:4505 -R 4506:localhost:4506 Eroot@<floating ip>

the -R commands open remote ports to the local machine, so the droplet doesn't need to access

  1. On the droplet, edit /etc/salt/minion to point at at the localhost for master:
# Set the location of the salt master server. If the master server cannot be
# resolved, then the minion will fail to start.
master: localhost
  1. Restart the salt minion daemon:
systemctl restart salt-minion
  1. On the local host, accept the minion's key:
salt-key -a mastodon
  1. Edit /etc/salt/master to point at the appropriate directories:
    - /home/<user>/do_mastodon/salt/pillar

    - /home/<user>/do_mastodon/salt
  1. Apply the salt state:
salt mastodon state.apply

You can do this as much as you want, to update the Mastodon instance without the downtime incurred by destroy-and-replace.

Importing existing infrastructure

If you already have existing infrastructure you'd like to use with Terraform, you can import it. The most important resources to add are the static IP and the volume:

terraform import -config=terraform digitalocean_volume.do_volume $(curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer <your api token>" ""  | jq -r '.volumes[0].id')
terraform import -config=terraform digitalocean_floating_ip.ip $(curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer <your api token>" ""  | jq -r '.floating_ips[0].ip')


No description, website, or topics provided.







No releases published


No packages published