name: Deploy production on: push: branches: [main] workflow_dispatch: jobs: deploy: # Build on the runner; the production Docker daemon is reached only over SSH. runs-on: ubuntu-latest env: IMAGE_PREFIX: ${{ vars.IMAGE_PREFIX }} DEPLOY_TAG: ${{ gitea.sha }} steps: - name: Checkout uses: https://github.com/actions/checkout@v4 with: persist-credentials: false - name: Set up QEMU for cross-platform builds uses: https://github.com/docker/setup-qemu-action@v3 with: platforms: amd64,arm64 # Gitea does not use the GitHub Actions cache backend. cache-image: false - name: Build and push to Gitea Packages shell: bash env: REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} BUILD_PLATFORM: ${{ vars.BUILD_PLATFORM }} run: | set -Eeuo pipefail umask 077 : "${IMAGE_PREFIX:?Set IMAGE_PREFIX to registry/owner/image (without a scheme or tag)}" : "${DEPLOY_TAG:?Missing commit SHA}" : "${REGISTRY_USERNAME:?Set REGISTRY_USERNAME}" : "${REGISTRY_PASSWORD:?Set REGISTRY_PASSWORD}" registry="${IMAGE_PREFIX%%/*}" auth_dir=$(mktemp -d) builder_name="" cleanup() { local rc=$? if [[ -n "$builder_name" ]]; then docker buildx rm "$builder_name" >/dev/null || true fi rm -rf -- "$auth_dir" exit "$rc" } trap cleanup EXIT trap 'exit 130' INT trap 'exit 143' TERM export DOCKER_CONFIG="$auth_dir" export BUILDX_CONFIG="$auth_dir/buildx" printf '%s' "$REGISTRY_PASSWORD" | docker login "$registry" --username "$REGISTRY_USERNAME" --password-stdin unset REGISTRY_PASSWORD # Create after selecting the isolated config; do not change the runner's default builder. builder_name=$(docker buildx create --driver docker-container) docker info --format 'Build host: {{.OSType}}/{{.Architecture}}' echo "Target platform: ${BUILD_PLATFORM:-linux/amd64}" docker buildx inspect "$builder_name" --bootstrap docker buildx build --builder "$builder_name" --pull --load --platform "${BUILD_PLATFORM:-linux/amd64}" \ --label "org.opencontainers.image.revision=$DEPLOY_TAG" \ -f Dockerfile.backend -t "$IMAGE_PREFIX-backend:$DEPLOY_TAG" . docker buildx build --builder "$builder_name" --pull --load --platform "${BUILD_PLATFORM:-linux/amd64}" \ --label "org.opencontainers.image.revision=$DEPLOY_TAG" \ -f Dockerfile.frontend -t "$IMAGE_PREFIX-web:$DEPLOY_TAG" . docker push "$IMAGE_PREFIX-backend:$DEPLOY_TAG" docker push "$IMAGE_PREFIX-web:$DEPLOY_TAG" - name: Pull, migrate and deploy on server B shell: bash env: PROD_HOST: ${{ secrets.PROD_HOST }} PROD_PORT: ${{ secrets.PROD_PORT }} PROD_USER: ${{ secrets.PROD_USER }} DEPLOY_PATH: ${{ vars.DEPLOY_PATH }} PROD_SSH_KEY: ${{ secrets.PROD_SSH_KEY }} PROD_KNOWN_HOSTS: ${{ secrets.PROD_KNOWN_HOSTS }} REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} DATABASE_URL: ${{ secrets.DATABASE_URL }} ADMIN_PASSWORD: ${{ secrets.ADMIN_PASSWORD }} WQ_EMAIL: ${{ secrets.WQ_EMAIL }} WQ_PASSWORD: ${{ secrets.WQ_PASSWORD }} ENCRYPTION_KEY: ${{ secrets.ENCRYPTION_KEY }} ADMIN_USERNAME: ${{ vars.ADMIN_USERNAME }} PUBLIC_ORIGIN: ${{ vars.PUBLIC_ORIGIN }} MCP_ENABLED: ${{ vars.MCP_ENABLED }} run: bash scripts/deploy-remote.sh