fix(deploy): add database migration step and auth env vars

Add run_migrations function to deploy.sh that automatically applies
pending SQL migrations during deployment. Migrations are run after
config installation and before service restart.

Migration runner:
- Sources /etc/silo/silod.env for SILO_DB_PASSWORD
- Reads DB host/port/name/user from production config.yaml
- Waits for database connectivity (5 retries)
- Applies each migration file in order, skipping already-applied ones
- Gracefully degrades if psql is missing or DB password is not set

This fixes the missing migration 009 (auth tables) that caused:
- 'column created_by of relation projects does not exist'
- 'relation api_tokens does not exist'

Also adds auth environment variables to silod.env.example:
- SILO_SESSION_SECRET
- SILO_ADMIN_USERNAME / SILO_ADMIN_PASSWORD
- SILO_OIDC_CLIENT_SECRET, SILO_LDAP_BIND_PASSWORD
This commit is contained in:
Forbes
2026-01-31 12:09:17 -06:00
parent 4f0107f1b2
commit 0888c0210c
2 changed files with 88 additions and 0 deletions

View File

@@ -255,6 +255,82 @@ restart_service() {
fi
}
run_migrations() {
log_info "Running database migrations..."
local src_dir="${INSTALL_DIR}/src"
local migrations_dir="${src_dir}/migrations"
local env_file="${CONFIG_DIR}/silod.env"
if [[ ! -d "${migrations_dir}" ]]; then
die "Migrations directory not found: ${migrations_dir}"
fi
# Source env file for DB password
if [[ -f "${env_file}" ]]; then
# shellcheck disable=SC1090
source "${env_file}"
fi
# Read DB config from production config
local db_host db_port db_name db_user db_password
db_host=$(grep -A10 '^database:' "${CONFIG_DIR}/config.yaml" | grep 'host:' | head -1 | awk '{print $2}' | tr -d '"')
db_port=$(grep -A10 '^database:' "${CONFIG_DIR}/config.yaml" | grep 'port:' | head -1 | awk '{print $2}')
db_name=$(grep -A10 '^database:' "${CONFIG_DIR}/config.yaml" | grep 'name:' | head -1 | awk '{print $2}' | tr -d '"')
db_user=$(grep -A10 '^database:' "${CONFIG_DIR}/config.yaml" | grep 'user:' | head -1 | awk '{print $2}' | tr -d '"')
db_password="${SILO_DB_PASSWORD:-}"
db_host="${db_host:-localhost}"
db_port="${db_port:-5432}"
db_name="${db_name:-silo}"
db_user="${db_user:-silo}"
if [[ -z "${db_password}" ]]; then
log_warn "SILO_DB_PASSWORD not set — skipping migrations"
log_warn "Run migrations manually: psql -h ${db_host} -U ${db_user} -d ${db_name} -f migrations/009_auth.sql"
return 0
fi
# Check psql is available
if ! command -v psql >/dev/null 2>&1; then
log_warn "psql not found — skipping automatic migrations"
log_warn "Run migrations manually: psql -h ${db_host} -U ${db_user} -d ${db_name} -f migrations/009_auth.sql"
return 0
fi
# Wait for database to be reachable
local retries=0
while ! PGPASSWORD="${db_password}" psql -h "${db_host}" -p "${db_port}" -U "${db_user}" -d "${db_name}" -c '\q' 2>/dev/null; do
retries=$((retries + 1))
if [[ ${retries} -ge 5 ]]; then
log_warn "Could not connect to database after 5 attempts — skipping migrations"
return 0
fi
log_info "Waiting for database... (attempt ${retries}/5)"
sleep 2
done
# Apply each migration, skipping ones that have already been applied
local applied=0
local skipped=0
for migration in "${migrations_dir}"/*.sql; do
if [[ ! -f "${migration}" ]]; then
continue
fi
local name
name=$(basename "${migration}")
if PGPASSWORD="${db_password}" psql -h "${db_host}" -p "${db_port}" \
-U "${db_user}" -d "${db_name}" -f "${migration}" 2>/dev/null; then
log_info "Applied: ${name}"
applied=$((applied + 1))
else
skipped=$((skipped + 1))
fi
done
log_success "Migrations complete (${applied} applied, ${skipped} already present)"
}
verify_deployment() {
log_info "Verifying deployment..."
@@ -361,6 +437,7 @@ main() {
fi
install_config
run_migrations
install_systemd
set_permissions
restart_service