diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 13875f8..84bd4cd 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -20,6 +20,12 @@ jobs: with: python-version: '3.11' + - name: Cache pip packages + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('api/requirements.txt') }} + - name: Установка зависимостей run: | cd api @@ -53,6 +59,82 @@ jobs: run: | cd web npm run build + + build-and-deploy: + needs: test-backend + runs-on: ubuntu-latest + if: success() # Запускается только если тесты прошли успешно + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to container registry + uses: docker/login-action@v3 + with: + registry: git.rlkdev.ru # Замените на ваш Gitea registry + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_TOKEN }} + + - name: Cache Docker layers + uses: actions/cache@v4 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ hashFiles('api/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-buildx- + + - name: Build Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: false + load: true + tags: fastapi-app:latest + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache,mode=max + + - name: Stop and remove old container + run: | + docker stop fastapi-container || true + docker rm fastapi-container || true + + - name: Run new container + run: | + docker run -d \ + --name fastapi-container \ + -p 8080:8000 \ + --restart unless-stopped \ + fastapi-app:latest + + - name: Wait for container to be ready + run: | + timeout=60 + interval=2 + elapsed=0 + while [ $elapsed -lt $timeout ]; do + if docker logs fastapi-container 2>&1 | grep -q "Application startup complete"; then + echo "Application startup detected in logs" + echo "Deployment successful!" + exit 0 + fi + echo "Waiting for startup log... ($elapsed/$timeout sec)" + sleep $interval + elapsed=$((elapsed + interval)) + done + echo "Timeout: Application startup not detected in logs" + docker logs fastapi-container + exit 1 + + - name: Clean up dangling images + run: | + echo "Removing old dangling images..." + docker image prune -f + echo "Current images after cleanup:" + docker images # Явный статус для PR pr-status: diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c42dd9e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3.11-slim + +WORKDIR /app + +# 1. Копируем только файл с зависимостями (меняется редко) +COPY api/requirements.txt requirements.txt + +# 2. Устанавливаем зависимости (слой кэшируется, пока не изменился requirements.txt) +RUN pip install --no-cache-dir -r requirements.txt + +# 3. Копируем весь остальной код (меняется часто) +COPY api/ api/ + +EXPOSE 8000 + +CMD ["uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file