Deploy Forem on AWS and build your tech community

Photo by Ben den Engelsen / Unsplash

Forem is an open-source software for building communities. Communities for your peers, customers, fanbases, families, friends, and any other time and space where people need to come together to be part of a collective.

Dev.to, one of the most well-known software developers community is powered by Forem. This is a great tool if you want to build your own community around a specific topic.

If you find it great for your case, you will need to deploy it on your own server. In this post, we will see how to self-host Forem on AWS and Digital Ocean.

Prerequisites

I'm a MacOS user; since the setup varies depending on the Operating System, we will use Docker to make this process OS agnostic. The only requirement is to install Docker; we will use it to create a container from a Fedora image. Fedora is preferred among other Linux distributions because the installation process of Forem needs butane (previously Fedora CoreOS Configuration Transpiler).

Start a Fedora Docker container

Before running the Docker command, let's pull the image from the Docker Hub.

docker pull fedora

docker run --rm -it -v $HOME/forem:/home/selfhost fedora 

Note: the --rm flag will delete the container automatically when you exit.

We will work inside the home directory, so navigate to this directory with the command: cd home

Fedora Docker container from the shell.

Clone Forem Selfhost repository

Let's clone the GitHub repository containing the files necessary to install Forem on our own server. It is main the Ansible playbook that will perform a suite of tasks on the VPS. The docker image doesn't come with Git installed, so we will install it first.

dnf install git -y

git clone https://github.com/forem/selfhost.git

cd selfhost
Clone the repository from GitHub

We are now inside the folder /home/selfhost , and all the following commands will be run inside this folder.

Install the Python dependencies

Run the command below:

dnf install python3-pip -y

pip3 install -r requirements.txt

Generate an Ansible Vault password

Run the command below to generate the ansible vault password; it will be used under the hood when executing the playbook.

dnf install pwgen -y

mkdir -p ~/.config/forem

pwgen -1 24|tee ~/.config/forem/selfhost_ansible_vault_password

Duplicate and edit the Ansible Inventory

Run the command below to copy the example ansible inventory:

cp inventory/example/setup.yml inventory/forem

Open the duplicated ansible repository for edition:

dnf install nano -y

nano inventory/forem/setup.yml

Edit the following Ansible inventory variables:

  • default_email (Admin Email for the system to use)
  • forem_domain_name (A domain name that you own and set A records on at your DNS provider)
  • forem_subdomain_name (defaults to www)
  • forem_server_hostname (defaults to host)

I want to host Forem on the subdomain forem.tericcabrel.com so, here are the values for my case:

default_email: contact@tericcabrel.com
forem_domain_name: tericcabrel.com
forem_subdomain_name: forem
forem_server_hostname: forem_server

Save and exit from the editor.

Edit the file setup.yml from the host

Edit a YAML file is tricky because you need to care about indentation; editing this file inside the terminal is not the best way. Remember when starting the Docker container, when added the option $HOME/forem:/home/selfhost; this basically maps the folder's content /home/selfhost in the Docker container to the folder $HOME/forem on our physical computer. You can edit the setup.yml from your computer using your favorite editor.

This will be very helpful for the following part.

Generate secrets for four Ansible inventories

We want to generate a secret for these four properties inside the setup.yml file:

  • vault_secret_key_base
  • vault_imgproxy_key
  • vault_imgproxy_salt
  • vault_forem_postgres_password

The process is the same for each property:

1- Run the command to generate the secret
2- Copy in the clipboard the output of the command
3- Locate the property in the setup.yml file
4- Paste the output copied in the clipboard to see it as the value of this property.

Important: Beware of the indentation!!!

Generate secret for vault_secret_key_base

Run the command below:

echo -n $(pwgen -1 128)|ansible-vault encrypt_string --stdin-name vault_secret_key_base

Here is the output:

How to set the Ansible Vault.

Generate secret for vault_imgproxy_key

Run the following command:

echo -n $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n') | ansible-vault encrypt_string --stdin-name vault_imgproxy_key

Generate secret for vault_imgproxy_salt

Run the following command:

echo -n $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n') | ansible-vault encrypt_string --stdin-name vault_imgproxy_salt

Generate secret for vault_forem_postgres_password

Run the following command:

echo -n $(pwgen -1 128)|ansible-vault encrypt_string --stdin-name vault_forem_postgres_password

Deploy on AWS or Digital Ocean

We will continue by deploying Forem on AWS; if you are interested in the deployment process on Digital Ocean, I wrote a separate post to show you how.

