diff --git a/.env.sample b/.env.sample index d73ad9c..8b50eae 100644 --- a/.env.sample +++ b/.env.sample @@ -15,6 +15,10 @@ LOG_LEVEL=warn SECRET_ADMIN_TOKEN_VERSION=v1 # length=48 +## DB settings +#COMPOSE_FILE="$COMPOSE_FILE:compose.mariadb.yml" +#SECRET_DB_PASSWORD_VERSION=v1 +#SECRET_DB_ROOT_PASSWORD_VERSION=v1 ## SMTP settings #COMPOSE_FILE="$COMPOSE_FILE:compose.smtp.yml" diff --git a/README.md b/README.md index 57bf2bc..46282c4 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ * **Status**: 2, beta * **Image**: [`vaultwarden/server`](https://hub.docker.com/vaultwarden/server), 4, upstream * **Healthcheck**: 3 -* **Backups**: No -* **Email**: No +* **Backups**: Yes +* **Email**: Yes * **Tests**: No * **SSO**: No @@ -21,8 +21,8 @@ 2. Deploy [`coop-cloud/traefik`] 3. `abra app new vaultwarden` 4. `abra app config YOURAPPDOMAIN` -5. `abra app secret generate vault.foo.bar admin_token v1` -6. `abra app secret insert vault.esn-cloud.de smtp_password v1 "super-secret-passowrd"` SMTP config and password needed for user email invites +5. `abra app cmd -l YOURAPPDOMAIN insert_vaultwarden_admin_token` will insert a hashed `admin_token` as password as recommended by vaultwarden. Will echo the admin_token to your cli. +6. `abra app secret insert YOURAPPDOMAIN smtp_password v1 "super-secret-password"` SMTP config and password needed for user email invites 5. `abra app deploy YOURAPPDOMAIN` [`abra`]: https://git.coopcloud.tech/coop-cloud/abra @@ -30,6 +30,9 @@ ## Tips & Tricks +### Using MariaDB instead of SQLite +Just comment in the `DB settings` section in your .env + ### Wiring up `fail2ban` You need the following logging config: diff --git a/abra.sh b/abra.sh index 1aa89e2..760c081 100644 --- a/abra.sh +++ b/abra.sh @@ -1,6 +1,25 @@ export APP_ENTRYPOINT_VERSION=v2 APP_DIR="app:/data" +insert_vaultwarden_admin_token() { + if ! command -v argon2 &> /dev/null; then + echo "argon2 could not be found, please install it to proceed." + exit 1 + fi + PASS=$(openssl rand 64 | openssl enc -A -base64) + # -e: output encoded hash, -id: use Argon2id, -k: memory cost, -t: time cost, -p: parallelism + HASH=$(echo -n "$PASS" | argon2 "$(openssl rand -base64 32)" -e -id -k 65540 -t 3 -p 4) + + if abra app secret insert -C "$APP_NAME" admin_token v1 "$HASH"; then + echo "Vaultwarden Admin Token is:" + echo "$PASS" + echo "TAKE NOTE OF IT NOW, WILL NEVER BE SHOWN AGAIN!" + else + echo "Failed to insert admin token." + exit 1 + fi +} + _backup_app() { # Copied _abra_backup_dir to make UX better on restore and backup { diff --git a/compose.mariadb.yml b/compose.mariadb.yml new file mode 100644 index 0000000..a533674 --- /dev/null +++ b/compose.mariadb.yml @@ -0,0 +1,51 @@ +--- +version: "3.8" + +services: + app: + environment: + # DATABASE_URL with secret db_password is being set by entrypoint.sh.tmpl + - MYSQL_HOST=db + - MYSQL_DATABASE=vaultwarden + - MYSQL_USER=vaultwarden + - MYSQL_PASSWORD_FILE=/run/secrets/db_password + secrets: + - db_password + + db: + image: "mariadb:10.6" # or "mysql" + environment: + - MYSQL_DATABASE=vaultwarden + - MYSQL_USER=vaultwarden + - MYSQL_PASSWORD_FILE=/run/secrets/db_password + - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_root_password + - MAX_DB_CONNECTIONS=${MAX_DB_CONNECTIONS:-100}# + secrets: + - db_root_password + - db_password + volumes: + - "mariadb:/var/lib/mysql" + networks: + - internal + deploy: + labels: + backupbot.backup.pre-hook: 'mysqldump --single-transaction -u root -p"$$(cat /run/secrets/db_root_password)" nextcloud > /var/lib/mysql/backup.sql' + backupbot.backup.volumes.mariadb.path: "backup.sql" + backupbot.restore.post-hook: 'mysql -u root -p"$$(cat /run/secrets/db_root_password)" nextcloud < /var/lib/mysql/backup.sql' + healthcheck: + test: ["CMD-SHELL", 'mysqladmin -p"$$(cat /run/secrets/db_root_password)" ping'] + interval: 5s + timeout: 10s + retries: 0 + start_period: 1m + +secrets: + db_root_password: + external: true + name: ${STACK_NAME}_db_root_password_${SECRET_DB_ROOT_PASSWORD_VERSION} + db_password: + external: true + name: ${STACK_NAME}_db_password_${SECRET_DB_PASSWORD_VERSION} + +volumes: + mariadb: \ No newline at end of file diff --git a/compose.yml b/compose.yml index 247501e..69136f6 100644 --- a/compose.yml +++ b/compose.yml @@ -6,6 +6,7 @@ services: image: vaultwarden/server:1.32.3 networks: - proxy + - internal environment: - "DOMAIN=https://$DOMAIN" - "WEBSOCKET_ENABLED=$WEBSOCKET_ENABLED" @@ -20,6 +21,7 @@ services: target: /docker-entrypoint.sh mode: 0555 entrypoint: /docker-entrypoint.sh + # entrypoint: ['tail', '-f', '/dev/null'] command: /start.sh secrets: - admin_token @@ -49,6 +51,7 @@ volumes: networks: proxy: external: true + internal: configs: app_entrypoint: diff --git a/entrypoint.sh.tmpl b/entrypoint.sh.tmpl index 6316e0c..2be7858 100644 --- a/entrypoint.sh.tmpl +++ b/entrypoint.sh.tmpl @@ -2,6 +2,23 @@ set -e +# set DATABASE_URL with db_password +set_db_url() { + if test -f "/var/run/secrets/db_password"; then + pwd=`cat /var/run/secrets/db_password` + if [ -z $pwd ]; then + echo >&2 "error: /var/run/secrets/db_password is empty" + exit 1 + fi + echo "entrypoint.sh setting DATABASE_URL" + export "DATABASE_URL"="mysql://vaultwarden:${pwd}@db/vaultwarden" + unset "pwd" + else + echo >&2 "error: /var/run/secrets/db_password does not exist" + exit 1 + fi +} + file_env() { local var="$1" local fileVar="${var}_FILE" @@ -24,6 +41,10 @@ file_env() { unset "$fileVar" } +if [ -n "${MYSQL_HOST}" ]; then + set_db_url +fi + file_env "ADMIN_TOKEN" file_env "SMTP_PASSWORD"