Want your address to be @name@example.com while Mastodon runs on social.example.com? That works, and your website stays on the main domain. This guide shows you what to set in DNS, Mastodon and nginx or Apache 2.
What the two values mean
| Value | Example | Purpose |
|---|---|---|
LOCAL_DOMAIN | example.com | Appears in addresses: @name@example.com |
WEB_DOMAIN | social.example.com | Where Mastodon runs and where everyone logs in |
Other servers only know the address at first, so they ask example.com. The web server on your main domain has to redirect these requests to social.example.com. That is all there is to it.
Important: Set both values before the first start. Once your instance has talked to other servers, you can no longer change them without breaking federation.
Step 1: DNS
Create the Mastodon subdomain at your DNS provider:
| Name | Type | Value |
|---|---|---|
social | A | IPv4 address of the Mastodon server |
social | AAAA | IPv6 address of the Mastodon server, if it has one |
The records for your main domain and your MX records stay as they are. The main domain only needs a valid HTTPS certificate, because the redirect has to work over HTTPS.
Step 2: Mastodon
Add both values to .env.production:
LOCAL_DOMAIN=example.com
WEB_DOMAIN=social.example.com
Mastodon’s own web server and its certificate only run on the WEB_DOMAIN.
Step 3: Redirect on the main domain
These settings go on the server that hosts example.com, not on the Mastodon server. Replace social.example.com with your own address.
nginx
In the server block for port 443:
location ~ ^/\.well-known/(webfinger|host-meta|nodeinfo)$ {
add_header Access-Control-Allow-Origin "*" always;
return 301 https://social.example.com$request_uri;
}
Then check and reload: nginx -t && systemctl reload nginx
Apache 2
In the VirtualHost for port 443. The header line needs mod_headers (a2enmod headers):
<LocationMatch "^/\.well-known/(webfinger|host-meta|nodeinfo)$">
Header always set Access-Control-Allow-Origin "*"
</LocationMatch>
Redirect 301 /.well-known/webfinger https://social.example.com/.well-known/webfinger
Redirect 301 /.well-known/host-meta https://social.example.com/.well-known/host-meta
Redirect 301 /.well-known/nodeinfo https://social.example.com/.well-known/nodeinfo
Then check and reload: apachectl configtest && systemctl reload apache2
Apache 2 with .htaccess, for example with WordPress
If you cannot edit the server configuration, the .htaccess file works too. The rule has to come before the # BEGIN WordPress block:
RewriteEngine On
RewriteRule ^\.well-known/(webfinger|host-meta|nodeinfo)$ https://social.example.com/.well-known/$1 [R=301,L]
Step 4: Test
Request the address the way another Mastodon server would. Replace the domain and name:
curl -sI -A 'http.rb/5.2.0 (Mastodon/4.7.5)' \
'https://example.com/.well-known/webfinger?resource=acct:name@example.com'
The response should look like this. The ?resource=… part has to survive the redirect:
HTTP/2 301
location: https://social.example.com/.well-known/webfinger?resource=acct:name@example.com
If Mastodon is already running, follow the redirect to the end. You will get JSON with your account:
curl -sL -A 'http.rb/5.2.0 (Mastodon/4.7.5)' \
'https://example.com/.well-known/webfinger?resource=acct:name@example.com'
Finally, search for @name@example.com from another instance. If your account shows up, everything is set up correctly.
If it does not work
- It works in the browser but not in the test: A bot block, web application firewall or CDN is blocking server requests, often with 403 or 418. Always test with the Mastodon user agent as shown above, and exclude the three paths from the block.
- nginx returns the block despite the redirect: An
ifwithreturndirectly in theserverblock runs before anylocationblock. Move the block intolocation /or exclude the paths there. - nginx returns 404: A
location ^~ /.well-known/block takes priority over the redirect. Put the redirect there or narrow that block, for example to/.well-known/acme-challenge/. - The account cannot be found: Check that
?resource=…survives. Without it, Mastodon cannot answer the request. - Certificate errors: The main domain needs a valid certificate. Other servers will not follow a redirect from an address with an invalid certificate.
- Your main domain already has a Fediverse connection, such as the ActivityPub plugin for WordPress: It uses the same paths. Pick one, because two services cannot answer on the same domain at once.
You can find more in the Mastodon documentation.
Want me to take care of this?
I run Mastodon instances with custom domains on servers in Germany and set all of this up for you. You only add the DNS records and the redirect.