Files
aliasvault/dockerfiles/all-in-one/s6-scripts/init/script
2025-08-11 21:35:22 +02:00

192 lines
7.6 KiB
Bash

#!/bin/sh -e
# AliasVault Container Initialization Script
# This script runs once at container startup and handles all initialization tasks
# Get verbosity level (0=minimal, 1=normal, 2=verbose)
VERBOSITY="${ALIASVAULT_VERBOSITY:-0}"
# Helper function for logging based on verbosity
log() {
level=$1
shift
if [ "$VERBOSITY" -ge "$level" ]; then
echo "$@"
fi
}
# Always show header and critical messages (level 0)
echo ""
echo "=================================================="
echo " _ _ _ __ __ _ _ "
echo " / \\ | (_) __ _ ___ \\ \\ / /_ _ _ _| | |_"
echo " / _ \\ | | |/ _\` / __| \\ \\/\\/ / _\` | | | | | __|"
echo " / ___ \\| | | (_| \\__ \\ \\ / / (_| | |_| | | |_ "
echo "/_/ \\_\\_|_|\\__,_|___/ \\/ \\__,__|\\__,_|_|\\__|"
echo ""
echo "=================================================="
echo ""
echo "[init] Starting AliasVault..."
echo ""
# Create required directories
if [ ! -d /database/postgres ] || [ ! -d /logs/postgres ] || [ ! -d /certificates ] || [ ! -d /secrets ] || [ ! -d /var/run/postgresql ]; then
mkdir -p /database/postgres /logs/postgres /certificates /secrets /var/run/postgresql
log 0 "[init] Required directories created"
else
log 0 "[init] ✅ Required directories already exist"
fi
if [ ! -f /secrets/postgres_password ]; then
log 0 "[init] → Generating PostgreSQL password..."
openssl rand -base64 32 | tr -d "\n" > /secrets/postgres_password
chmod 600 /secrets/postgres_password
else
log 0 "[init] ✅ PostgreSQL password already exists "
fi
if [ ! -f /secrets/data_protection_cert_pass ]; then
log 0 "[init] → Generating Data Protection Certificate password..."
openssl rand -base64 32 | tr -d "\n" > /secrets/data_protection_cert_pass
chmod 600 /secrets/data_protection_cert_pass
else
log 0 "[init] ✅ Data Protection Certificate password already exists"
fi
if [ ! -f /secrets/jwt_key ]; then
log 0 "[init] → Generating JWT key..."
openssl rand -base64 32 | tr -d "\n" > /secrets/jwt_key
chmod 600 /secrets/jwt_key
else
log 0 "[init] ✅ JWT key already exists"
fi
# Admin password is not created by default
# Users must run reset-admin-password.sh to configure the admin password
log 0 "[init] ✅ Admin password configuration deferred to manual setup"
# Read PostgreSQL password for database initialization
POSTGRES_PASSWORD=$(cat /secrets/postgres_password)
export PGDATA="/database/postgres"
# Initialize PostgreSQL if needed
if [ ! -d "$PGDATA/base" ]; then
log 0 ""
log 0 "[init] PostgreSQL database not found, initializing..."
# Set proper permissions
chown -R postgres:postgres /database/postgres /logs/postgres /var/run/postgresql
chmod 700 /database/postgres
# Initialize database as postgres user
log 1 "[init] → Running initdb..."
if [ "$VERBOSITY" -ge 2 ]; then
su - postgres -c "/usr/lib/postgresql/16/bin/initdb -D $PGDATA --locale=C.UTF-8 --encoding=UTF8" 2>&1 | tee /logs/postgres/initdb.log
else
su - postgres -c "/usr/lib/postgresql/16/bin/initdb -D $PGDATA --locale=C.UTF-8 --encoding=UTF8" > /logs/postgres/initdb.log 2>&1
fi
# Configure PostgreSQL
log 0 "[init] → Configuring PostgreSQL..."
# Listen on all container interfaces (covers localhost & Docker networks)
echo "listen_addresses = '*'" >> "$PGDATA/postgresql.conf"
# Store SCRAM hashes instead of MD5
echo "password_encryption = scram-sha-256" >> "$PGDATA/postgresql.conf"
# Allow local Unix-socket connections (processes inside the same container)
echo "local all all trust" >> "$PGDATA/pg_hba.conf"
# Allow any client on the same subnet(s) as this container (bridge/overlay)
# Prefer SCRAM if enabled above; otherwise MD5
if grep -qi '^password_encryption *= *scram-sha-256' "$PGDATA/postgresql.conf"; then
AUTH_METHOD="scram-sha-256"
else
AUTH_METHOD="md5"
fi
echo "host all all samenet ${AUTH_METHOD}" >> "$PGDATA/pg_hba.conf"
# Start PostgreSQL temporarily to create database and user
log 0 "[init] → Starting PostgreSQL temporarily for setup..."
if [ "$VERBOSITY" -ge 2 ]; then
su - postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA -l /logs/postgres/postgres.log start"
else
su - postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA -l /logs/postgres/postgres.log start" >/dev/null 2>&1
fi
# Wait for PostgreSQL to be ready
log 0 "[init] → Waiting for PostgreSQL to be ready..."
i=1
while [ $i -le 30 ]; do
if su - postgres -c "/usr/lib/postgresql/16/bin/psql -c 'SELECT 1;'" >/dev/null 2>&1; then
break
fi
sleep 1
i=$((i + 1))
done
# Create database and user
log 0 "[init] → Creating AliasVault database and user..."
if [ "$VERBOSITY" -ge 2 ]; then
su - postgres -c "/usr/lib/postgresql/16/bin/psql -c \"CREATE USER aliasvault WITH PASSWORD '$POSTGRES_PASSWORD'\""
su - postgres -c "/usr/lib/postgresql/16/bin/psql -c \"CREATE DATABASE aliasvault OWNER aliasvault LOCALE 'C.UTF-8';\""
su - postgres -c "/usr/lib/postgresql/16/bin/psql -c \"GRANT ALL PRIVILEGES ON DATABASE aliasvault TO aliasvault;\""
else
su - postgres -c "/usr/lib/postgresql/16/bin/psql -c \"CREATE USER aliasvault WITH PASSWORD '$POSTGRES_PASSWORD'\"" >/dev/null 2>&1
su - postgres -c "/usr/lib/postgresql/16/bin/psql -c \"CREATE DATABASE aliasvault OWNER aliasvault LOCALE 'C.UTF-8';\"" >/dev/null 2>&1
su - postgres -c "/usr/lib/postgresql/16/bin/psql -c \"GRANT ALL PRIVILEGES ON DATABASE aliasvault TO aliasvault;\"" >/dev/null 2>&1
fi
# Stop PostgreSQL
log 0 "[init] → Stopping PostgreSQL..."
if [ "$VERBOSITY" -ge 2 ]; then
su - postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA stop"
else
su - postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA stop" >/dev/null 2>&1
fi
sleep 2
log 0 "[init] PostgreSQL initialization complete"
else
log 0 "[init] ✅ PostgreSQL database already initialized"
# Just ensure permissions are correct
chown -R postgres:postgres /database/postgres /logs/postgres /var/run/postgresql
chmod 700 /database/postgres
fi
# Future: Database migrations could go here
# log 1 "[init] Checking for database migrations..."
# if [ -f /app/migrations/pending ]; then
# log 1 "[init] → Running database migrations..."
# # Run migration logic here
# fi
# Generate SSL certificates if needed
if [ ! -f /certificates/ssl/cert.pem ] || [ ! -f /certificates/ssl/key.pem ]; then
log 0 ""
log 0 "[init] Generating SSL certificates..."
mkdir -p /certificates/ssl
if [ "$VERBOSITY" -ge 2 ]; then
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /certificates/ssl/key.pem \
-out /certificates/ssl/cert.pem \
-subj "/C=US/ST=State/L=City/O=AliasVault/CN=${HOSTNAME:-localhost}"
else
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /certificates/ssl/key.pem \
-out /certificates/ssl/cert.pem \
-subj "/C=US/ST=State/L=City/O=AliasVault/CN=${HOSTNAME:-localhost}" \
>/dev/null 2>&1
fi
chmod 600 /certificates/ssl/key.pem
chmod 644 /certificates/ssl/cert.pem
log 0 "[init] Self-signed SSL certificates generated"
else
log 0 "[init] ✅ Self-signed SSL certificates already exist"
fi
echo ""
echo "[init] Waiting for all services to be ready... this can take a short while..."
echo ""
# Oneshot service exits successfully, dependencies can now start