Add server Docker compose stack with Vault-backed secrets

This commit is contained in:
Fabio Scotto di Santolo
2026-03-30 21:40:12 +02:00
parent 652a861a26
commit fc26ea0242
6 changed files with 136 additions and 11 deletions

View File

@@ -5,6 +5,7 @@ server_user_home: "/home/{{ server_username }}"
effective_username: "{{ server_username }}"
effective_user_group: "{{ server_user_group }}"
effective_user_home: "{{ server_user_home }}"
server_container_stack_dir: /opt/docker/server
profile_packages:
- avahi-daemon
@@ -33,8 +34,29 @@ server_templates:
- src: server/.gitconfig.j2
dest: .gitconfig
mode: "0644"
- src: server/docker-compose.yml.j2
dest: "{{ server_container_stack_dir }}/docker-compose.yml"
owner: root
group: root
mode: "0644"
- src: server/navidrome_db_password.txt.j2
dest: "{{ server_container_stack_dir }}/navidrome_db_password.txt"
owner: root
group: root
mode: "0600"
no_log: true
- src: server/postgres_root_password.txt.j2
dest: "{{ server_container_stack_dir }}/postgres_root_password.txt"
owner: root
group: root
mode: "0600"
no_log: true
server_directories:
- path: "{{ server_container_stack_dir }}"
owner: root
group: root
mode: "0755"
- path: /opt/navidrome/data
owner: "{{ server_username }}"
group: "{{ server_user_group }}"

View File

@@ -12,17 +12,15 @@
loop_control:
label: "{{ item.dest }}"
- name: Render server templates
tags: [dotfiles, dotfiles:server]
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ server_user_home }}/{{ item.dest }}"
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
mode: "{{ item.mode }}"
loop: "{{ server_templates | default([]) }}"
loop_control:
label: "{{ item.dest }}"
- name: Require server container secret variables
tags: [dotfiles, dotfiles:server, services]
ansible.builtin.assert:
that:
- (vault_navidrome_db_password | default('')) | length > 0
- (vault_postgres_root_password | default('')) | length > 0
fail_msg: >-
Server container secrets are missing. Define vault_navidrome_db_password and
vault_postgres_root_password in secrets/vault.yml or another vars source.
- name: Ensure server directories exist
tags: [dotfiles, services]
@@ -36,6 +34,19 @@
loop_control:
label: "{{ item.path }}"
- name: Render server templates
tags: [dotfiles, dotfiles:server]
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest if item.dest.startswith('/') else server_user_home ~ '/' ~ item.dest }}"
owner: "{{ item.owner | default(server_username) }}"
group: "{{ item.group | default(server_user_group) }}"
mode: "{{ item.mode }}"
loop: "{{ server_templates | default([]) }}"
loop_control:
label: "{{ item.dest }}"
no_log: "{{ item.no_log | default(false) }}"
- name: Disable SSH root login on server
tags: [services]
ansible.builtin.lineinfile:

View File

@@ -0,0 +1,87 @@
---
version: "3.8"
services:
navidrome:
image: deluan/navidrome:latest
container_name: navidrome
restart: unless-stopped
expose:
- "4533"
environment:
ND_DATABASE_URL: "postgres://navidrome:$(cat /run/secrets/navidrome_db_password)@navidromedb:5432/navidrome_db?sslmode=disable"
ND_SESSIONTIMEOUT: 24h
ND_ENABLETRANSCODING: "true"
volumes:
- "/opt/navidrome/data:/data"
- "/opt/music:/music:ro"
user: "1000:1000"
networks:
- web
depends_on:
- navidromedb
secrets:
- navidrome_db_password
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "81:81"
volumes:
- "/opt/npm/data:/data"
- "/opt/npm/letsencrypt:/etc/letsencrypt"
networks:
- web
- gitea
navidromedb:
image: postgres:13
container_name: navidromedb
restart: unless-stopped
mem_limit: 2048m
environment:
POSTGRES_DB: "navidrome_db"
POSTGRES_USER: "navidrome"
POSTGRES_PASSWORD_FILE: "/run/secrets/postgres_root_password"
volumes:
- "/opt/postgres/data:/var/lib/postgresql/data"
networks:
- web
secrets:
- postgres_root_password
gitea:
image: docker.gitea.com/gitea:1.25.2
container_name: gitea
environment:
- USER_UID=1100
- USER_GID=1100
restart: always
networks:
- gitea
volumes:
- /opt/gitea/data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /home/git/.ssh:/data/git/.ssh
ports:
- "3000:3000"
- "127.0.0.1:222:22"
secrets:
navidrome_db_password:
file: "{{ server_container_stack_dir }}/navidrome_db_password.txt"
postgres_root_password:
file: "{{ server_container_stack_dir }}/postgres_root_password.txt"
networks:
web:
external: false
gitea:
external: false

View File

@@ -0,0 +1 @@
{{ vault_navidrome_db_password }}

View File

@@ -0,0 +1 @@
{{ vault_postgres_root_password }}

View File

@@ -5,3 +5,6 @@ vault_git_signing_key: "REPLACE_ME"
vault_icloud_email: "REPLACE_ME"
vault_protonmail_email: "REPLACE_ME"
vault_icloud_mail_password: "REPLACE_ME"
vault_git_work_email: "REPLACE_ME"
vault_navidrome_db_password: "REPLACE_ME"
vault_postgres_root_password: "REPLACE_ME"