mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-05-24 08:17:57 -04:00
Refactor s6 config so each service has its separate run and type files (#1098)
This commit is contained in:
committed by
Leendert de Borst
parent
af0b5ff5f8
commit
2d40e424e8
@@ -112,296 +112,20 @@ RUN sed -i 's/client:3000/localhost:3000/g' /etc/nginx/nginx.conf && \
|
||||
sed -i 's/admin:3002/localhost:3002/g' /etc/nginx/nginx.conf
|
||||
|
||||
# ============================================
|
||||
# S6 Service Definitions
|
||||
# S6 Service Configuration
|
||||
# ============================================
|
||||
|
||||
# Container initialization with secrets management
|
||||
RUN mkdir -p /etc/s6-overlay/s6-rc.d/init-container && \
|
||||
echo '#!/bin/sh' > /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'echo "[init-container] Initializing AliasVault single container..." >&2' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'echo "[init-container] Creating data directories..." >&2' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'mkdir -p /database/postgres /logs/postgres /certificates /secrets' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo '' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo '# Initialize secrets files if they dont exist' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'echo "[init-container] Initializing secrets..." >&2' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo '' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo '# Generate random 32 character password for PostgreSQL if not exists' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'if [ ! -f /secrets/postgres_password ]; then' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo ' echo "[init-container] Generating PostgreSQL password..." >&2' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo ' openssl rand -base64 32 | tr -d "\\n" > /secrets/postgres_password' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo ' chmod 600 /secrets/postgres_password' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'fi' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo '' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo '# Generate random 32 character password for Data Protection Certificate if not exists' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'if [ ! -f /secrets/data_protection_cert_pass ]; then' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo ' echo "[init-container] Generating Data Protection Certificate password..." >&2' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo ' openssl rand -base64 32 | tr -d "\\n" > /secrets/data_protection_cert_pass' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo ' chmod 600 /secrets/data_protection_cert_pass' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'fi' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo '' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo '# Generate JWT key if not exists' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'if [ ! -f /secrets/jwt_key ]; then' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo ' echo "[init-container] Generating JWT key..." >&2' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo ' openssl rand -base64 32 | tr -d "\\n" > /secrets/jwt_key' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo ' chmod 600 /secrets/jwt_key' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'fi' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo '' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'echo "[init-container] Setting database permissions..." >&2' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'chown -R postgres:postgres /database/postgres' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'chmod 700 /database/postgres' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo '' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo 'echo "[init-container] Container initialization complete" >&2' >> /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
chmod +x /etc/s6-overlay/s6-rc.d/init-container/up && \
|
||||
echo "oneshot" > /etc/s6-overlay/s6-rc.d/init-container/type
|
||||
# Copy s6 service definitions
|
||||
COPY dockerfiles/s6-scripts /etc/s6-overlay/s6-rc.d/
|
||||
|
||||
# PostgreSQL service
|
||||
RUN mkdir -p /etc/s6-overlay/s6-rc.d/postgres && \
|
||||
{ echo '#!/bin/sh'; \
|
||||
echo ''; \
|
||||
echo '# Set PostgreSQL paths'; \
|
||||
echo 'export PATH="/usr/lib/postgresql/16/bin:$PATH"'; \
|
||||
echo 'export PGDATA="/database/postgres"'; \
|
||||
echo ''; \
|
||||
echo '# Read PostgreSQL password from file'; \
|
||||
echo 'if [ -f /secrets/postgres_password ]; then'; \
|
||||
echo ' POSTGRES_PASSWORD=$(cat /secrets/postgres_password)'; \
|
||||
echo 'else'; \
|
||||
echo ' # Fallback to environment variable or default'; \
|
||||
echo ' POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-defaultpassword}"'; \
|
||||
echo 'fi'; \
|
||||
echo ''; \
|
||||
echo '# Initialize PostgreSQL if needed'; \
|
||||
echo 'if [ ! -d "$PGDATA/base" ]; then'; \
|
||||
echo ' echo "Initializing PostgreSQL database..."'; \
|
||||
echo ' mkdir -p "$PGDATA" /logs/postgres'; \
|
||||
echo ' chown -R postgres:postgres "$PGDATA" /logs/postgres'; \
|
||||
echo ' chmod 700 "$PGDATA"'; \
|
||||
echo ' su - postgres -c "/usr/lib/postgresql/16/bin/initdb -D $PGDATA --locale=en_US.UTF-8 --encoding=UTF8"'; \
|
||||
echo ' '; \
|
||||
echo ' # Configure PostgreSQL'; \
|
||||
echo ' echo "host all all 127.0.0.1/32 md5" >> "$PGDATA/pg_hba.conf"'; \
|
||||
echo ' echo "listen_addresses = '\''127.0.0.1'\''" >> "$PGDATA/postgresql.conf"'; \
|
||||
echo ' '; \
|
||||
echo ' # Start PostgreSQL temporarily to create database and user'; \
|
||||
echo ' su - postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA -l /logs/postgres/postgres.log start"'; \
|
||||
echo ' sleep 5'; \
|
||||
echo ' '; \
|
||||
echo ' # Create database and user'; \
|
||||
echo ' su - postgres -c "/usr/lib/postgresql/16/bin/psql -c \\"CREATE USER aliasvault WITH PASSWORD '\''$POSTGRES_PASSWORD'\''\\""'; \
|
||||
echo ' su - postgres -c "/usr/lib/postgresql/16/bin/psql -c \\"CREATE DATABASE aliasvault OWNER aliasvault;\\""'; \
|
||||
echo ' su - postgres -c "/usr/lib/postgresql/16/bin/psql -c \\"GRANT ALL PRIVILEGES ON DATABASE aliasvault TO aliasvault;\\""'; \
|
||||
echo ' '; \
|
||||
echo ' # Stop PostgreSQL'; \
|
||||
echo ' su - postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA stop"'; \
|
||||
echo ' sleep 2'; \
|
||||
echo 'fi'; \
|
||||
echo ''; \
|
||||
echo '# Run PostgreSQL'; \
|
||||
echo 'exec s6-setuidgid postgres /usr/lib/postgresql/16/bin/postgres -D "$PGDATA"'; \
|
||||
} > /etc/s6-overlay/s6-rc.d/postgres/run && \
|
||||
chmod +x /etc/s6-overlay/s6-rc.d/postgres/run && \
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/postgres/type && \
|
||||
mkdir -p /etc/s6-overlay/s6-rc.d/postgres/dependencies.d && \
|
||||
touch /etc/s6-overlay/s6-rc.d/postgres/dependencies.d/init-container
|
||||
# Make all scripts executable (run for longrun services, up for oneshot services, and script files)
|
||||
RUN find /etc/s6-overlay/s6-rc.d -type f \( -name "run" -o -name "up" -o -name "script" \) -exec chmod +x {} \;
|
||||
|
||||
|
||||
# API service
|
||||
RUN mkdir -p /etc/s6-overlay/s6-rc.d/api && \
|
||||
{ echo '#!/command/with-contenv bash'; \
|
||||
echo 'cd /app/api'; \
|
||||
echo '# Read PostgreSQL password from file'; \
|
||||
echo 'if [ -f /secrets/postgres_password ]; then'; \
|
||||
echo ' POSTGRES_PASSWORD=$(cat /secrets/postgres_password)'; \
|
||||
echo 'else'; \
|
||||
echo ' POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-defaultpassword}"'; \
|
||||
echo 'fi'; \
|
||||
echo '# Wait for PostgreSQL to be ready'; \
|
||||
echo 'i=1; while [ $i -le 30 ]; do'; \
|
||||
echo ' if PGPASSWORD="$POSTGRES_PASSWORD" /usr/lib/postgresql/16/bin/psql -h localhost -U aliasvault -d aliasvault -c "SELECT 1;" >/dev/null 2>&1; then'; \
|
||||
echo ' echo "[api] PostgreSQL ready, starting API..." >&2; break'; \
|
||||
echo ' fi'; \
|
||||
echo ' echo "[api] Waiting for PostgreSQL ($i/30)..." >&2; sleep 2; i=$((i+1))'; \
|
||||
echo 'done'; \
|
||||
echo 'export ConnectionStrings__AliasServerDbContext="Host=localhost;Database=aliasvault;Username=aliasvault;Password=$POSTGRES_PASSWORD"'; \
|
||||
echo 'export ASPNETCORE_URLS="http://0.0.0.0:3001"'; \
|
||||
echo 'export ASPNETCORE_PATHBASE="/api"'; \
|
||||
echo 'export PRIVATE_EMAIL_DOMAINS="${PRIVATE_EMAIL_DOMAINS:-}"'; \
|
||||
echo 'export PUBLIC_REGISTRATION_ENABLED="${PUBLIC_REGISTRATION_ENABLED:-true}"'; \
|
||||
echo 'export IP_LOGGING_ENABLED="${IP_LOGGING_ENABLED:-true}"'; \
|
||||
echo 'exec dotnet AliasVault.Api.dll'; \
|
||||
} > /etc/s6-overlay/s6-rc.d/api/run && \
|
||||
chmod +x /etc/s6-overlay/s6-rc.d/api/run && \
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/api/type
|
||||
|
||||
# Client service (nginx for WASM app) - using echo approach
|
||||
RUN mkdir -p /etc/s6-overlay/s6-rc.d/client && \
|
||||
{ echo '#!/command/with-contenv bash'; \
|
||||
echo '# Client service entrypoint'; \
|
||||
echo 'DEFAULT_PRIVATE_EMAIL_DOMAINS=""'; \
|
||||
echo 'DEFAULT_SUPPORT_EMAIL=""'; \
|
||||
echo 'PRIVATE_EMAIL_DOMAINS=${PRIVATE_EMAIL_DOMAINS:-$DEFAULT_PRIVATE_EMAIL_DOMAINS}'; \
|
||||
echo 'SUPPORT_EMAIL=${SUPPORT_EMAIL:-$DEFAULT_SUPPORT_EMAIL}'; \
|
||||
echo 'PUBLIC_REGISTRATION_ENABLED=${PUBLIC_REGISTRATION_ENABLED:-true}'; \
|
||||
echo ''; \
|
||||
echo 'mkdir -p /etc/nginx/ssl'; \
|
||||
echo ''; \
|
||||
echo 'if [ ! -f /etc/nginx/ssl/nginx.crt ] || [ ! -f /etc/nginx/ssl/nginx.key ]; then'; \
|
||||
echo ' echo "Generating SSL certificate (10 years validity)..."'; \
|
||||
echo ' openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"'; \
|
||||
echo ' chmod 644 /etc/nginx/ssl/nginx.crt'; \
|
||||
echo ' chmod 600 /etc/nginx/ssl/nginx.key'; \
|
||||
echo 'fi'; \
|
||||
echo ''; \
|
||||
echo '# Create simple JSON with environment variables'; \
|
||||
echo 'cat > /app/client/wwwroot/appsettings.json << EOF'; \
|
||||
echo '{'; \
|
||||
echo ' "PrivateEmailDomains": ["$PRIVATE_EMAIL_DOMAINS"],'; \
|
||||
echo ' "SupportEmail": "$SUPPORT_EMAIL",'; \
|
||||
echo ' "PublicRegistrationEnabled": "$PUBLIC_REGISTRATION_ENABLED"'; \
|
||||
echo '}'; \
|
||||
echo 'EOF'; \
|
||||
echo ''; \
|
||||
echo 'sed -i "s|/usr/share/nginx/html|/app/client/wwwroot|g" /app/client/nginx.conf'; \
|
||||
echo ''; \
|
||||
echo 'exec nginx -c /app/client/nginx.conf -g "daemon off;"'; \
|
||||
} > /etc/s6-overlay/s6-rc.d/client/run && \
|
||||
chmod +x /etc/s6-overlay/s6-rc.d/client/run && \
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/client/type
|
||||
|
||||
# Admin service
|
||||
RUN mkdir -p /etc/s6-overlay/s6-rc.d/admin && \
|
||||
{ echo '#!/command/with-contenv bash'; \
|
||||
echo 'cd /app/admin'; \
|
||||
echo '# Read PostgreSQL password from file'; \
|
||||
echo 'if [ -f /secrets/postgres_password ]; then'; \
|
||||
echo ' POSTGRES_PASSWORD=$(cat /secrets/postgres_password)'; \
|
||||
echo 'else'; \
|
||||
echo ' POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-defaultpassword}"'; \
|
||||
echo 'fi'; \
|
||||
echo '# Wait for PostgreSQL to be ready'; \
|
||||
echo 'i=1; while [ $i -le 30 ]; do'; \
|
||||
echo ' if PGPASSWORD="$POSTGRES_PASSWORD" /usr/lib/postgresql/16/bin/psql -h localhost -U aliasvault -d aliasvault -c "SELECT 1;" >/dev/null 2>&1; then'; \
|
||||
echo ' echo "[admin] PostgreSQL ready, starting Admin..." >&2; break'; \
|
||||
echo ' fi'; \
|
||||
echo ' echo "[admin] Waiting for PostgreSQL ($i/30)..." >&2; sleep 2; i=$((i+1))'; \
|
||||
echo 'done'; \
|
||||
echo 'export ConnectionStrings__AliasServerDbContext="Host=localhost;Database=aliasvault;Username=aliasvault;Password=$POSTGRES_PASSWORD"'; \
|
||||
echo 'export ASPNETCORE_URLS="http://0.0.0.0:3002"'; \
|
||||
echo 'export ASPNETCORE_PATHBASE="/admin"'; \
|
||||
echo 'export IP_LOGGING_ENABLED="${IP_LOGGING_ENABLED:-true}"'; \
|
||||
echo 'exec dotnet AliasVault.Admin.dll'; \
|
||||
} > /etc/s6-overlay/s6-rc.d/admin/run && \
|
||||
chmod +x /etc/s6-overlay/s6-rc.d/admin/run && \
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/admin/type
|
||||
|
||||
# SMTP service
|
||||
RUN mkdir -p /etc/s6-overlay/s6-rc.d/smtp && \
|
||||
{ echo '#!/command/with-contenv bash'; \
|
||||
echo 'cd /app/smtp'; \
|
||||
echo '# Read PostgreSQL password from file'; \
|
||||
echo 'if [ -f /secrets/postgres_password ]; then'; \
|
||||
echo ' POSTGRES_PASSWORD=$(cat /secrets/postgres_password)'; \
|
||||
echo 'else'; \
|
||||
echo ' POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-defaultpassword}"'; \
|
||||
echo 'fi'; \
|
||||
echo '# Wait for PostgreSQL to be ready'; \
|
||||
echo 'i=1; while [ $i -le 30 ]; do'; \
|
||||
echo ' if PGPASSWORD="$POSTGRES_PASSWORD" /usr/lib/postgresql/16/bin/psql -h localhost -U aliasvault -d aliasvault -c "SELECT 1;" >/dev/null 2>&1; then'; \
|
||||
echo ' echo "[smtp] PostgreSQL ready, starting SMTP..." >&2; break'; \
|
||||
echo ' fi'; \
|
||||
echo ' echo "[smtp] Waiting for PostgreSQL ($i/30)..." >&2; sleep 2; i=$((i+1))'; \
|
||||
echo 'done'; \
|
||||
echo 'export ConnectionStrings__AliasServerDbContext="Host=localhost;Database=aliasvault;Username=aliasvault;Password=$POSTGRES_PASSWORD"'; \
|
||||
echo 'export PRIVATE_EMAIL_DOMAINS="${PRIVATE_EMAIL_DOMAINS:-}"'; \
|
||||
echo 'export SMTP_TLS_ENABLED="${SMTP_TLS_ENABLED:-false}"'; \
|
||||
echo 'exec dotnet AliasVault.SmtpService.dll'; \
|
||||
} > /etc/s6-overlay/s6-rc.d/smtp/run && \
|
||||
chmod +x /etc/s6-overlay/s6-rc.d/smtp/run && \
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/smtp/type
|
||||
|
||||
# Task Runner service
|
||||
RUN mkdir -p /etc/s6-overlay/s6-rc.d/taskrunner && \
|
||||
{ echo '#!/command/with-contenv bash'; \
|
||||
echo 'cd /app/taskrunner'; \
|
||||
echo '# Read PostgreSQL password from file'; \
|
||||
echo 'if [ -f /secrets/postgres_password ]; then'; \
|
||||
echo ' POSTGRES_PASSWORD=$(cat /secrets/postgres_password)'; \
|
||||
echo 'else'; \
|
||||
echo ' POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-defaultpassword}"'; \
|
||||
echo 'fi'; \
|
||||
echo '# Wait for PostgreSQL to be ready'; \
|
||||
echo 'i=1; while [ $i -le 30 ]; do'; \
|
||||
echo ' if PGPASSWORD="$POSTGRES_PASSWORD" /usr/lib/postgresql/16/bin/psql -h localhost -U aliasvault -d aliasvault -c "SELECT 1;" >/dev/null 2>&1; then'; \
|
||||
echo ' echo "[taskrunner] PostgreSQL ready, starting TaskRunner..." >&2; break'; \
|
||||
echo ' fi'; \
|
||||
echo ' echo "[taskrunner] Waiting for PostgreSQL ($i/30)..." >&2; sleep 2; i=$((i+1))'; \
|
||||
echo 'done'; \
|
||||
echo 'export ConnectionStrings__AliasServerDbContext="Host=localhost;Database=aliasvault;Username=aliasvault;Password=$POSTGRES_PASSWORD"'; \
|
||||
echo 'exec dotnet AliasVault.TaskRunner.dll'; \
|
||||
} > /etc/s6-overlay/s6-rc.d/taskrunner/run && \
|
||||
chmod +x /etc/s6-overlay/s6-rc.d/taskrunner/run && \
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/taskrunner/type
|
||||
|
||||
# Nginx service
|
||||
RUN mkdir -p /etc/s6-overlay/s6-rc.d/nginx && \
|
||||
{ echo '#!/command/with-contenv bash'; \
|
||||
echo '# Generate SSL certificate if not exists'; \
|
||||
echo 'if [ ! -f /certificates/ssl/cert.pem ]; then'; \
|
||||
echo ' echo "Generating self-signed SSL certificate (10 years validity)..."'; \
|
||||
echo ' mkdir -p /certificates/ssl'; \
|
||||
echo ' openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \\'; \
|
||||
echo ' -keyout /certificates/ssl/key.pem \\'; \
|
||||
echo ' -out /certificates/ssl/cert.pem \\'; \
|
||||
echo ' -subj "/C=US/ST=State/L=City/O=Organization/CN=${HOSTNAME:-localhost}"'; \
|
||||
echo 'fi'; \
|
||||
echo ''; \
|
||||
echo '# Copy certificates to nginx directory'; \
|
||||
echo 'cp /certificates/ssl/* /etc/nginx/ssl/ 2>/dev/null || true'; \
|
||||
echo ''; \
|
||||
echo '# Create SSL configuration file'; \
|
||||
echo 'cat > /etc/nginx/ssl.conf << "SSLEOF"'; \
|
||||
echo 'ssl_certificate /etc/nginx/ssl/cert.pem;'; \
|
||||
echo 'ssl_certificate_key /etc/nginx/ssl/key.pem;'; \
|
||||
echo 'ssl_session_timeout 1d;'; \
|
||||
echo 'ssl_session_cache shared:MozTLS:10m;'; \
|
||||
echo 'ssl_session_tickets off;'; \
|
||||
echo 'ssl_protocols TLSv1.2 TLSv1.3;'; \
|
||||
echo 'ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;'; \
|
||||
echo 'ssl_prefer_server_ciphers off;'; \
|
||||
echo 'SSLEOF'; \
|
||||
echo ''; \
|
||||
echo '# Use container nginx configuration'; \
|
||||
echo 'cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf'; \
|
||||
echo ''; \
|
||||
echo '# Wait for all services to be ready'; \
|
||||
echo 'echo "[nginx] Waiting for services to be ready..."'; \
|
||||
echo 'i=1'; \
|
||||
echo 'while [ $i -le 60 ]; do'; \
|
||||
echo ' if nc -z localhost 3000 && nc -z localhost 3001 && nc -z localhost 3002; then'; \
|
||||
echo ' echo "[nginx] All services ready, starting nginx..."'; \
|
||||
echo ' break'; \
|
||||
echo ' fi'; \
|
||||
echo ' if [ $i -eq 60 ]; then'; \
|
||||
echo ' echo "[nginx] Timeout waiting for services"'; \
|
||||
echo ' exit 1'; \
|
||||
echo ' fi'; \
|
||||
echo ' echo "[nginx] Waiting for services ($i/60)..."'; \
|
||||
echo ' sleep 1'; \
|
||||
echo ' i=$(($i + 1))'; \
|
||||
echo 'done'; \
|
||||
echo ''; \
|
||||
echo 'exec nginx -g "daemon off;"'; \
|
||||
} > /etc/s6-overlay/s6-rc.d/nginx/run && \
|
||||
chmod +x /etc/s6-overlay/s6-rc.d/nginx/run && \
|
||||
echo "longrun" > /etc/s6-overlay/s6-rc.d/nginx/type && \
|
||||
mkdir -p /etc/s6-overlay/s6-rc.d/nginx/dependencies.d && \
|
||||
touch /etc/s6-overlay/s6-rc.d/nginx/dependencies.d/api && \
|
||||
touch /etc/s6-overlay/s6-rc.d/nginx/dependencies.d/client && \
|
||||
touch /etc/s6-overlay/s6-rc.d/nginx/dependencies.d/admin
|
||||
# Service dependencies are now defined in the s6-scripts directory structure
|
||||
|
||||
# Enable all services in the default bundle
|
||||
RUN mkdir -p /etc/s6-overlay/s6-rc.d/user/contents.d && \
|
||||
touch /etc/s6-overlay/s6-rc.d/user/contents.d/init-container && \
|
||||
touch /etc/s6-overlay/s6-rc.d/user/contents.d/init && \
|
||||
touch /etc/s6-overlay/s6-rc.d/user/contents.d/postgres && \
|
||||
touch /etc/s6-overlay/s6-rc.d/user/contents.d/api && \
|
||||
touch /etc/s6-overlay/s6-rc.d/user/contents.d/client && \
|
||||
@@ -412,7 +136,7 @@ RUN mkdir -p /etc/s6-overlay/s6-rc.d/user/contents.d && \
|
||||
|
||||
# Set environment variables for s6-overlay
|
||||
ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \
|
||||
S6_VERBOSITY=1 \
|
||||
S6_VERBOSITY=0 \
|
||||
S6_BEHAVIOUR_IF_STAGE2_FAILS=2 \
|
||||
S6_KILL_GRACETIME=30000
|
||||
|
||||
|
||||
28
dockerfiles/s6-scripts/admin/run
Normal file
28
dockerfiles/s6-scripts/admin/run
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/command/with-contenv bash
|
||||
|
||||
cd /app/admin
|
||||
|
||||
# Read PostgreSQL password from file
|
||||
POSTGRES_PASSWORD=$(cat /secrets/postgres_password)
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
echo "[admin] Waiting for PostgreSQL to be ready..."
|
||||
for i in {1..30}; do
|
||||
if PGPASSWORD="$POSTGRES_PASSWORD" /usr/lib/postgresql/16/bin/psql -h localhost -U aliasvault -d aliasvault -c "SELECT 1;" >/dev/null 2>&1; then
|
||||
echo "[admin] PostgreSQL ready, starting Admin..."
|
||||
break
|
||||
fi
|
||||
if [ $i -eq 30 ]; then
|
||||
echo "[admin] Timeout waiting for PostgreSQL"
|
||||
exit 1
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
export ConnectionStrings__AliasServerDbContext="Host=localhost;Database=aliasvault;Username=aliasvault;Password=$POSTGRES_PASSWORD"
|
||||
export ASPNETCORE_URLS="http://0.0.0.0:3002"
|
||||
export ASPNETCORE_PATHBASE="/admin"
|
||||
export IP_LOGGING_ENABLED="${IP_LOGGING_ENABLED:-true}"
|
||||
|
||||
echo "[admin] Starting Admin service..."
|
||||
exec dotnet AliasVault.Admin.dll
|
||||
1
dockerfiles/s6-scripts/admin/type
Normal file
1
dockerfiles/s6-scripts/admin/type
Normal file
@@ -0,0 +1 @@
|
||||
longrun
|
||||
0
dockerfiles/s6-scripts/api/dependencies.d/postgres
Normal file
0
dockerfiles/s6-scripts/api/dependencies.d/postgres
Normal file
30
dockerfiles/s6-scripts/api/run
Normal file
30
dockerfiles/s6-scripts/api/run
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/command/with-contenv bash
|
||||
|
||||
cd /app/api
|
||||
|
||||
# Read PostgreSQL password from file
|
||||
POSTGRES_PASSWORD=$(cat /secrets/postgres_password)
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
echo "[api] Waiting for PostgreSQL to be ready..."
|
||||
for i in {1..30}; do
|
||||
if PGPASSWORD="$POSTGRES_PASSWORD" /usr/lib/postgresql/16/bin/psql -h localhost -U aliasvault -d aliasvault -c "SELECT 1;" >/dev/null 2>&1; then
|
||||
echo "[api] PostgreSQL ready, starting API..."
|
||||
break
|
||||
fi
|
||||
if [ $i -eq 30 ]; then
|
||||
echo "[api] Timeout waiting for PostgreSQL"
|
||||
exit 1
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
export ConnectionStrings__AliasServerDbContext="Host=localhost;Database=aliasvault;Username=aliasvault;Password=$POSTGRES_PASSWORD"
|
||||
export ASPNETCORE_URLS="http://0.0.0.0:3001"
|
||||
export ASPNETCORE_PATHBASE="/api"
|
||||
export PRIVATE_EMAIL_DOMAINS="${PRIVATE_EMAIL_DOMAINS:-}"
|
||||
export PUBLIC_REGISTRATION_ENABLED="${PUBLIC_REGISTRATION_ENABLED:-true}"
|
||||
export IP_LOGGING_ENABLED="${IP_LOGGING_ENABLED:-true}"
|
||||
|
||||
echo "[api] Starting API service..."
|
||||
exec dotnet AliasVault.Api.dll
|
||||
1
dockerfiles/s6-scripts/api/type
Normal file
1
dockerfiles/s6-scripts/api/type
Normal file
@@ -0,0 +1 @@
|
||||
longrun
|
||||
0
dockerfiles/s6-scripts/client/dependencies.d/init
Normal file
0
dockerfiles/s6-scripts/client/dependencies.d/init
Normal file
33
dockerfiles/s6-scripts/client/run
Normal file
33
dockerfiles/s6-scripts/client/run
Normal file
@@ -0,0 +1,33 @@
|
||||
#!/command/with-contenv bash
|
||||
|
||||
# Client service entrypoint
|
||||
DEFAULT_PRIVATE_EMAIL_DOMAINS=""
|
||||
DEFAULT_SUPPORT_EMAIL=""
|
||||
PRIVATE_EMAIL_DOMAINS=${PRIVATE_EMAIL_DOMAINS:-$DEFAULT_PRIVATE_EMAIL_DOMAINS}
|
||||
SUPPORT_EMAIL=${SUPPORT_EMAIL:-$DEFAULT_SUPPORT_EMAIL}
|
||||
PUBLIC_REGISTRATION_ENABLED=${PUBLIC_REGISTRATION_ENABLED:-true}
|
||||
|
||||
mkdir -p /etc/nginx/ssl
|
||||
|
||||
if [ ! -f /etc/nginx/ssl/nginx.crt ] || [ ! -f /etc/nginx/ssl/nginx.key ]; then
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /etc/nginx/ssl/nginx.key \
|
||||
-out /etc/nginx/ssl/nginx.crt \
|
||||
-subj "/C=US/ST=State/L=City/O=Organization/CN=localhost" >/dev/null 2>&1
|
||||
chmod 644 /etc/nginx/ssl/nginx.crt
|
||||
chmod 600 /etc/nginx/ssl/nginx.key
|
||||
fi
|
||||
|
||||
# Create simple JSON with environment variables
|
||||
cat > /app/client/wwwroot/appsettings.json << EOF
|
||||
{
|
||||
"PrivateEmailDomains": ["$PRIVATE_EMAIL_DOMAINS"],
|
||||
"SupportEmail": "$SUPPORT_EMAIL",
|
||||
"PublicRegistrationEnabled": "$PUBLIC_REGISTRATION_ENABLED"
|
||||
}
|
||||
EOF
|
||||
|
||||
sed -i "s|/usr/share/nginx/html|/app/client/wwwroot|g" /app/client/nginx.conf
|
||||
|
||||
echo "[client] Starting Client service (nginx)..."
|
||||
exec nginx -c /app/client/nginx.conf -g "daemon off;"
|
||||
1
dockerfiles/s6-scripts/client/type
Normal file
1
dockerfiles/s6-scripts/client/type
Normal file
@@ -0,0 +1 @@
|
||||
longrun
|
||||
0
dockerfiles/s6-scripts/init/dependencies.d/base
Normal file
0
dockerfiles/s6-scripts/init/dependencies.d/base
Normal file
139
dockerfiles/s6-scripts/init/script
Normal file
139
dockerfiles/s6-scripts/init/script
Normal file
@@ -0,0 +1,139 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# AliasVault Container Initialization Script
|
||||
# This script runs once at container startup and handles all initialization tasks
|
||||
|
||||
# Print AliasVault header
|
||||
echo ""
|
||||
echo "=================================================="
|
||||
echo " _ _ _ __ __ _ _ "
|
||||
echo " / \\ | (_) __ _ ___ \\ \\ / /_ _ _ _| | |_"
|
||||
echo " / _ \\ | | |/ _\` / __| \\ \\/\\/ / _\` | | | | | __|"
|
||||
echo " / ___ \\| | | (_| \\__ \\ \\ / / (_| | |_| | | |_ "
|
||||
echo "/_/ \\_\\_|_|\\__,_|___/ \\/ \\__,__|\\__,_|_|\\__|"
|
||||
echo ""
|
||||
echo "=================================================="
|
||||
echo ""
|
||||
|
||||
echo "[init] Starting AliasVault container initialization..."
|
||||
echo ""
|
||||
|
||||
# Create required directories
|
||||
echo "[init] Creating required directories..."
|
||||
mkdir -p /database/postgres /logs/postgres /certificates /secrets /var/run/postgresql
|
||||
|
||||
# Initialize secrets if they don't exist
|
||||
echo "[init] Checking and initializing secrets..."
|
||||
|
||||
if [ ! -f /secrets/postgres_password ]; then
|
||||
echo "[init] → Generating PostgreSQL password..."
|
||||
openssl rand -base64 32 | tr -d "\n" > /secrets/postgres_password
|
||||
chmod 600 /secrets/postgres_password
|
||||
else
|
||||
echo "[init] → PostgreSQL password already exists"
|
||||
fi
|
||||
|
||||
if [ ! -f /secrets/data_protection_cert_pass ]; then
|
||||
echo "[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
|
||||
echo "[init] → Data Protection Certificate password already exists"
|
||||
fi
|
||||
|
||||
if [ ! -f /secrets/jwt_key ]; then
|
||||
echo "[init] → Generating JWT key..."
|
||||
openssl rand -base64 32 | tr -d "\n" > /secrets/jwt_key
|
||||
chmod 600 /secrets/jwt_key
|
||||
else
|
||||
echo "[init] → JWT key already exists"
|
||||
fi
|
||||
|
||||
# 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
|
||||
echo ""
|
||||
echo "[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
|
||||
echo "[init] → Running initdb..."
|
||||
su - postgres -c "/usr/lib/postgresql/16/bin/initdb -D $PGDATA --locale=en_US.UTF-8 --encoding=UTF8" > /logs/postgres/initdb.log 2>&1
|
||||
|
||||
# Configure PostgreSQL
|
||||
echo "[init] → Configuring PostgreSQL..."
|
||||
echo "host all all 127.0.0.1/32 md5" >> "$PGDATA/pg_hba.conf"
|
||||
echo "listen_addresses = '127.0.0.1'" >> "$PGDATA/postgresql.conf"
|
||||
|
||||
# Start PostgreSQL temporarily to create database and user
|
||||
echo "[init] → Starting PostgreSQL temporarily for setup..."
|
||||
su - postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA -l /logs/postgres/postgres.log start"
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
echo "[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
|
||||
echo "[init] → Creating AliasVault database and user..."
|
||||
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;\""
|
||||
su - postgres -c "/usr/lib/postgresql/16/bin/psql -c \"GRANT ALL PRIVILEGES ON DATABASE aliasvault TO aliasvault;\""
|
||||
|
||||
# Stop PostgreSQL
|
||||
echo "[init] → Stopping PostgreSQL..."
|
||||
su - postgres -c "/usr/lib/postgresql/16/bin/pg_ctl -D $PGDATA stop"
|
||||
sleep 2
|
||||
|
||||
echo "[init] → PostgreSQL initialization complete"
|
||||
else
|
||||
echo "[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
|
||||
# echo "[init] Checking for database migrations..."
|
||||
# if [ -f /app/migrations/pending ]; then
|
||||
# echo "[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
|
||||
echo ""
|
||||
echo "[init] Generating SSL certificates..."
|
||||
mkdir -p /certificates/ssl
|
||||
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
|
||||
chmod 600 /certificates/ssl/key.pem
|
||||
chmod 644 /certificates/ssl/cert.pem
|
||||
echo "[init] → SSL certificates generated"
|
||||
else
|
||||
echo "[init] SSL certificates already exist"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[init] ========================================="
|
||||
echo "[init] AliasVault initialization complete!"
|
||||
echo "[init] ========================================="
|
||||
echo ""
|
||||
|
||||
# Oneshot service exits successfully, dependencies can now start
|
||||
1
dockerfiles/s6-scripts/init/type
Normal file
1
dockerfiles/s6-scripts/init/type
Normal file
@@ -0,0 +1 @@
|
||||
oneshot
|
||||
1
dockerfiles/s6-scripts/init/up
Normal file
1
dockerfiles/s6-scripts/init/up
Normal file
@@ -0,0 +1 @@
|
||||
/etc/s6-overlay/s6-rc.d/init/script
|
||||
0
dockerfiles/s6-scripts/nginx/dependencies.d/admin
Normal file
0
dockerfiles/s6-scripts/nginx/dependencies.d/admin
Normal file
0
dockerfiles/s6-scripts/nginx/dependencies.d/api
Normal file
0
dockerfiles/s6-scripts/nginx/dependencies.d/api
Normal file
0
dockerfiles/s6-scripts/nginx/dependencies.d/client
Normal file
0
dockerfiles/s6-scripts/nginx/dependencies.d/client
Normal file
34
dockerfiles/s6-scripts/nginx/run
Normal file
34
dockerfiles/s6-scripts/nginx/run
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/command/with-contenv bash
|
||||
|
||||
# Copy certificates to nginx directory (they were created during init)
|
||||
mkdir -p /etc/nginx/ssl
|
||||
cp /certificates/ssl/* /etc/nginx/ssl/ 2>/dev/null || true
|
||||
|
||||
# Create SSL configuration file
|
||||
cat > /etc/nginx/ssl.conf << "SSLEOF"
|
||||
ssl_certificate /etc/nginx/ssl/cert.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/key.pem;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:MozTLS:10m;
|
||||
ssl_session_tickets off;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
SSLEOF
|
||||
|
||||
# Wait for all services to be ready
|
||||
echo "[nginx] Waiting for services to be ready..."
|
||||
for i in {1..60}; do
|
||||
if nc -z localhost 3000 && nc -z localhost 3001 && nc -z localhost 3002; then
|
||||
echo "[nginx] All services ready, starting reverse proxy..."
|
||||
break
|
||||
fi
|
||||
if [ $i -eq 60 ]; then
|
||||
echo "[nginx] Timeout waiting for services"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "[nginx] Starting reverse proxy..."
|
||||
exec nginx -g "daemon off;"
|
||||
1
dockerfiles/s6-scripts/nginx/type
Normal file
1
dockerfiles/s6-scripts/nginx/type
Normal file
@@ -0,0 +1 @@
|
||||
longrun
|
||||
0
dockerfiles/s6-scripts/postgres/dependencies.d/init
Normal file
0
dockerfiles/s6-scripts/postgres/dependencies.d/init
Normal file
10
dockerfiles/s6-scripts/postgres/run
Normal file
10
dockerfiles/s6-scripts/postgres/run
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Set PostgreSQL paths
|
||||
export PATH="/usr/lib/postgresql/16/bin:$PATH"
|
||||
export PGDATA="/database/postgres"
|
||||
|
||||
echo "[postgres] Starting PostgreSQL server..."
|
||||
|
||||
# Run PostgreSQL as postgres user
|
||||
exec s6-setuidgid postgres /usr/lib/postgresql/16/bin/postgres -D "$PGDATA"
|
||||
1
dockerfiles/s6-scripts/postgres/type
Normal file
1
dockerfiles/s6-scripts/postgres/type
Normal file
@@ -0,0 +1 @@
|
||||
longrun
|
||||
0
dockerfiles/s6-scripts/smtp/dependencies.d/postgres
Normal file
0
dockerfiles/s6-scripts/smtp/dependencies.d/postgres
Normal file
27
dockerfiles/s6-scripts/smtp/run
Normal file
27
dockerfiles/s6-scripts/smtp/run
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/command/with-contenv bash
|
||||
|
||||
cd /app/smtp
|
||||
|
||||
# Read PostgreSQL password from file
|
||||
POSTGRES_PASSWORD=$(cat /secrets/postgres_password)
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
echo "[smtp] Waiting for PostgreSQL to be ready..."
|
||||
for i in {1..30}; do
|
||||
if PGPASSWORD="$POSTGRES_PASSWORD" /usr/lib/postgresql/16/bin/psql -h localhost -U aliasvault -d aliasvault -c "SELECT 1;" >/dev/null 2>&1; then
|
||||
echo "[smtp] PostgreSQL ready, starting SMTP..."
|
||||
break
|
||||
fi
|
||||
if [ $i -eq 30 ]; then
|
||||
echo "[smtp] Timeout waiting for PostgreSQL"
|
||||
exit 1
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
export ConnectionStrings__AliasServerDbContext="Host=localhost;Database=aliasvault;Username=aliasvault;Password=$POSTGRES_PASSWORD"
|
||||
export PRIVATE_EMAIL_DOMAINS="${PRIVATE_EMAIL_DOMAINS:-}"
|
||||
export SMTP_TLS_ENABLED="${SMTP_TLS_ENABLED:-false}"
|
||||
|
||||
echo "[smtp] Starting SMTP service..."
|
||||
exec dotnet AliasVault.SmtpService.dll
|
||||
1
dockerfiles/s6-scripts/smtp/type
Normal file
1
dockerfiles/s6-scripts/smtp/type
Normal file
@@ -0,0 +1 @@
|
||||
longrun
|
||||
25
dockerfiles/s6-scripts/taskrunner/run
Normal file
25
dockerfiles/s6-scripts/taskrunner/run
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/command/with-contenv bash
|
||||
|
||||
cd /app/taskrunner
|
||||
|
||||
# Read PostgreSQL password from file
|
||||
POSTGRES_PASSWORD=$(cat /secrets/postgres_password)
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
echo "[taskrunner] Waiting for PostgreSQL to be ready..."
|
||||
for i in {1..30}; do
|
||||
if PGPASSWORD="$POSTGRES_PASSWORD" /usr/lib/postgresql/16/bin/psql -h localhost -U aliasvault -d aliasvault -c "SELECT 1;" >/dev/null 2>&1; then
|
||||
echo "[taskrunner] PostgreSQL ready, starting TaskRunner..."
|
||||
break
|
||||
fi
|
||||
if [ $i -eq 30 ]; then
|
||||
echo "[taskrunner] Timeout waiting for PostgreSQL"
|
||||
exit 1
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
export ConnectionStrings__AliasServerDbContext="Host=localhost;Database=aliasvault;Username=aliasvault;Password=$POSTGRES_PASSWORD"
|
||||
|
||||
echo "[taskrunner] Starting TaskRunner service..."
|
||||
exec dotnet AliasVault.TaskRunner.dll
|
||||
1
dockerfiles/s6-scripts/taskrunner/type
Normal file
1
dockerfiles/s6-scripts/taskrunner/type
Normal file
@@ -0,0 +1 @@
|
||||
longrun
|
||||
Reference in New Issue
Block a user