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 checkwhich 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-Policyby 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/v0.28.1/meilisearch-linux-amd64"
meili_release_checksum: "sha256:d394626b43c71acba0516336016285a963046b5ccf6f2c5ea6d5ef17085a3b40"
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!
  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
    - favicon.svg
    - jwt-key.pem
  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.svglogo-small.svgfavicon.svgjwt-key.pem
templates/config.toml(see Configuration docs)
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