Inject app variables into deployments

This commit is contained in:
2026-06-03 08:21:37 +02:00
parent f2f7a59850
commit 98c7468a80
2 changed files with 75 additions and 1 deletions
+69
View File
@@ -17,6 +17,8 @@ mkdir -p "$DOCKER_CONFIG"
DB_FILE="/opt/appfactory/data/appfactory/appfactory.db" DB_FILE="/opt/appfactory/data/appfactory/appfactory.db"
APP_SOURCE_DIR="$WORKSPACE_DIR/$APP_ID" APP_SOURCE_DIR="$WORKSPACE_DIR/$APP_ID"
TOOLS_DIR="$WORKSPACE_DIR/appfactory-tools" TOOLS_DIR="$WORKSPACE_DIR/appfactory-tools"
APP_DATA_DIR="$APPFACTORY_DIR/data/apps/$APP_ID"
APP_ENV_FILE="$APP_DATA_DIR/.env"
TRIGGER_SOURCE="${APPFACTORY_TRIGGER_SOURCE:-cli}" TRIGGER_SOURCE="${APPFACTORY_TRIGGER_SOURCE:-cli}"
TRIGGERED_BY_USER_ID="${APPFACTORY_TRIGGERED_BY_USER_ID:-}" TRIGGERED_BY_USER_ID="${APPFACTORY_TRIGGERED_BY_USER_ID:-}"
@@ -179,6 +181,73 @@ fi
RESULT=$? RESULT=$?
if [ "$RESULT" -eq 0 ]; then
run_step "Generating app environment file" bash -c "
mkdir -p '$APP_DATA_DIR'
python3 - '$DB_FILE' '$APP_ID' '$APP_ENV_FILE' <<'PY'
import os
import re
import sqlite3
import sys
from pathlib import Path
db_file = sys.argv[1]
app_id = sys.argv[2]
env_file = Path(sys.argv[3])
key_pattern = re.compile(r'^[A-Za-z_][A-Za-z0-9_]*$')
con = sqlite3.connect(db_file)
con.row_factory = sqlite3.Row
rows = con.execute(
'''
SELECT key, value, is_secret, required
FROM app_variables
WHERE app_id = ?
ORDER BY key
''',
(app_id,),
).fetchall()
missing_required = []
lines = [
'# Generated by AppFactory. Do not edit manually.',
f'APP_ID={app_id}',
]
for row in rows:
key = row['key']
value = row['value'] or ''
required = int(row['required'] or 0)
if not key_pattern.match(key):
raise SystemExit(f'Invalid environment variable key: {key}')
if required and value == '':
missing_required.append(key)
escaped = value.replace('\\\\', '\\\\\\\\').replace('\"', '\\\\\"').replace('\\n', '\\\\n')
lines.append(f'{key}=\"{escaped}\"')
if missing_required:
raise SystemExit('Missing required variables: ' + ', '.join(missing_required))
env_file.parent.mkdir(parents=True, exist_ok=True)
env_file.write_text('\\n'.join(lines) + '\\n', encoding='utf-8')
os.chmod(env_file, 0o600)
con.close()
PY
echo 'Generated env file: $APP_ENV_FILE'
"
RESULT=$?
fi
if [ "$RESULT" -eq 0 ]; then if [ "$RESULT" -eq 0 ]; then
run_step "Building Docker image" \ run_step "Building Docker image" \
docker build --pull --no-cache \ docker build --pull --no-cache \
+6 -1
View File
@@ -11,11 +11,13 @@ cat > "$COMPOSE_FILE" <<'EOF_COMPOSE'
services: services:
EOF_COMPOSE EOF_COMPOSE
python3 - "$CATALOG_FILE" "$COMPOSE_FILE" <<'PY' python3 - "$CATALOG_FILE" "$COMPOSE_FILE" "$APPFACTORY_DIR" <<'PY'
import sys import sys
from pathlib import Path
catalog_file = sys.argv[1] catalog_file = sys.argv[1]
compose_file = sys.argv[2] compose_file = sys.argv[2]
appfactory_dir = sys.argv[3]
apps = [] apps = []
current = None current = None
@@ -41,11 +43,14 @@ with open(compose_file, "a", encoding="utf-8") as f:
app_id = app["id"] app_id = app["id"]
memory = app.get("memory", "") memory = app.get("memory", "")
cpus = app.get("cpus", "") cpus = app.get("cpus", "")
env_file = f"{appfactory_dir}/data/apps/{app_id}/.env"
f.write(f" {app_id}:\n") f.write(f" {app_id}:\n")
f.write(f" image: {app_id}:latest\n") f.write(f" image: {app_id}:latest\n")
f.write(f" container_name: {app_id}\n") f.write(f" container_name: {app_id}\n")
f.write(" restart: unless-stopped\n") f.write(" restart: unless-stopped\n")
f.write(" env_file:\n")
f.write(f" - {env_file}\n")
if memory: if memory:
f.write(f" mem_limit: {memory}\n") f.write(f" mem_limit: {memory}\n")