Skip to main content
Version: v2.11

Ansible example

This document shows some Ansible scripts that can serve as a starting point to deploy Tobira.

note

These are not ready-to-use scripts. You have to adjust them according to your needs! In fact, this is even untested. It's just provided on a best effort basis.


Known problems and missing things

  • These scripts don't setup automatic database backup. But you should!
  • These script can't deal properly with a Meili update that requires the index to be deleted/rebuilt.
  • These scripts don't use tobira check which is a useful to command to run before restarting Tobira to make sure the restart will actually likely succeed.
  • Webserver (e.g. nginx) setup is completely missing. This depends a lot on your authentication setup. A few notes:
    • Make sure to properly compress JS, SVG, HTML, and similar files. It improves loading speed by a lot!
    • You likely want to set some security relevant headers. Tobira already sets Content-Security-Policy by itself, but everything else you have to decide.

Variables

Be sure to adjust the versions – we rarely update these docs.

vars.yml
db_password: "{{ vault_db_password }}"
meili_key: "{{ vault_meili_key }}"
tobira_trusted_external_key: "{{ vault_tobira_trusted_external_key }}"

tobira_release_url: "https://github.com/elan-ev/tobira/releases/download/v1.2/tobira-x86_64-unknown-linux-gnu"
tobira_release_checksum: "sha256:c173c60bc35e8fa922324910a4968557903c9382a5d46d67cc99a15df262e245"
meili_release_url: "https://github.com/meilisearch/meilisearch/releases/download/v1.4.2/meilisearch-linux-amd64"
meili_release_checksum: "sha256:b54b9ace213b0d45558c5d0e79710f718b63d2e29c190fb95be01dc27eb1ca5c"

Services

MeiliSearch

roles/tobira/tasks/setup_meili.yml
- name: create MeiliSearch directory
file:
path: /opt/meili
state: directory
mode: '0755'

- name: install MeiliSearch
get_url:
url: '{{ meili_release_url }}'
dest: /opt/meili/meilisearch
mode: '0755'
checksum: '{{ meili_release_checksum }}'
# TODO: this does not handle rebuilding the search index when doing a major meili update!
# In that case, delete `/opt/meili/data.ms` and restart the tobira worker.
notify: restart meili

- name: install MeiliSearch service file
template:
src: meili.service
dest: /etc/systemd/system/meili.service
mode: '0644'
owner: root
group: root
notify: restart meili

- name: start and enable Meili
service:
name: meili
state: started
enabled: true
daemon_reload: true

Database

The following sets up a new PostgreSQL database. But maybe your organization already offers a DB cluster with PostgreSQL. In that case, you should use it. Also not shown here: setup regular database backups!

roles/tobira/tasks/setup_db.yml
- name: install dependencies
package:
state: present
name:
- postgresql-server
- postgresql-contrib
# Python packages required for the 'postgresql_ext' module below.
- python3
- python3-psycopg2

# -----
# The next two are only necessary for PG < 14 which defaults to md5 otherwise.
# You might also need to adjust `/var/lib/pgsql/data/pg_hba.conf` to require
# scram-sha-256.
- name: initialize database
command:
cmd: postgresql-setup --initdb
creates: /var/lib/pgsql/data/postgresql.conf

- name: set auth to scram-sha-256
lineinfile:
path: /var/lib/pgsql/data/postgresql.conf
regexp: '^password_encryption'
line: "password_encryption = 'scram-sha-256'"
notify: restart postgresql
# ------ End section for PG < 14.

- name: start and enable database
service:
name: postgresql
state: started
enabled: yes

- name: create tobira postgres user
become_user: postgres
community.postgresql.postgresql_user:
name: tobira
password: "{{ db_password }}"

- name: create database
become_user: postgres
community.postgresql.postgresql_db:
name: tobira
owner: tobira

- name: add pgcrypto extension
become_user: postgres
community.postgresql.postgresql_ext:
name: pgcrypto
db: tobira

Tobira

roles/tobira/tasks/setup_tobira.yml
- name: create tobira user
user:
name: tobira

- name: create application and logging directories
file:
path: "{{ item }}"
state: directory
owner: tobira
group: tobira
mode: '0755'
loop:
- /opt/tobira
- /var/log/tobira

- name: Deploy Tobira executable
get_url:
url: '{{ tobira_binary_url }}'
dest: /opt/tobira/tobira
owner: tobira
group: tobira
mode: '0755'
checksum: '{{ tobira_release_checksum }}'
notify: restart tobira

- name: Deploy assets
copy:
src: "{{ item }}"
dest: /opt/tobira/
owner: tobira
group: tobira
mode: '0644'
loop:
- logo-large.svg
- logo-small.svg
- logo-large-dark.svg
- logo-small-dark.svg
- favicon.svg
notify: restart tobira

- name: Deploy configuration
template:
src: config.toml
dest: /opt/tobira/
owner: tobira
group: tobira
mode: '0644'
notify: restart tobira

- name: install tobira service files
template:
src: '{{ item }}.service'
dest: /etc/systemd/system/{{ item }}.service
mode: '0644'
owner: root
group: root
loop:
- tobira
- tobira-worker
notify: restart tobira

- name: start and enable tobira
systemd:
daemon_reload: true
name: '{{ item }}'
state: started
enabled: true
loop:
- tobira
- tobira-worker

Other files

The scripts assume the following files to exist:

  • roles/tobira/
    • files/
      • logo-large.svg
      • logo-small.svg
      • favicon.svg
    • templates/

Service files

roles/tobira/templates/tobira.service
[Unit]
Description=Tobira
Documentation=https://github.com/elan-ev/tobira

After=local-fs.target
After=network.target
After=postgresql.service
After=meili.service

[Service]
WorkingDirectory=/opt/tobira/
ExecStart=/opt/tobira/tobira serve
Restart=always
User=tobira

[Install]
WantedBy=multi-user.target
roles/tobira/templates/tobira-worker.service
[Unit]
Description=Tobira Worker
Documentation=https://github.com/elan-ev/tobira

After=local-fs.target
After=network.target
After=postgresql.service
After=meili.service

[Service]
WorkingDirectory=/opt/tobira/
ExecStart=/opt/tobira/tobira worker
Restart=always
User=tobira

[Install]
WantedBy=multi-user.target
roles/tobira/templates/meili.service
[Unit]
Description=MeiliSearch
Documentation=https://docs.meilisearch.com/

After=local-fs.target
After=network.target

[Service]
WorkingDirectory=/opt/meili
# You decide, see https://docs.meilisearch.com/learn/what_is_meilisearch/telemetry.html
#Environment="MEILI_NO_ANALYTICS=true"
Environment="MEILI_MASTER_KEY={{ meili_key }}"
Environment="MEILI_HTTP_PAYLOAD_SIZE_LIMIT=20Gb"
ExecStart=/opt/meili/meilisearch
Restart=always

[Install]
WantedBy=multi-user.target