#!/bin/bash # entrypoint.sh — seed first-run instance state into the config volume, then # start the app. The image itself is code-only and stateless/rebuildable; # everything mutable lives under $ALEMBIC_CONFIG_DIR (see docs/ARCHITECTURE.md). set -euo pipefail ALEMBIC_CONFIG_DIR="${ALEMBIC_CONFIG_DIR:-/config}" PIPELINE_DIR="${PIPELINE_DIR:-/app/pipeline}" # The container runs as uid 1000. If the mounted config folder is owned by # root on the host (the usual result of `mkdir` as your normal user), the # first write fails and the container would otherwise exit with a bare # "Permission denied". Catch that here and say exactly how to fix it. if ! mkdir -p \ "$ALEMBIC_CONFIG_DIR/beets/data" \ "$ALEMBIC_CONFIG_DIR/pipeline" \ "$ALEMBIC_CONFIG_DIR/logs" 2>/dev/null; then echo "[entrypoint] ERROR: cannot write to $ALEMBIC_CONFIG_DIR" >&2 echo "[entrypoint] The container runs as uid 1000 but that folder is not writable by it." >&2 echo "[entrypoint] On the host, run: chown -R 1000:1000 " >&2 exit 1 fi seed_if_absent() { local src="$1" dst="$2" if [[ ! -f "$dst" ]]; then cp "$src" "$dst" echo "[entrypoint] seeded $dst from $(basename "$src")" fi } seed_if_absent "$PIPELINE_DIR/beets/config.yaml.example" "$ALEMBIC_CONFIG_DIR/beets/config.yaml" seed_if_absent "$PIPELINE_DIR/configs/artist-canonical.list.example" "$ALEMBIC_CONFIG_DIR/pipeline/artist-canonical.list" seed_if_absent "$PIPELINE_DIR/configs/djmix-albums.txt.example" "$ALEMBIC_CONFIG_DIR/pipeline/djmix-albums.txt" seed_if_absent "$PIPELINE_DIR/configs/genres-whitelist.txt.example" "$ALEMBIC_CONFIG_DIR/pipeline/genres-whitelist.txt" seed_if_absent "$PIPELINE_DIR/configs/cross-album-keep.list.example" "$ALEMBIC_CONFIG_DIR/pipeline/cross-album-keep.list" export BEETSDIR="$ALEMBIC_CONFIG_DIR/beets" exec uvicorn app.main:app --host 0.0.0.0 --port "${ALEMBIC_PORT:-8420}"