Self-hosted Taiga.io on Scaleway
Tags: taiga, docker, scaleway, backup
Published: 2021-11-28 20:57:11

There may come a time in one’s life where long term project planning is needed. I’m a big fan of Taiga for project management and I’ve been using both free and paid plans on their saas platform. Check it out before you decide to follow in my footsteps as their free offering is positively good.

----

## The Task

Deploy dockerised taiga.io
Host it on the cheap (single instance, no external db), but ensure full, encrypted off-site backup.

## Infrastructure

Taiga is open source, what is more unlike a lot of open source saas the team behind Taiga offers a dockerised version, which you can config and run on the server. Pick whatever provider you like, I chose [Scaleway](https://www.scaleway.com) and used one of their guides for backups. Scaleway offers an s3 compatible api for object storage, so you can use [s3cmd](https://github.com/s3tools/s3cmd) if you like it. They also have a s3 glacier equivalent, which is nice. In any case, first 75GB of storage is free, and you are unlikely to hit that unless you store a lot of media with your tasks.

## Setup

At this point in time we only care about getting a running setup, upgrades may come in the future. There is a [new version of Taiga coming in 2022](https://blog.taiga.io/announcing_taiganext.html), so depending on the upgrade path, I will probably write a new post :)  

Assuming you already have access to your instance, follow the 
[Install Taiga in Production guide](https://docs.taiga.io/setup-production.html). I've had a bit of a problem with email setup (gmail most likely will work for you, but before I figured out what the issue was I have already setup a free account on SendGrid), so here are my env vars:

```yaml
EMAIL_BACKEND: "django.core.mail.backends.smtp.EmailBackend"
DEFAULT_FROM_EMAIL: "no-reply@mycompany.com"
EMAIL_USE_TLS: "True"
#EMAIL_USE_SSL: "False"
EMAIL_HOST: "smtp.sendgrid.net"
EMAIL_PORT: 587
EMAIL_HOST_USER: "apikey"
EMAIL_HOST_PASSWORD: "YOUR_KEY_HERE"
```

Note the commented out `EMAIL_USE_SSL`.

## Configuring Nginx

Install certbot on your server and obtain the certificate for your domain.
Update nginx config file in 'taiga-gateway' dir. I might publish my setup, but it's unlikely given how much I would need to change or strip out to remove secrets from the base Taiga one. Just make sure you set up TLS properly and add your domain.

## Backups

I'm hoping that by now you have Taiga up and running, so let's move onto setting up backups. These are handled by [duplicity](https://duplicity.gitlab.io/duplicity-web/index.html).

The steps are as follows:

* Install duplicity
* Create GPG keys
* Manual test
* Add shell scripts to cron to automate the process

I have followed this [guide from Scaleway](https://www.scaleway.com/en/docs/tutorials/backup-dedicated-server-s3-duplicity), however, if like me you install the newer version of duplicity, then you will need to adjust the shell scripts as params have changed. I've installed 0.8.21 and if you look into [my repo](https://github.com/strayobject/scaleway-backup-scripts) you will be able to find all the updated scripts.

## DB backup

This is a simple script that outputs a .pgdata file which contains snapshot of our taiga DB.

```bash
#!/bin/bash

if [ $# -lt 4 ]; then
  echo -e "Usage $0 <container_name> <db_user_name> <db_name> <backup_file_path>"
  echo -e "Exemple:"
  echo -e "$ $0 taiga_taiga-db_1 taiga taiga /backups/db/db.pgdata ## based on defaults from Taiga docker repo
  ";
  exit;
fi

CONTAINER_NAME=$1
DB_USER=$2
DB_NAME=$3
BACKUP_FILE_PATH=$4

docker exec -i "$CONTAINER_NAME" /bin/bash -lc "pg_dump --username \"$DB_USER\"  --format custom \"$DB_NAME\"" > "$BACKUP_FILE_PATH"
```

## Media backup

Another simple script that copies contents of taiga media container. Note that I take a simple copy, without stopping of containers nor any data verification, which does not guarantee data integrity. In my case, with the backups scheduled at night, there is very low risk that there could be an issue. Your mileage may vary.

```bash
#!/bin/bash

# This script is quite pointless at the moment.
if [ $# -lt 2 ]; then
  echo -e "Usage $0 <source_dir_path> <backup_dir_path>"
  echo -e "Exemple:"
  echo -e "$ $0 /var/lib/docker/volumes/taiga_taiga-media-data/_data /backups/media ## based on defaults from Taiga docker repo
  ";
  exit;
fi

SOURCE_DIR_PATH=$1
BACKUP_FILE_PATH=$2

cp -R "$SOURCE_DIR_PATH" "$BACKUP_FILE_PATH"
```

## Cron

Set up cron to your liking, mine is similar to the one below. Note that I'm restarting gateway daily, to ensure certificate swap when certbot updates the ssl certificate. (I'm aware there are hooks I could use, but at this point this is good enough for me.)

```bash
0 0 * * * /bin/db-backup.sh <container_name> <db_user_name> <db_name> <backup_file_path> >> /var/log/taiga-cron.log 2>&1
0 0 * * * /bin/media-backup.sh <source_dir_path> <backup_dir_path> >> /var/log/taiga-cron.log 2>&1
0 3 * * * /bin/upload-backup.sh <config_dir_path> >> /var/log/taiga-cron.log 2>&1
0 4 * * * cd /var/www/taiga && /usr/local/bin/docker-compose restart taiga-gateway >> /var/log/taiga-cron.log 2>&1
```

----

If you have reached the end then you should now have a fully working self-hosted instance of Taiga with an encrypted backup to whatever off-site storage you chose to use.  

In the next part (if time allows), I will write about pulling the backup onto your local machine and importing it to a blank instance of Taiga. With that said, the relevant scripts to fetch the data from storage and to import the DB are in the [repo on github](https://github.com/strayobject/scaleway-backup-scripts).