blob: a6bc0eaa46cc891f4d387d33e27ec20bcced2265 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
---
title: 'Migrating vaultwarden from nixos to Debian'
description: 'How I am deploying vaultwarden with ansible'
date: '2024-12-31'
tags:
- ansible
- vaultwarden
---
## Introduction
I am migrating several services from a NixOS server (dalinar.adyxax.org) to a Debian server (lore.adyxax.org). Here is how I performed the operation for my self hosted [vaultwarden](https://github.com/dani-garcia/vaultwarden).
## Ansible role
### Meta
The `meta/main.yaml` contains the role dependencies:
``` yaml
---
dependencies:
- role: 'borg'
- role: 'nginx'
- role: 'podman'
- role: 'postgresql'
```
### Tasks
The `tasks/main.yaml` just creates a data directory and fetches the admin secret token from a terraform state. All the heavy lifting is then done by calling other roles:
``` yaml
---
- name: 'Make vaultwarden data directory'
file:
path: '/srv/vaultwarden'
owner: 'root'
group: 'root'
mode: '0750'
state: 'directory'
- include_role:
name: 'postgresql'
tasks_from: 'database'
vars:
postgresql:
name: 'vaultwarden'
- name: 'Load the tofu state to read the database encryption key'
include_vars:
file: '../tofu/04-apps/terraform.tfstate' # TODO use my http backend instead
name: 'tofu_state_vaultwarden'
- set_fact:
vaultwarden_argon2_token: "{{ tofu_state_vaultwarden | json_query(\"resources[?type=='random_password'&&name=='vaultwarden_argon2_token'].instances[0].attributes.result\") }}"
- include_role:
name: 'podman'
tasks_from: 'container'
vars:
container:
name: 'vaultwarden'
env_vars:
- name: 'ADMIN_TOKEN'
value: "'{{ vaultwarden_argon2_token[0] }}'"
- name: 'DATABASE_MAX_CONNS'
value: '2'
- name: 'DATABASE_URL'
value: 'postgres://vaultwarden:{{ ansible_local.postgresql_vaultwarden.password }}@10.88.0.1/vaultwarden?sslmode=disable'
image: '{{ versions.vaultwarden.image }}:{{ versions.vaultwarden.tag }}'
publishs:
- container_port: '80'
host_port: '8083'
ip: '127.0.0.1'
volumes:
- dest: '/data'
src: '/srv/vaultwarden'
- include_role:
name: 'nginx'
tasks_from: 'vhost'
vars:
vhost:
name: 'vaultwarden'
path: 'roles/vaultwarden/files/nginx-vhost.conf'
- include_role:
name: 'borg'
tasks_from: 'client'
vars:
client:
jobs:
- name: 'data'
paths:
- '/srv/vaultwarden'
- name: 'postgres'
command_to_pipe: "su - postgres -c '/usr/bin/pg_dump -b -c -C -d vaultwarden'"
name: 'vaultwarden'
server: '{{ vaultwarden.borg }}'
```
### Files
There is only the nginx vhost file, fairly straightforward:
``` nginx
###############################################################################
# \_o< WARNING : This file is being managed by ansible! >o_/ #
# ~~~~ ~~~~ #
###############################################################################
server {
listen 80;
listen [::]:80;
server_name pass.adyxax.org;
location / {
return 308 https://$server_name$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name pass.adyxax.org;
location / {
proxy_pass http://127.0.0.1:8083;
}
ssl_certificate adyxax.org.fullchain;
ssl_certificate_key adyxax.org.key;
}
```
## Migration process
The first step is to deploy this new configuration to the server:
``` shell
make run limit=lore.adyxax.org tags=vaultwarden
```
After that I manually backup the vaultwarden data with:
``` shell
ssh root@dalinar.adyxax.org systemctl stop podman-vaultwarden
ssh root@dalinar.adyxax.org /run/current-system/sw/bin/pg_dump -b -c -C -h localhost -U vaultwarden -d vaultwarden > /tmp/vaultwarden.sql
ssh root@dalinar.adyxax.org tar czf /tmp/vaultwarden.tar.gz /srv/vaultwarden/
```
I retrieve then migrate these backups with:
``` shell
scp root@dalinar.adyxax.org:/tmp/vaultwarden.{sql,tar.gz} .
ssh root@dalinar.adyxax.org rm vaultwarden.{sql,tar.gz}
scp vaultwarden.{sql,tar.gz} root@lore.adyxax.org:
rm vaultwarden.{sql,tar.gz}
```
On the new server, restoring the backup is done with:
``` shell
ssh root@lore.adyxax.org systemctl stop podman-vaultwarden
ssh root@lore.adyxax.org "cat vaultwarden.sql | su - postgres -c 'psql'"
ssh root@lore.adyxax.org tar -xzf vaultwarden.tar.gz -C /srv/vaultwarden/
ssh root@lore.adyxax.org rm vaultwarden.{sql,tar.gz}
ssh root@lore.adyxax.org systemctl start podman-vaultwarden
```
I then test the new server by setting the record in my `/etc/hosts` file. Since it all works well, I rollback my change to `/etc/hosts` and update the DNS record using OpenTofu.
## Conclusion
I did all this in early October and performed several vaultwarden upgrades since then. It all works well!
|