From e3b5b4d5ff06e3ccc048ab2cc339f274e61f751f Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Sat, 6 Nov 2021 19:33:33 -0500 Subject: [PATCH] r/bitwarden_rs: Migrate to podman Docker is effectively deprecated by Fedora/Red Hat. It is a pain in the ass to work with anyway. Podman integrates better with systemd, and is in general more aligned with how I prefer to deploy and manage applications. I am following the same pattern here that I have used for Home Assistant, ZWaveJS2MQTT, etc. The systemd service starts the container with `podman`, passing the necessary arguments for UID/GID mapping, etc. Note that, by default, Vaultwarden expects to be able to bind to port 80; since the container is unprivileged, we have to configure it (or rather, its embedded HTTP server [Rocket](https://rocket.rs)) to listen on a different port. We also configure it to listen only on the loopback, since it is being proxied by Apache to the outside network. To migrate the data from the Docker volume, we just have to copy the files and fix their ownership. The *bitwarden_rs* project was recently renamed to *Vaultwarden*, so I took this opportunity to update the name in most places within the *bitwarden_rs* role. --- roles/bitwarden_rs/files/migrate-volume.sh | 5 + roles/bitwarden_rs/handlers/main.yml | 7 ++ roles/bitwarden_rs/meta/main.yml | 3 +- roles/bitwarden_rs/tasks/main.yml | 96 ++++++++++++++----- roles/bitwarden_rs/tasks/migration.yml | 19 ++++ .../templates/vaultwarden.service.j2 | 25 +++++ .../templates/vaultwarden.sysconfig.j2 | 10 ++ 7 files changed, 139 insertions(+), 26 deletions(-) create mode 100644 roles/bitwarden_rs/files/migrate-volume.sh create mode 100644 roles/bitwarden_rs/handlers/main.yml create mode 100644 roles/bitwarden_rs/tasks/migration.yml create mode 100644 roles/bitwarden_rs/templates/vaultwarden.service.j2 create mode 100644 roles/bitwarden_rs/templates/vaultwarden.sysconfig.j2 diff --git a/roles/bitwarden_rs/files/migrate-volume.sh b/roles/bitwarden_rs/files/migrate-volume.sh new file mode 100644 index 0000000..8fb87e0 --- /dev/null +++ b/roles/bitwarden_rs/files/migrate-volume.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +cp -a /var/lib/docker/volumes/bw-data/_data \ + /var/lib/vaultwarden/data +chown -R vaultwarden: /var/lib/vaultwarden/data diff --git a/roles/bitwarden_rs/handlers/main.yml b/roles/bitwarden_rs/handlers/main.yml new file mode 100644 index 0000000..c58866f --- /dev/null +++ b/roles/bitwarden_rs/handlers/main.yml @@ -0,0 +1,7 @@ +- name: reload systemd + systemd: + daemon_reload: true +- name: restart vaultwarden + service: + name: vaultwarden + state: restarted diff --git a/roles/bitwarden_rs/meta/main.yml b/roles/bitwarden_rs/meta/main.yml index 9838d9f..8f2b4cb 100644 --- a/roles/bitwarden_rs/meta/main.yml +++ b/roles/bitwarden_rs/meta/main.yml @@ -1,2 +1,3 @@ dependencies: -- apache +- role: apache + tags: apache diff --git a/roles/bitwarden_rs/tasks/main.yml b/roles/bitwarden_rs/tasks/main.yml index 7d0ea9f..f873bf6 100644 --- a/roles/bitwarden_rs/tasks/main.yml +++ b/roles/bitwarden_rs/tasks/main.yml @@ -5,44 +5,89 @@ tags: - install -- name: ensure python docker client is installed +- name: ensure podman is installed package: - name: python3-docker + name: podman state: present tags: - install -- name: ensure docker service starts at boot +- name: ensure vaultwarden user exists + user: + name: vaultwarden + system: true + home: /var/lib/vaultwarden + createhome: false + register: vaultwarden_user + tags: + - user +- name: cache vaultwarden user fact + set_fact: + vaultwarden_user: '{{ vaultwarden_user }}' + cacheable: true + +- name: ensure vaultwarden_rs home directory exists + file: + path: '{{ vaultwarden_user.home }}' + owner: '{{ vaultwarden_user.name }}' + group: '{{ vaultwarden_user.group }}' + mode: u=rwx,go= + state: directory + tags: + - datadir + +- name: ensure vaultwarden container image is available + podman_image: + name: docker.io/vaultwarden/server + tag: latest + state: present + force: '{{ vaultwarden_update|d|bool }}' + notify: + - restart vaultwarden + tags: + - container-image + - container + +- name: ensure vaultwarden environment is configured + template: + src: vaultwarden.sysconfig.j2 + dest: /etc/sysconfig/vaultwarden + mode: u=rw,go= + notify: + - restart vaultwarden + tags: + - config + +- name: ensure vaultwarden systemd unit is installed + template: + src: vaultwarden.service.j2 + dest: /etc/systemd/system/vaultwarden.service + mode: u=rw,go=r + notify: + - reload systemd + - restart vaultwarden + tags: + - service + - systemd +- name: ensure vaultwarden starts at boot service: - name: docker + name: vaultwarden enabled: true tags: - service - - docker -- name: ensure docker service is running + +- import_tasks: migration.yml # noqa: unnamed-task + tags: + - migration + +- meta: flush_handlers # noqa: unnamed-task + +- name: ensure vaultwarden is running service: - name: docker + name: vaultwarden state: started tags: - service - - docker - -- name: ensure bitwarden_rs docker container is running - docker_container: - name: bitwarden - image: bitwardenrs/server:latest - detach: yes - volumes: - - bw-data:/data - published_ports: - - 127.0.0.1:8080:80 - - 127.0.0.1:3012:3012 - env: - ADMIN_TOKEN: '{{ bitwarden_admin_token|d(omit) }}' - DOMAIN: '{{ bitwarden_domain|d(omit) }}' - WEBSOCKET_ENABLED: 'true' - tags: - - docker - name: ensure apache is allowed to proxy seboolean: @@ -53,5 +98,6 @@ template: src: bitwarden.httpd.conf.j2 dest: /etc/httpd/conf.d/bitwarden.conf + mode: u=rw,go=r notify: - reload httpd diff --git a/roles/bitwarden_rs/tasks/migration.yml b/roles/bitwarden_rs/tasks/migration.yml new file mode 100644 index 0000000..cafa23b --- /dev/null +++ b/roles/bitwarden_rs/tasks/migration.yml @@ -0,0 +1,19 @@ +- name: ensure bitwarden_rs docker container is stopped + docker_container: + name: bitwarden + state: absent + ignore_errors: true +- name: ensure bitwarden_rs data directory is moved + script: migrate-volume.sh + args: + creates: /var/lib/vaultwarden/data +- name: ensure docker service is disabled + service: + name: docker + state: stopped + enabled: false + ignore_errors: true +- name: ensure docker is not installed + package: + name: docker + state: absent diff --git a/roles/bitwarden_rs/templates/vaultwarden.service.j2 b/roles/bitwarden_rs/templates/vaultwarden.service.j2 new file mode 100644 index 0000000..ad47ba5 --- /dev/null +++ b/roles/bitwarden_rs/templates/vaultwarden.service.j2 @@ -0,0 +1,25 @@ +[Unit] +Description=Vaultwarden API server + +[Service] +Type=notify +NotifyAccess=all +ExecStart=/usr/bin/podman run \ + --pull never \ + --sdnotify=conmon --cgroups=no-conmon \ + --rm \ + --network=host \ + --name vaultwarden \ + -v /var/lib/vaultwarden/data:/data:Z \ + --env-file /etc/sysconfig/vaultwarden \ + --uidmap 0:{{ vaultwarden_user.uid }}:1 \ + --gidmap 0:{{ vaultwarden_user.group }}:1 \ + --uidmap 1:100000:65536 \ + --gidmap 1:100000:65536 \ + docker.io/vaultwarden/server:latest +SuccessExitStatus=143 +ProtectSystem=full +UMask=0077 + +[Install] +WantedBy=multi-user.target diff --git a/roles/bitwarden_rs/templates/vaultwarden.sysconfig.j2 b/roles/bitwarden_rs/templates/vaultwarden.sysconfig.j2 new file mode 100644 index 0000000..7f16c6b --- /dev/null +++ b/roles/bitwarden_rs/templates/vaultwarden.sysconfig.j2 @@ -0,0 +1,10 @@ +{% if bitwarden_admin_token|d %} +ADMIN_TOKEN={{ bitwarden_admin_token }} +{% endif %} +{% if bitwarden_domain|d %} +DOMAIN={{ bitwarden_domain }} +{% endif %} +WEBSOCKET_ENABLED=true +WEBSOCKET_ADDRESS=127.0.0.1 +ROCKET_ADDRESS=127.0.0.1 +ROCKET_PORT=8080