Thanks to Oracle Cloud Free Tier, you can get a good server that can host your fediverse instance 100% free, indefinitely. And with free DNS services, you can get a subdomain name that will allow it to federate.
Part 1: Get a free server
Create an Oracle Cloud account
You will need a credit card to create an account, but no money will ever be charged unless you explicitly upgrade the account to a paid account.
Head over to https://www.oracle.com/cloud/free/ and click “Start for free” to start the process. Choose a region that is close to you for the lowest latency. You cannot change this later.
Create the virtual server
- Navigate to Compute -> Instances. On the left, choose your root compartment. Click “Create Instance”.
- On “Image and shape”, click Edit.
- Click “Change shape”. Click “Ampere”, scroll down and select “VM.Standard.A1.Flex”. Increase “Number of OCPUs” to 4, and “Amount of memory (GB)” to 24.
- Click “Change image” and select “Ubuntu” -> “Canonical Ubuntu 22.04”.
- Under “Boot volume”, select “Specify a custom boot volume size”. Set “Boot volume size (GB)” to 200.
- Click “Save private key” so that you can access the instance with an SSH client.
- Everything else can be left as is. Click “Create”.
⚠ If you get a “Out of host capacity” error, then unfortunately you can’t get the good free server at this time. You will have to use this script, https://github.com/hitrov/oci-arm-host-capacity , to automatically try creating the instance over and over again until it works. This might take days, weeks or months. You can create a free AMD instance to run the script 24/7 or you can run it anywhere else. Keep in mind that you only have 30 days to exceed the free tier limits, afterwards you will not be able to have more than 200GB total of storage volumes, so if you’ve created one server with 200GB you will not be able to run another. You may want to change the boot volume size to default before using this script, and then expand it to 200GB once you obtain the ARM server and delete the AMD server.
You might be able to run Pleroma on a 1GB AMD instance, if you add swap. You can add swap with the following commands as root (type sudo -i
to become root): dd if=/dev/zero of=/swapfile bs=1M count=4096; chmod 600 /swapfile; mkswap /swapfile; swapon /swapfile; echo "/swapfile none swap sw 0 0" >> /etc/fstab
. (then exit
root). But it will be slow, you should wait for the free 24GB 4-core ARM server.
Connect to the virtual server
- Find the private key you downloaded and rename it to “id_rsa”. Go to your home directory (
%homepath%
), create a folder named.ssh
if it does not exist, and place theid_rsa
file in there. - On the Oracle Cloud dashboard, select your instance and copy the “Public IP Address”.
- Open a Command Prompt and type in
ssh ubuntu@
, then paste the IP address by right-clicking. Example:ssh ubuntu@192.9.148.6
. Press enter - You should now be connected to your server. Now is a good time to update it, type:
sudo apt update; sudo apt upgrade; reboot
Prepare the Oracle firewall for web traffic
- On the Instance page on Oracle Cloud dashboard, select “Attached VNICs” on the bottom right, and then select the subnet in the “Subnet or VLAN” column.
- Select the “Default Security List”. Click “Add Ingress Rules”. Fill in the following information:
- Source CIDR: 0.0.0.0/0
- IP Protocol: TCP
- Destination Port Range: 80,443
- Click “+ Another Ingress Rule”
- Source CIDR: 0.0.0.0/0
- IP Protocol: UDP
- Destination Port Range: 443
- Click “Add Ingress Rules”.
Part 2: Obtain a domain name
The domain name is where your server will live and will be a permanent part of your handle. Domains typically cost $10-$20 per year, but you can often get a first year sale for a dollar.
If you don’t want to buy a domain, there are plenty of “free DNS” solutions where you can get a free subdomain, for example: my-awesome-fedi-server.chickenkiller.com
. One of the best free DNS providers is https://freedns.afraid.org/
, but there is also https://www.noip.com/
, https://www.duckdns.org/
.
Simply create a subdomain/hostname of type “A” with the “Public IPv4 Address” of your Oracle Server.
Another service you can use is nip.io
, this lets you get started without creating an account or anything. Simply append .nip.io
to the end of your IP address, and you have a hostname that you can use to host your instance. (It is actually possible to host a server on the raw IP address, but it is hard to set up SSL and it breaks some fedi platforms.)
Once you have a domain/hostname, go to nslookup.io and type in the name. You should see your A record with your server’s IP address. If not, you may need to wait a few minutes and try again. Once you see that, the name is ready to be used.
Part 3: Install the web server
The web server connects the people on the internet to the web services running on the server. The best web server is Caddy, as it is very easy to configure and it automatically takes care of all the SSL certificate stuff so you don’t even need to THINK about it.
- Per the caddy documentation
, install caddy by running each of these commands, one by one:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
- Type in
sudo nano /etc/caddy/Caddyfile
to open the config in the nano text editor, and add this to the bottom, replacingmy-awesome-fedi-server.chickenkiller.com
with the domain name you got for the server. Press ctrl O to write and ctrl X to exit.
Or if you are going to use Mastodon:my-awesome-fedi-server.chickenkiller.com { reverse_proxy localhost:3000 }
my-awesome-mastodon-server.chickenkiller.com { reverse_proxy /api/v1/streaming* localhost:4000 reverse_proxy localhost:3000 }
- Type
sudo systemctl reload caddy
. In a few moments you should be able to type in your domain name into the web browser and see a 502 error. This means the web server is working, and now we just need the backend service.
Part 4: Install the fediverse software
Choose one of these applications to install.
Pleroma/Akkoma
I recommend Pleroma because it is the most usable software with relatively few issues, and it is simple and easy to host.
- Install all the packages that you will need:
sudo apt update; sudo apt install git build-essential postgresql postgresql-contrib cmake libmagic-dev elixir erlang-dev erlang-nox imagemagick ffmpeg libimage-exiftool-perl
- Run this:
echo "export MIX_ENV=prod >> .profile; exec bash
. This will let you run pleroma commands without typingMIX_ENV=prod
every time, which is needed to run it in production mode, otherwise it runs in development mode, which we don’t want. - Download the Pleroma code:
git clone https://git.pleroma.social/pleroma/pleroma.git -b stable
- If you want to use Akkoma, just replace the git url with
https://akkoma.dev/AkkomaGang/akkoma.git
- If you want to use Akkoma, just replace the git url with
- Enter the pleroma folder:
cd pleroma
- Load all the dependencies:
mix deps.get
- Generate configuration file:
mix pleroma.instance gen
- The server name must be the domain name you got
- When it asks for port, type in 3000 so it matches the caddy config.
- Leave all the database settings default (just press enter)
- I recommend deduplicating uploads to save disk space.
- Rename the configuration file:
mv config/{generated_config.exs,prod.secret.exs}
- Initialize the database:
sudo -u postgres psql -f config/setup_db.psql
- Import the schema:
mix ecto.migrate
- Test the server:
mix phx.server
. Visit your domain name in the browser to see if it is working. - Stop the server with Ctrl-C.
- Type:
sudo nano /etc/systemd/system/pleroma.service
and type or paste in the following:[Unit] Description=Pleroma social network After=postgresql.service [Service] User=ubuntu Environment="MIX_ENV=prod" WorkingDirectory=/home/ubuntu/pleroma/ ExecStart=/usr/bin/mix phx.server [Install] WantedBy=multi-user.target
- Enable and start the service:
sudo systemctl daemon-reload; sudo systemctl enable --now pleroma
- Create the first admin account:
mix pleroma.user new <username> <your@emailaddress> --admin
- Open the URL in your browser to activate the account with a password.
Misskey/Sharkey
Misskey is modern and feature-rich but lacks support for post edits, so I recommend using Sharkey instead of Misskey.
- Install dependencies
- Install Node.js >=20 with the following commands
curl -fsSL https://deb.nodesource.com/setup_lts.x -o nodesource_setup.sh
sudo -E bash nodesource_setup.sh
sudo apt-get install -y nodejs
sudo corepack enable
- Install PostgreSQL >=15
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install postgresql-16
- Install the rest of the packages:
sudo apt install redis ffmpeg build-essential git
- Install Node.js >=20 with the following commands
- Prepare the database
- Create database user:
sudo -u postgres createuser ubuntu
. - Create database:
sudo -u postgres createdb -O ubuntu sharkey
- Create database user:
- Download Sharkey:
git clone --recurse-submodules -b stable https://activitypub.software/TransFem-org/Sharkey.git sharkey
- Enter Sharkey folder:
cd sharkey
- Load its npm packages:
pnpm install --frozen-lockfile
- Prepare config file:
cp .config/example.yml .config/default.yml
- Edit config file:
.config/default.yml
- Replace
example.tld
with your domain name. - Set
db:
tosharkey
,user:
toubuntu
and deletepass:
. Since the DB username is the same as the Linux username, no password is needed. - I suggest setting
proxyRemoteFiles:
tofalse
or your disk will fill up with other people’s files. Also, if this is enabled, posts will go missing if it can’t download the attachment, such as if it’s too large.
- Replace
- Build Sharkey:
pnpm run build
- Initialize db:
pnpm run init
- Test the server:
pnpm start
. Open the URL in your browser. - Press ctrl C to stop the server. Type
sudo nano /etc/systemd/system/sharkey.service
and paste in the following:[Unit] Description=Sharkey After=postgresql.service redis.service [Service] User=ubuntu WorkingDirectory=/home/ubuntu/sharkey/ ExecStart=/usr/bin/pnpm start Environment=NODE_OPTIONS=--max-old-space-size=8192 NODE_ENV=production [Install] WantedBy=multi-user.target
- Enable and start the service:
sudo systemctl daemon-reload; sudo systemctl enable --now sharkey
Mastodon
Mastodon is the most well known and polished but lacks reactions and has deliberate hard-coded limitations (you cannot see more than four attachments, you cannot attach images with video, you cannot have more than four poll options, etc).
Mastodon requires an email server. You can manually approve accounts on the command line, but it is not possible to allow automatic approval without an email server.
- Install system dependencies
- Install the latest LTS Node.js with the following commands
curl -fsSL https://deb.nodesource.com/setup_lts.x -o nodesource_setup.sh
sudo -E bash nodesource_setup.sh
sudo apt-get install -y nodejs
sudo corepack enable
yarn set version classic
- Install rest of packages:
apt install ruby ruby-bundler ruby-dev postgresql postgresql-contrib redis imagemagick ffmpeg git build-essential autoconf libpq-dev libxml2-dev libxslt1-dev libprotobuf-dev protobuf-compiler pkg-config bison libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev libidn11-dev libicu-dev libjemalloc-dev
- Install the latest LTS Node.js with the following commands
- Create database user:
sudo -Hu postgres createuser -d ubuntu
- Download mastodon and enter folder:
git clone https://github.com/mastodon/mastodon.git; cd mastodon
- Checkout the latest version:
git checkout $(git tag -l | grep '^v[0-9.]*$' | sort -V | tail -n 1)
- Install application dependencies
bundle config deployment 'true'
bundle config without 'development test'
bundle install -j$(getconf _NPROCESSORS_ONLN)
yarn install --pure-lockfile
- Run the Mastodon setup wizard:
RAILS_ENV=production bundle exec rake mastodon:setup
- Type
ubuntu
for the PostgreSQL user. Since it is the same as Linux user, no password is needed.
- Type
- Create each of these files with
sudo nano
:/etc/systemd/system/mastodon-web.service
[Unit] Description=mastodon-web After=postgresql.service redis.service [Service] User=ubuntu WorkingDirectory=/home/ubuntu/mastodon/ Environment=RAILS_ENV=production PORT=3000 RAILS_SERVE_STATIC_FILES=true LD_PRELOAD=libjemalloc.so ExecStart=/usr/bin/bundle exec puma -C config/puma.rb [Install] WantedBy=multi-user.target
/etc/systemd/system/mastodon-sidekiq.service
[Unit] Description=mastodon-sidekiq After=postgresql.service redis.service [Service] User=ubuntu WorkingDirectory=/home/ubuntu/mastodon/ Environment=RAILS_ENV=production DB_POOL=25 MALLOC_ARENA_MAX=2 LD_PRELOAD=libjemalloc.so ExecStart=/usr/bin/bundle exec sidekiq -c 25 [Install] WantedBy=multi-user.target
/etc/systemd/system/mastodon-streaming.service
[Unit] Description=mastodon-streaming After=postgresql.service redis.service [Service] Type=simple User=ubuntu WorkingDirectory=/home/ubuntu/mastodon/ Environment=NODE_ENV=production PORT=4000 ExecStart=/usr/bin/node ./streaming [Install] WantedBy=multi-user.target
- Start the services:
sudo systemctl daemon-reload; sudo systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming
- Sign in to your admin account and navigate to
https://<your domain>/admin/settings/content_retention
. Add a value under “Media cache retention period”, such as 30 days. Otherwise, you will run out of disk space as everyone’s media is downloaded and kept forever.
The End
If you encountered any issues, report them to me on fediverse or wherever. Eventually, I will add comments to this blog site thing.