Storage
Smaller items of data, such as usernames and text, will be stored in our PostgreSQL database. However for larger items such as images we need a different storage solution.
The storage solution recommended in this guide is Supabase Storage. We already use Supabase for our database. If you followed the Database page on this guide you should have already an account on Supabase and be subscribed to the Pro plan. The Pro plan includes 100GB of storage.
Bucket Creation
To create a new storage bucket, go to your Supabase project dashboard, choose your test environment project and click on the "Storage" icon on the left sidebar. Then click on "New bucket":
Enter a name for your bucket, e.g. "storage", and click "Save". In the case of Epic Fantasy Forge, we don't make the bucket public since it will contain user data, e.g. images visualizing user's worlds.
You should now have a bucket for your test environment in Supabase:
Naturally the bucket is still empty and doesn't contain anything. Now repeat the above steps to also create a bucket for your production environment.
In your production environment, drag and drop some file into the bucket so it is not completely empty. We will use this test file to verify our automated backups are working correctly in a later section of this guide.
We now have storage environments to store our user's larger data, such as images. Later in this guide we will utilize this storage.
Access Key
In order to allow a third-party to backup our S3 production bucket, we will create an access key. We will only need an access key for the production environment, not the test environment. Navigate to your production environment's dashboard in Supabase, click on the "Project Settings" icon on the left sidebar and click on "Storage" under the "CONFIGURATION" section. Ensure the toggle switch "Enable connection via S3 protocol" in the section "S3 Connection" is enabled and click on "New access key" in the "S3 Access Keys" section:
Enter a name for your access key, e.g. "SimpleBackups" since the backup provider that will use the key is SimpleBackups. Then click "Create access key":
Save the shown "Access key ID" and "Secret access key" to a secure location, e.g. your password manager. Then click "Done":
You should now have an access key for your Supabase S3 bucket:
Backups
To regularly backup our storage, we will use a third-party solution. The recommended backup server by this guide is SimpleBackups. The service offers several pricing tiers, Basic, Plus and custom plans. The Basic tier is free. The tier recommended in this guide is Basic in addition to a few custom addons.
Start by creating an account on SimpleBackups.
Backup Bucket
Our data needs to be backed up somewhere. We will use a Hetzner S3 bucket for this purpose. To create one, navigate to your project's dashboard in the Hetzner cloud and select "Object Storage" from the left sidebar. Then click on "Create Bucket":
Choose a location for your bucket, e.g. "Helsinki", and gave the bucket a name, e.g. "epic-fantasy-forge-backup". Leave the "Object Lock" as "Disabled" and the "Visibility" as "Private". Then click "Create & Buy now":
Click on your newly created bucket:
On your bucket's dashboard you can see the bucket's URL and name. You will need these later. Click on "Manage credentials" in the "S3 CREDENTIALS" section:
Click on "Generate credentials":
Enter a description for your credentials, e.g. "SimpleBackups" and click "Generate credentials":
You should now be presented with the credentials for your bucket. Save the "ACCESS KEY" and "SECRET KEY" to a safe place, e.g. your password manager, and then close the "Credentials generated" popup:
You should now have a set of credentials for your bucket:
Storage
Once you have an account on SimpleBackups you can start by creating your first backup. From the "What do you want to back up?" selection choose "S3":
Choose "Own server" and click on the "+" icon to add a server:
Click the "Copy" button under the command string you are supposed to run on your own server:
SSH into your production server and install some necessary dependencies:
sudo dnf install postgresql python pip git
Paste and run the command you copied earlier from SimpleBackups:
You can now click the "Validate" button in SimpleBackups and your server should now be registered with SimpleBackups.
To automatically install this SimpleBackups daemon whenever we re-provision our production server, we need to install it as part of our Infrastructure as Code setup. Modify the provision-production-environment.yml file to include the below line at the end of the "script" section:
- if [ "$APPLY_INFRASTRUCTURE_CHANGES" == "YES" ]; then ssh -i $CI_PRIVATE_KEY -o StrictHostKeyChecking=no henrik@$PRODUCTION_ENVIRONMENT_IP "curl -sSL https://my.simplebackups.io/api/setup/$SIMPLE_BACKUPS_ID/connect?token=$SIMPLE_BACKUPS_API_TOKEN | bash -s $SIMPLE_BACKUPS_TOKEN"; fi
Naturally replace the SSH username "henrik" above with your own username. Note that the username used here must be the same one used when you initially added the server to SimpleBackups.
Add the "SIMPLE_BACKUPS_ID", "SIMPLE_BACKUPS_API_TOKEN" and "SIMPLE_BACKUPS_TOKEN" CI variables in GitLab. You can take the values for these variables from the re-initialization script which you can find from SimpleBackups by clicking on your user icon on the top-right and selecting "Servers". Then select your registered server, e.g. "Production", to view the re-initialization script:
Finally you should have three additional CI variables:
We can now add a "Source Storage" in the "Which storage do you want to replicate?" section. Click on the "+" icon next to "Source Storage". For the provider choose "Supabase Object Storage". For the "Access Key" and "Secret Key" fields, enter the details of the access key you created in the section Access Key above. For the "Region" field choose "eu-north-1". For the "Bucket" enter "storage". For the "Project Reference ID", enter your project's ID which you can find under "Project Settings" in the field "Project ID" on Supabase. For the "Path" field, enter "/". Now click on "Validate".
Tip
If your "Region" is not available in the dropdown list, temporarily switch to "Amazon S3" for the "Provider" field and select your region from there. Then switch the provider back to "Supabase Object Storage" and the "Region" field should still be populated with the value you selected when the provider was "Amazon S3".
Enter a name for your storage, e.g. "Production Storage", and click "Save Storage":
For the "Destination Storage", we will use the bucket we created in the Backup Bucket section above. Click on the "+" icon next to "Destination Storage". For the provider choose "S3 Compatible Storage". For the "Key" and "Secret" fields, enter the details of the S3 credentials you created in the section Backup Bucket above. For the "Endpoint" field, enter the URL to your bucket, e.g. "hel1.your-objectstorage.com". You can find your S3 bucket connection details in Hetzner. See the Backup Bucket section above for more details. For the "Bucket" field, enter your bucket's name that you created in Hetzner earlier, e.g. "epic-fantasy-forge-backup". For the "Region" field choose the first part of your Hetzner S3 bucket URL, e.g. "hel1". For the "Path" field, enter "/". Now click on "Validate".
Enter a name for your backup storage, e.g. "Backup" and click "Save Storage":
For the "When should we run this storage replication?" section, keep the "Daily" schedule but remove any other schedules if present. You may have to pay for additional schedules whereas the daily schedule is free. Keep the "Source path" field empty. For the "Destination Path" field enter "storage". Then click "Validate Connection":
Name your new backup job, e.g. "Production Storage" and click "Create Storage Sync":
You should now have a job to backup your production storage on a daily basis. Click on the "Warmup/Run" button:
After the warmup completes successfully, click on the "Run now" button:
The backup should complete successfully:
You can verify that the backup was successful by verifying the contents of the S3 bucket in Hetzner. It should include the files in your production storage:
Database
Whilst our database is already backed up in Supabase, there is no harm in storing another backup with a different provider. To run additional backup jobs, we must first purchase more backup jobs as an add-on to our free Basic subscription. The cost will be $10 per month. To purchase this add-on, click on your profile icon on the top right and select "Subscription":
In the "Included Backup Jobs" section, set the field to 1. This will give you a total of 10 backups jobs. Disable the "Auto-scale Addons" toggle switch to avoid unexpected expenses.
Then click on "Update Add-ons":
To backup your database, go to your dashboard in SimpleBackups and select "PostgreSQL" in the "What do you want to back up?" section:
For the "Choose the server that will carry out the backup job" section, select "Own Server" and select your production server that you added to SimpleBackups earlier:
Now enter your database's connection details into the relevant fields. You can find them from the "Connect" button in Supabase. For more details see the Connecting to the Database section on the Database page of this guide. You need to pick the pieces, e.g. host, user, etc. from your connection string. Use the "Session pooler" connection string as a reference. For the "TLS/SSL Mode" section, select "required". Tick the checkbox "Back Up All Databases". Now click on "Validate Connection":
For the name of your backup job, enter "Production Database". For the "When do you want to run your backup?" section, keep the "Daily" entry but remove all other entries if present. Set the "RETENTION" to 1. For more retentions you would need to pay additionally as they are not included in our Basic subscription. In the "Where do you want to store your backup?" select the "Backup" storage you configured earlier and set the backup path to "database". Then click "Create Backup":
You should now have a SimpleBackups job to backup your production database. You can test your new backup job by clicking on "Run now":
The backup should be successful:
You can verify your backup was successful by checking if the S3 backup bucket in Hetzner contains a copy of your database.
GitLab
To backup your GitLab account, go to your dashboard in SimpleBackups and select "GitLab" in the "What do you want to back up?" section:
Choose "Own Server" and select your "Production" server that you added to SimpleBackups earlier. Select "GitLab" in the "Select the app you want to backup" section and click the "+" icon beside the "GitLab Connection" field:
Select "GitLab.com - OAuth" as the "Provider" and name your GitLab connection, e.g. "Epic Fantasy Forge". Then click on "Connect GitLab.com - OAuth":
Click the "Authorize SimpleBackups" button:
In the "Configure your GitLab backup" section, enable the "Backup Repositories & Projects" toggle switch and select either "All Repositories" or "Specific Repositories" depending on your needs. For the "BACKUP OPTIONS", enable all of the checkboxes. Enable the "Backup Snippets" toggle button. Then click "Validate Connection":
In the "When do you want to run your backup?" section, keep the "Daily" schedule and remove all other schedules if present. In the "Where do you want to store your backup?" section, select the "Backup" storage you configured earlier. Set the backup path to "gitlab". Then click on "Create Backup":
You should now have a job in SimpleBackups to backup your GitLab account. To test if it is working, click the "Run now" button:
The backup should complete successfully:
Backup Alerts
To receive alerts whenever a backup fails, complete your account setup by clicking on "Complete your setup!" on your SimpleBackups dashboard:
Enable the "Activate backup anomaly detection" toggle button and click "Mark step as completed" for the "Activate advanced backup monitoring" section. By default, one notifcation channel should already be configured which includes the email address you used to register an account on SimpleBackups.
For the "Invite your team" section, click the "Mark step as completed" button: