name: Build and Push API & Web on: push: branches: - 'main' - 'deploy/**' - 'build/**' - 'release/e-*' - 'hotfix/**' tags: - '*' concurrency: group: build-push-${{ github.head_ref || github.run_id }} cancel-in-progress: true env: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} DIFY_WEB_IMAGE_NAME: ${{ vars.DIFY_WEB_IMAGE_NAME || 'langgenius/dify-web' }} DIFY_API_IMAGE_NAME: ${{ vars.DIFY_API_IMAGE_NAME || 'langgenius/dify-api' }} DIFY_AGENT_IMAGE_NAME: ${{ vars.DIFY_AGENT_IMAGE_NAME || 'langgenius/dify-agent-backend' }} DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME: ${{ vars.DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME || 'langgenius/dify-agent-local-sandbox' }} jobs: build: runs-on: ${{ matrix.runs_on }} if: github.repository == 'langgenius/dify' permissions: contents: read id-token: write strategy: matrix: include: - service_name: 'build-api-amd64' image_name_env: 'DIFY_API_IMAGE_NAME' artifact_context: 'api' build_context: '{{defaultContext}}' file: 'api/Dockerfile' platform: linux/amd64 runs_on: depot-ubuntu-24.04-4 - service_name: 'build-api-arm64' image_name_env: 'DIFY_API_IMAGE_NAME' artifact_context: 'api' build_context: '{{defaultContext}}' file: 'api/Dockerfile' platform: linux/arm64 runs_on: depot-ubuntu-24.04-4 - service_name: 'build-web-amd64' image_name_env: 'DIFY_WEB_IMAGE_NAME' artifact_context: 'web' build_context: '{{defaultContext}}' file: 'web/Dockerfile' platform: linux/amd64 runs_on: depot-ubuntu-24.04-4 - service_name: 'build-web-arm64' image_name_env: 'DIFY_WEB_IMAGE_NAME' artifact_context: 'web' build_context: '{{defaultContext}}' file: 'web/Dockerfile' platform: linux/arm64 runs_on: depot-ubuntu-24.04-4 - service_name: 'build-agent-amd64' image_name_env: 'DIFY_AGENT_IMAGE_NAME' artifact_context: 'agent' build_context: '{{defaultContext}}' file: 'dify-agent/Dockerfile' platform: linux/amd64 runs_on: depot-ubuntu-24.04-4 - service_name: 'build-agent-arm64' image_name_env: 'DIFY_AGENT_IMAGE_NAME' artifact_context: 'agent' build_context: '{{defaultContext}}' file: 'dify-agent/Dockerfile' platform: linux/arm64 runs_on: depot-ubuntu-24.04-4 - service_name: 'build-agent-local-sandbox-amd64' image_name_env: 'DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME' artifact_context: 'local-sandbox' build_context: '{{defaultContext}}:dify-agent-runtime' file: 'docker/Dockerfile' platform: linux/amd64 runs_on: depot-ubuntu-24.04-4 - service_name: 'build-agent-local-sandbox-arm64' image_name_env: 'DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME' artifact_context: 'local-sandbox' build_context: '{{defaultContext}}:dify-agent-runtime' file: 'docker/Dockerfile' platform: linux/arm64 runs_on: depot-ubuntu-24.04-4 steps: - name: Prepare run: | platform=${{ matrix.platform }} echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Login to Docker Hub uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: username: ${{ env.DOCKERHUB_USER }} password: ${{ env.DOCKERHUB_TOKEN }} - name: Set up Depot CLI uses: depot/setup-action@91bc8495a33ebfc504ffc89e5674379ccf23c29c # v1.7.2 - name: Extract metadata for Docker id: meta uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 with: images: ${{ env[matrix.image_name_env] }} - name: Build Docker image id: build uses: depot/build-push-action@98e78adca7817480b8185f474a400b451d74e287 # v1.18.0 with: project: ${{ vars.DEPOT_PROJECT_ID }} context: ${{ matrix.build_context }} file: ${{ matrix.file }} platforms: ${{ matrix.platform }} build-args: COMMIT_SHA=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} build-contexts: ${{ matrix.build_contexts }} labels: ${{ steps.meta.outputs.labels }} outputs: type=image,name=${{ env[matrix.image_name_env] }},push-by-digest=true,name-canonical=true,push=true - name: Export digest env: DIGEST: ${{ steps.build.outputs.digest }} run: | mkdir -p /tmp/digests sanitized_digest=${DIGEST#sha256:} touch "/tmp/digests/${sanitized_digest}" - name: Upload digest uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: digests-${{ matrix.artifact_context }}-${{ env.PLATFORM_PAIR }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 fork-build-validate: if: github.repository != 'langgenius/dify' runs-on: ubuntu-24.04 strategy: matrix: include: - service_name: 'validate-api-amd64' build_context: '{{defaultContext}}' file: 'api/Dockerfile' - service_name: 'validate-web-amd64' build_context: '{{defaultContext}}' file: 'web/Dockerfile' - service_name: 'validate-agent-amd64' build_context: '{{defaultContext}}' file: 'dify-agent/Dockerfile' - service_name: 'validate-agent-local-sandbox-amd64' build_context: '{{defaultContext}}:dify-agent-runtime' file: 'docker/Dockerfile' steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 - name: Validate Docker image uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 with: push: false context: ${{ matrix.build_context }} file: ${{ matrix.file }} build-contexts: ${{ matrix.build_contexts }} platforms: linux/amd64 create-manifest: needs: build runs-on: depot-ubuntu-24.04 if: github.repository == 'langgenius/dify' strategy: matrix: include: - service_name: 'merge-api-images' image_name_env: 'DIFY_API_IMAGE_NAME' context: 'api' - service_name: 'merge-web-images' image_name_env: 'DIFY_WEB_IMAGE_NAME' context: 'web' - service_name: 'merge-agent-images' image_name_env: 'DIFY_AGENT_IMAGE_NAME' context: 'agent' - service_name: 'merge-agent-local-sandbox-images' image_name_env: 'DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME' context: 'local-sandbox' steps: - name: Download digests uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: /tmp/digests pattern: digests-${{ matrix.context }}-* merge-multiple: true - name: Login to Docker Hub uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: username: ${{ env.DOCKERHUB_USER }} password: ${{ env.DOCKERHUB_TOKEN }} - name: Extract metadata for Docker id: meta uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 with: images: ${{ env[matrix.image_name_env] }} tags: | type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref, '-') }} type=ref,event=branch type=sha,enable=true,priority=100,prefix=,suffix=,format=long type=raw,value=${{ github.ref_name }},enable=${{ startsWith(github.ref, 'refs/tags/') }} - name: Create manifest list and push working-directory: /tmp/digests env: IMAGE_NAME: ${{ env[matrix.image_name_env] }} run: | docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ $(printf "$IMAGE_NAME@sha256:%s " *) - name: Inspect image env: IMAGE_NAME: ${{ env[matrix.image_name_env] }} IMAGE_VERSION: ${{ steps.meta.outputs.version }} run: | docker buildx imagetools inspect "$IMAGE_NAME:$IMAGE_VERSION" sync-e2b-template: needs: create-manifest runs-on: ubuntu-24.04 if: github.repository == 'langgenius/dify' && startsWith(github.ref, 'refs/tags/') strategy: matrix: include: - project: dev api_key_secret: E2B_API_KEY_DEV - project: prod api_key_secret: E2B_API_KEY_PROD steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Docker Buildx uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 - name: Login to Docker Hub uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: username: ${{ env.DOCKERHUB_USER }} password: ${{ env.DOCKERHUB_TOKEN }} - name: Sync E2B Template (${{ matrix.project }}) env: E2B_API_KEY: ${{ secrets[matrix.api_key_secret] }} run: ./dify-agent-runtime/docker/sync-e2b-template.sh