From 9a7bc25237577f8fc644c1699869fa91fce2ed24 Mon Sep 17 00:00:00 2001 From: spwoodcock Date: Tue, 4 Feb 2025 23:49:28 +0000 Subject: [PATCH] build: add supercronic to backend container, plus scheduler compose --- compose.yaml | 36 +++++++++++++++++++++++++++++++++++- src/backend/.dockerignore | 1 + src/backend/Dockerfile | 19 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/compose.yaml b/compose.yaml index 092d2e583c..44a7ea3919 100644 --- a/compose.yaml +++ b/compose.yaml @@ -78,7 +78,7 @@ services: - fmtm_logs:/opt/logs - fmtm_tiles:/opt/tiles - ./src/backend/pyproject.toml:/opt/pyproject.toml:ro - - ./src/backend/app:/opt/app + - ./src/backend/app:/opt/app:ro - ./src/backend/tests:/opt/tests:ro # - ../osm-fieldwork/osm_fieldwork:/home/appuser/.local/lib/python3.12/site-packages/osm_fieldwork:ro # - ../osm-rawdata/osm_rawdata:/home/appuser/.local/lib/python3.12/site-packages/osm_rawdata:ro @@ -344,3 +344,37 @@ services: restart: "on-failure:2" healthcheck: test: [] # Set the health check test to an empty value to disable it + + scheduler: + image: "ghcr.io/hotosm/fmtm/backend:${TAG_OVERRIDE:-debug}" + depends_on: + fmtm-db: + condition: service_healthy + s3: + condition: service_healthy + env_file: + - .env + volumes: + - ./src/backend/scheduler:/opt/scheduler:ro + networks: + - fmtm-net + entrypoint: ["/bin/sh", "-c"] + # The approach below allows us to easily switch to Kubernetes CronJob if needed + command: | + " + # Task unlocking every 3hrs + echo '* */3 * * * /opt/scheduler/unlock_tasks.py' > ./crontab + + # Task unlocking every Sunday 00:00 + echo '0 0 * * 0 /opt/scheduler/inactive_users.py' > ./crontab + + exec /usr/local/bin/supercronic ./crontab + " + restart: "unless-stopped" + # Check the 'supercronic' service is still running + healthcheck: + test: ["CMD", "pgrep", "supercronic"] + interval: 5m + timeout: 10s + retries: 3 + start_period: 10s diff --git a/src/backend/.dockerignore b/src/backend/.dockerignore index 8dddb3d6dc..f821d89204 100644 --- a/src/backend/.dockerignore +++ b/src/backend/.dockerignore @@ -11,3 +11,4 @@ !pyproject.toml !uv.lock !migrations +!scheduler diff --git a/src/backend/Dockerfile b/src/backend/Dockerfile index 04da14d68f..82ac1dd9e3 100644 --- a/src/backend/Dockerfile +++ b/src/backend/Dockerfile @@ -59,6 +59,17 @@ ENV LANG=en_US.UTF-8 \ STOPSIGNAL SIGINT +# Get supercronic binary for userland scheduling (cron daemon needs root) +FROM base AS supercronic +ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.2.33/supercronic-linux-amd64 \ + SUPERCRONIC_SHA1SUM=71b0d58cc53f6bd72cf2f293e09e294b79c666d8 \ + SUPERCRONIC=supercronic-linux-amd64 +RUN curl -fsSLO "$SUPERCRONIC_URL" \ + && echo "${SUPERCRONIC_SHA1SUM} ${SUPERCRONIC}" | sha1sum -c - \ + && chmod +x "$SUPERCRONIC" \ + && mv "$SUPERCRONIC" /supercronic + + # Build stage will all dependencies required to build Python wheels FROM base AS build # NOTE the MONITORING argument is specified during production build on Github workflow @@ -105,11 +116,17 @@ ENV PYTHONDONTWRITEBYTECODE=1 \ SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \ REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt \ CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt +# Packages: +# - procps: pgrep util for heathchecks +# - gettext-base: envsubst util for dotenv substitution +# - postgresql-client: pg_isready util for healthchecks +# - mime-support: web mimetype support RUN apt-get update --quiet \ && DEBIAN_FRONTEND=noninteractive \ apt-get install -y --quiet --no-install-recommends \ "nano" \ "curl" \ + "procps" \ "gettext-base" \ "libpcre3" \ "mime-support" \ @@ -121,6 +138,7 @@ RUN apt-get update --quiet \ && rm -rf /var/lib/apt/lists/* # Copy minio mc client COPY --from=minio /usr/bin/mc /usr/local/bin/ +COPY --from=supercronic /supercronic /usr/local/bin/ COPY *-entrypoint.sh / ENTRYPOINT ["/app-entrypoint.sh"] # Copy Python deps from build to runtime @@ -129,6 +147,7 @@ WORKDIR /opt # Add app code COPY app/ /opt/app/ COPY migrations/ /opt/migrations/ +COPY scheduler/ /opt/scheduler/ # Add non-root user, permissions RUN useradd -u 1001 -m -c "fmtm account" -d /home/appuser -s /bin/false appuser \ && mkdir -p /opt/logs /opt/tiles \