Setting up Ringer on AWS

Ringer can be deployed to an EC2 instance. The only requirements are enough memory and CPU to run your database and an attached volume with a capacity of around twice the size of your database. The operating system should be Ubuntu 22.04. Other operating systems may work, but they have not been tested. If you need to use a different operating system please get in touch!

First, note the name of the attached volume. It should be newly created or otherwise suitable to be reformatted. From here on we will assume that the volume is mounted at /dev/sdb. Also note the public hostname of your instance, which we will assume to be my-instance.amazonaws.com.

Installing Ringer

On the instance, run the following command to configure AWS credentials for the Ringer APT repository. We will provide the AWS access key ID and secret access key separately. If you don't have one, contact us.

cat << EOF > /etc/apt/s3auth.conf
AccessKeyId = YOUR_ACCESS_KEY_ID
SecretAccessKey = YOUR_SECRET_ACCESS_KEY
Region = 'eu-west-2'
EOF
            

Now run the following commands to install Ringer and PostgreSQL 16. If your production database is running on a diferent version of PostgreSQL, you can specify that instead. Ringer should work on versions 12+.

# Install required dependencies
apt-get update
apt-get install -y apt-transport-s3 wget gnupg lsb-release

# Add the Ringer PPA along with its public key
wget --quiet -O - https://ringer.dev/keys/02AAED66.asc | apt-key add -
echo "deb s3://ringer-releases stable main" > /etc/apt/sources.list.d/ringer.list

# Add the PostgreSQL PPA along with its public key
sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -

# Install Ringer and PostgreSQL
apt-get update
apt-get install -y ringer postgresql-16

# Stop the default PostgreSQL database
pg_ctlcluster 16 main stop
            

Preparing the disk

On the instance, run the following commands to set up the attached volume as part of a ZFS pool. Ringer will use this volume to store your database.

sudo zpool create ringer /dev/sdb
sudo zfs create -o mountpoint=/ringer ringer/ringer
sudo zfs create ringer/bases
sudo zfs create ringer/clones
            

Configuring and starting Ringer

On the instance, run the following commands to configure and start the Ringer server. Replace my-instance.amazonaws.com with the public host name of your instance. If you have set up DNS for a custom domain for this instance, use that instead. Note that this will configure Ringer to server over HTTP, which is not recommended for production deployment. You should configure TLS before using Ringer with your production database. For instructions on configuring TLS see here.

mkdir /var/ringer
cat << EOF > /etc/ringer.toml
domain = "my-instance.amazonaws.com"
url = "http://my-instance.amazonaws.com"
http_bind_address = "0.0.0.0:80"

database_path = "/var/ringer/db.sqlite"
zfs_pool_path = "/ringer"
database_port_min = 10000
database_port_max = 11000

filesystem.provider = "zfs"
scheduler.provider = "systemd"

[database]
provider = "postgres"
ownership = "postgres:postgres"
bin_dir = "/usr/lib/postgresql/16/bin"
EOF

systemctl start ringer-server
            

Now navigate to http://my-instance.amazonaws.com in your browser. If Ringer has started correctly, you should see the "Welcome to Ringer" landing page. Here you can enter the setup key from your Ringer account to complete the installation. This will configure Ringer with your account and allow users in your organisation to log in.

You're now ready to try out Ringer. After entering your setup key you will be taken to the main dashboard, from where you can download the Ringer CLI. The next step is to import a database into Ringer. If your database is hosted in Amazon RDS or Aurora, see this guide. When you're ready to run Ringer with your production database, see below for setting up TLS.

Configuring Ringer with TLS

We recommend using Ringer over HTTPS in production. HTTP is only supported to make it easy to initially set up and try things out. There are many ways to configure TLS and the right method depends on your specific architecture. In broad strokes, we recommend you assign a (sub-)domain to Ringer, e.g. ringer.my-org.com. You can then acquire a TLS certificate for this domain. A popular choice is Let's Encrypt. If your method needs to (temporarily) serve HTTP from the instance in order to complete a TLS challenge (for example if using certbot) then you can just shut down Ringer with systemctl stop ringer-server. When the challenge is complete, run systemctl start ringer-server to bring it back up.

Once you have a certificate and corresponding private key stored on the instance, edit /etc/ringer.toml to add the following lines:

[tls]
key_path = "/path/to/key.pem"
cert_path = "/path/to/cert.pem"
            
Additionally, change the http_bind_address line to
http_bind_address = "0.0.0.0:443"
            
and change the url line to start with https. Now restart Ringer with systemctl restart ringer-server and you should be good to go.

If you are running Ringer behind a load balancer that does TLS termination, there's no need to configure Ringer for TLS and you can keep serving HTTP with no problems.