Deploy Forem on Digital Ocean and build your tech community
Forem is an open-source software for building communities. In this post, we will see how to deploy self-host Forem on a Digital Ocean droplet.

Generate an SSH RSA key

This key will be used to connect to the EC2 instance we will create later.
Run the command below, give the name forem to the key and enter a passphrase if you want:

ssh-keygen -t rsa
Generate the SSH RSA key

Install Ansible collection for AWS

ansible-galaxy collection install amazon.aws community.aws

Update EC2 instance settings

In the file playbooks/providers/aws.yml, locate the following variables and update them based on your needs:

fcos_aws_region: eu-west-1
fcos_aws_size: t3a.small
fcos_aws_ebs_size: 60
  • fcos_aws_region: the AWS region used to set up your Forem server. The default region is in us-east-1, in North Virginia, USA
  • fcos_aws_size: the AWS EC2 instance type. A recommended type is a t3a.small EC2 instance, with 2 VCPUs and 2GB of RAM.
  • fcos_aws_ebs_size: the amount of EBS disk space (in GB).

Save and exit.

Install and configure AWS CLI

Run the commands below to install the CLI:

dnf install unzip -y

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

unzip -q awscliv2.zip

./aws/install

aws --version

You will get the output similar to this:

Install the AWS CLI 

Set the AWS Access ID and Access Secret Key

Create an AWS IAM user with Programmatic access called forem-selfhost with the following AmazonEC2FullAccess, AmazonS3FullAccess, AmazonVPCFullAccess AWS managed policies attached. You will have the Access Id and the Access Secret Key at the end of this process.

Run the command below to set these credentials:

aws configure --profile forem-selfhost

Input the access key ID and secret key when prompted. We use us-east-1 for default region name, but you can choose a different one if you wish. Set default output format to json.

Configure the AWS Profile

Run the Ansible playbook

Butane is required at some step when running the playbook. Let's install it first:

dnf install butane -y

butane -V

Finally, run the playbook and wait for it to complete:

ansible-playbook -i inventory/forem/setup.yml playbooks/providers/aws.yml
The Ansible playbook was executed successfully.

Configure the DNS Zone

We need to create a DNS record of type A that points the subdomain forem.tericcabrel.com to the EC2 instance IP address where Forem is installed. This IP address is printed at the end of the Ansible playbook execution.

Go to your domain name provider and look at how to do that. My domain name is registered at OVH.

Configure the DNS Zone

Wait for the DNS to propagate completely. You can check the propagation status on this website: whatsmydns.net.

Restart the Web server service

Connect to the server through SSH using the private key:

ssh -i "~/.ssh/id_rsa" core@<server_public_dns>

Once connected, run the command below:

sudo systemctl restart forem-traefik.service

First connection to Forem

Navigate to your subdomain URL, in my case: forem.tericcabrel.com; you will see a beautiful webpage. Please see the Forem Admin documentation located here for more information on setting up your Forem.

Create the first admin user.

Provide information to create the admin user and submit. You will be redirected to a page to add basic information about the community.

Configure Forem settings

Define the settings as you want and click on finish

Forem configured successfully ?.

Yay ?! You are all set. You can continue writing your first article.

Forem Control (foremctl)

Since Forem is now running on your server, you will need to perform some tasks often to check the health, restart, update the version, etc...

foremctl is a helper script you can use to control your Forem via CLI.

$ foremctl help

Usage: foremctl {console|deploy|help|rake|restart|start|stat|status|stop|update|version}

console         Open a Rails console
deploy          Updates and deploy the most current version of Forem
help            Show this message
rake            Run a rake task
restart         Restart Forem
start           Start Forem
stats           Show CPU, RAM, Disk IO usage of the Forem containers
status          Show the current running Forem containers
stop            Stop Forem
update          Updates Forem to the lastest container
version         Shows information on the current running version of Forem

Update Forem to the latest version and restart

sudo foremctl deploy

Note: The deploy process causes a small downtime while the Forem code restarts.

Going Further

There are many other commands you can run to manage your Forem application. To learn more, check out this repository on GitHub.

GitHub - forem/selfhost: Selfhost your Forem Community on your own infrastructure ?
Selfhost your Forem Community on your own infrastructure ? - GitHub - forem/selfhost: Selfhost your Forem Community on your own infrastructure ?

Follow me on Twitter or subscribe to my newsletter to not miss the upcoming posts and the tips and tricks I share every week.

Happy to see you soon ?