From 745dd9799ba7853e715c40d2bcb45b4dd4c73361 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 17 Nov 2025 14:12:50 +0000 Subject: [PATCH 1/3] Initial plan From d35df4c24c5b616e047bd4c99431c5ced167fe93 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 17 Nov 2025 14:16:36 +0000 Subject: [PATCH 2/3] Add cron service for load_from_static command Co-authored-by: tiankaima <91816094+tiankaima@users.noreply.github.com> --- .github/workflows/docker-build-push-cron.yml | 55 ++++++++++++++++++++ docker-compose.prod.yml | 17 ++++++ docker-compose.yml | 19 +++++++ src/Dockerfile.cron | 27 ++++++++++ src/crontab | 3 ++ 5 files changed, 121 insertions(+) create mode 100644 .github/workflows/docker-build-push-cron.yml create mode 100644 src/Dockerfile.cron create mode 100644 src/crontab diff --git a/.github/workflows/docker-build-push-cron.yml b/.github/workflows/docker-build-push-cron.yml new file mode 100644 index 0000000..ba04cb1 --- /dev/null +++ b/.github/workflows/docker-build-push-cron.yml @@ -0,0 +1,55 @@ +name: Build and Push Cron Docker Image + +on: + push: + branches: [main] + paths: + - "src/**" + - ".github/workflows/docker-build-push-cron.yml" + workflow_dispatch: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: Life-USTC/server-cron + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=sha,format=short + type=ref,event=branch + latest + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: ./src + file: ./src/Dockerfile.cron + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 0dc7947..5aacf48 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -33,6 +33,23 @@ services: networks: - backend + cron: + image: ghcr.io/life-ustc/server-cron:latest + restart: always + depends_on: + - db + environment: + - DJANGO_SECRET_KEY=${DJANGO_SECRET_KEY} + - DJANGO_DEBUG=False + - DJANGO_ALLOWED_HOSTS=life-ustc.tiankaima.dev + - POSTGRES_DB=${POSTGRES_DB:-postgres} + - POSTGRES_USER=${POSTGRES_USER:-user} + - POSTGRES_PASSWORD=${POSTGRES_password} + - POSTGRES_HOST=${POSTGRES_HOST:-db} + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + networks: + - backend + networks: backend: driver: bridge diff --git a/docker-compose.yml b/docker-compose.yml index 564c44d..9d83f08 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -36,6 +36,25 @@ services: networks: - backend + cron: + build: + context: ./src + dockerfile: Dockerfile.cron + volumes: + - ./src:/app + depends_on: + - db + environment: + - DJANGO_DEBUG=True + - DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0 + - POSTGRES_DB=${POSTGRES_DB:-postgres} + - POSTGRES_USER=${POSTGRES_USER:-user} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password} + - POSTGRES_HOST=${POSTGRES_HOST:-db} + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + networks: + - backend + networks: backend: driver: bridge diff --git a/src/Dockerfile.cron b/src/Dockerfile.cron new file mode 100644 index 0000000..d122e32 --- /dev/null +++ b/src/Dockerfile.cron @@ -0,0 +1,27 @@ +FROM python:3.13-slim + +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app + +COPY . . + +# Install cron, gettext, and git (needed for load_from_static to clone repos) +RUN apt-get update && apt-get install -y cron gettext git && rm -rf /var/lib/apt/lists/* \ + && pip install --upgrade pip \ + && pip install --no-cache-dir -r requirements.txt + +RUN python manage.py compilemessages + +# Copy crontab file and set up cron +COPY crontab /etc/cron.d/django-cron +RUN chmod 0644 /etc/cron.d/django-cron \ + && crontab /etc/cron.d/django-cron \ + && touch /var/log/cron.log + +# Create entrypoint script +RUN echo '#!/bin/bash\nset -e\nprintenv | grep -v "no_proxy" >> /etc/environment\ncron && tail -f /var/log/cron.log' > /entrypoint.sh \ + && chmod +x /entrypoint.sh + +CMD ["/entrypoint.sh"] diff --git a/src/crontab b/src/crontab new file mode 100644 index 0000000..02d4bd4 --- /dev/null +++ b/src/crontab @@ -0,0 +1,3 @@ +# Run load_from_static command 4 times per day (every 6 hours) +# At 00:00, 06:00, 12:00, and 18:00 every day +0 0,6,12,18 * * * cd /app && python manage.py load_from_static >> /var/log/cron.log 2>&1 From 5fd6cced403c86f735b4d0f79098cc06ecdfb9b9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 17 Nov 2025 14:18:22 +0000 Subject: [PATCH 3/3] Add newline to crontab file for proper parsing Co-authored-by: tiankaima <91816094+tiankaima@users.noreply.github.com> --- src/crontab | 1 + 1 file changed, 1 insertion(+) diff --git a/src/crontab b/src/crontab index 02d4bd4..db3df65 100644 --- a/src/crontab +++ b/src/crontab @@ -1,3 +1,4 @@ # Run load_from_static command 4 times per day (every 6 hours) # At 00:00, 06:00, 12:00, and 18:00 every day 0 0,6,12,18 * * * cd /app && python manage.py load_from_static >> /var/log/cron.log 2>&1 +