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:
@@ -11,5 +11,16 @@ SILO_DB_PASSWORD=
|
|||||||
SILO_MINIO_ACCESS_KEY=silouser
|
SILO_MINIO_ACCESS_KEY=silouser
|
||||||
SILO_MINIO_SECRET_KEY=
|
SILO_MINIO_SECRET_KEY=
|
||||||
|
|
||||||
|
# Authentication
|
||||||
|
# Session secret (required when auth is enabled)
|
||||||
|
SILO_SESSION_SECRET=
|
||||||
|
# Default admin account (created on first startup if both are set)
|
||||||
|
SILO_ADMIN_USERNAME=admin
|
||||||
|
SILO_ADMIN_PASSWORD=
|
||||||
|
# OIDC client secret (if using Keycloak)
|
||||||
|
# SILO_OIDC_CLIENT_SECRET=
|
||||||
|
# LDAP bind password (if using service account for user search)
|
||||||
|
# SILO_LDAP_BIND_PASSWORD=
|
||||||
|
|
||||||
# Optional: Override server base URL
|
# Optional: Override server base URL
|
||||||
# SILO_SERVER_BASE_URL=http://silo.kindred.internal:8080
|
# SILO_SERVER_BASE_URL=http://silo.kindred.internal:8080
|
||||||
|
|||||||
@@ -255,6 +255,82 @@ restart_service() {
|
|||||||
fi
|
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() {
|
verify_deployment() {
|
||||||
log_info "Verifying deployment..."
|
log_info "Verifying deployment..."
|
||||||
|
|
||||||
@@ -361,6 +437,7 @@ main() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
install_config
|
install_config
|
||||||
|
run_migrations
|
||||||
install_systemd
|
install_systemd
|
||||||
set_permissions
|
set_permissions
|
||||||
restart_service
|
restart_service
|
||||||
|
|||||||
Reference in New Issue
Block a user