feat(docker): migrations sqlx intégrées dans le démarrage de l'API
- Déplace les migrations du service `migrate` séparé vers un entrypoint.sh - L'API exécute `sqlx migrate run` au démarrage avant de lancer le binaire - Gestion de la rétrocompatibilité : détecte un schéma pre-sqlx et crée une baseline `_sqlx_migrations` pour éviter les conflits sur les instances existantes - Installe sqlx-cli dans le builder, copie le binaire et les migrations dans l'image finale - Supprime le service `migrate` du docker-compose.yml ; l'indexer dépend maintenant du healthcheck de l'API (qui garantit que les migrations sont appliquées) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -18,13 +18,20 @@ COPY crates/parsers/src crates/parsers/src
|
||||
|
||||
# Build with sccache (cache persisted between builds via Docker cache mount)
|
||||
RUN --mount=type=cache,target=/sccache \
|
||||
cargo build --release -p api
|
||||
cargo build --release -p api && \
|
||||
cargo install sqlx-cli --no-default-features --features postgres --locked
|
||||
|
||||
FROM debian:bookworm-slim
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates wget unar poppler-utils locales && rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates wget unar poppler-utils locales postgresql-client \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
|
||||
ENV LANG=en_US.UTF-8
|
||||
ENV LC_ALL=en_US.UTF-8
|
||||
COPY --from=builder /app/target/release/api /usr/local/bin/api
|
||||
COPY --from=builder /usr/local/cargo/bin/sqlx /usr/local/bin/sqlx
|
||||
COPY infra/migrations /app/migrations
|
||||
COPY apps/api/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
EXPOSE 7080
|
||||
CMD ["/usr/local/bin/api"]
|
||||
CMD ["/usr/local/bin/entrypoint.sh"]
|
||||
|
||||
63
apps/api/entrypoint.sh
Normal file
63
apps/api/entrypoint.sh
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# psql requires "postgresql://" but Rust/sqlx accepts both "postgres://" and "postgresql://"
|
||||
PSQL_URL=$(echo "$DATABASE_URL" | sed 's|^postgres://|postgresql://|')
|
||||
|
||||
# Check 1: does the old schema exist (index_jobs table)?
|
||||
HAS_OLD_TABLES=$(psql "$PSQL_URL" -tAc \
|
||||
"SELECT EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name='index_jobs')::text" \
|
||||
2>/dev/null || echo "false")
|
||||
|
||||
# Check 2: is sqlx tracking present and non-empty?
|
||||
HAS_SQLX_TABLE=$(psql "$PSQL_URL" -tAc \
|
||||
"SELECT EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name='_sqlx_migrations')::text" \
|
||||
2>/dev/null || echo "false")
|
||||
|
||||
if [ "$HAS_SQLX_TABLE" = "true" ]; then
|
||||
HAS_SQLX_ROWS=$(psql "$PSQL_URL" -tAc \
|
||||
"SELECT EXISTS(SELECT 1 FROM _sqlx_migrations LIMIT 1)::text" \
|
||||
2>/dev/null || echo "false")
|
||||
else
|
||||
HAS_SQLX_ROWS="false"
|
||||
fi
|
||||
|
||||
echo "==> Migration check: old_tables=$HAS_OLD_TABLES sqlx_table=$HAS_SQLX_TABLE sqlx_rows=$HAS_SQLX_ROWS"
|
||||
|
||||
if [ "$HAS_OLD_TABLES" = "true" ] && [ "$HAS_SQLX_ROWS" = "false" ]; then
|
||||
echo "==> Upgrade from pre-sqlx migration system detected: creating baseline..."
|
||||
|
||||
psql "$PSQL_URL" -c "
|
||||
CREATE TABLE IF NOT EXISTS _sqlx_migrations (
|
||||
version BIGINT PRIMARY KEY,
|
||||
description TEXT NOT NULL,
|
||||
installed_on TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
success BOOLEAN NOT NULL,
|
||||
checksum BYTEA NOT NULL,
|
||||
execution_time BIGINT NOT NULL
|
||||
)
|
||||
"
|
||||
|
||||
for f in /app/migrations/*.sql; do
|
||||
filename=$(basename "$f")
|
||||
# Strip leading zeros to get the integer version (e.g. "0005" -> "5")
|
||||
version=$(echo "$filename" | sed 's/^0*//' | cut -d'_' -f1)
|
||||
description=$(echo "$filename" | sed 's/^[0-9]*_//' | sed 's/\.sql$//')
|
||||
checksum=$(sha384sum "$f" | awk '{print $1}')
|
||||
|
||||
psql "$PSQL_URL" -c "
|
||||
INSERT INTO _sqlx_migrations (version, description, installed_on, success, checksum, execution_time)
|
||||
VALUES ($version, '$description', NOW(), TRUE, decode('$checksum', 'hex'), 0)
|
||||
ON CONFLICT (version) DO NOTHING
|
||||
"
|
||||
echo " baselined: $filename"
|
||||
done
|
||||
|
||||
echo "==> Baseline complete."
|
||||
fi
|
||||
|
||||
echo "==> Running migrations..."
|
||||
sqlx migrate run --source /app/migrations
|
||||
|
||||
echo "==> Starting API..."
|
||||
exec /usr/local/bin/api
|
||||
@@ -29,24 +29,6 @@ services:
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
migrate:
|
||||
image: postgres:16-alpine
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
POSTGRES_USER: stripstream
|
||||
POSTGRES_PASSWORD: stripstream
|
||||
POSTGRES_DB: stripstream
|
||||
volumes:
|
||||
- ./infra/migrations:/migrations:ro
|
||||
command:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
"export PGPASSWORD=$$POSTGRES_PASSWORD; for f in /migrations/*.sql; do echo \"Applying migration: $$f\"; psql -h postgres -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\" -f \"$$f\" || exit 1; done",
|
||||
]
|
||||
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
@@ -59,8 +41,6 @@ services:
|
||||
- ${LIBRARIES_HOST_PATH:-./libraries}:/libraries
|
||||
- ${THUMBNAILS_HOST_PATH:-./data/thumbnails}:/data/thumbnails
|
||||
depends_on:
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
meilisearch:
|
||||
@@ -83,8 +63,8 @@ services:
|
||||
- ${LIBRARIES_HOST_PATH:-./libraries}:/libraries
|
||||
- ${THUMBNAILS_HOST_PATH:-./data/thumbnails}:/data/thumbnails
|
||||
depends_on:
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
api:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
meilisearch:
|
||||
|
||||
Reference in New Issue
Block a user