diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8a4ecceb14..dfb31f064a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -397,6 +397,7 @@ jobs: runs-on: ${{ matrix.runner }} permissions: contents: read + packages: write defaults: run: working-directory: ./e2e @@ -440,8 +441,33 @@ jobs: run: pnpm install --frozen-lockfile if: ${{ !cancelled() }} + - name: Setup Buildx + uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 + + - name: Login to GitHub Container Registry + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + if: ${{ github.event_name == 'push' && !github.event.pull_request.head.repo.fork }} + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Resolve build cache + id: cache + run: | + ref=ghcr.io/immich-app/immich-server-build-cache:e2e-main-${{ runner.arch }} + echo "ref=$ref" >> "$GITHUB_OUTPUT" + if docker buildx imagetools inspect "$ref" > /dev/null 2>&1; then + echo "from=type=registry,ref=$ref" >> "$GITHUB_OUTPUT" + else + echo "from=" >> "$GITHUB_OUTPUT" + fi + - name: Start Docker Compose id: docker + env: + E2E_CACHE_FROM: ${{ steps.cache.outputs.from }} + E2E_CACHE_TO: ${{ github.event_name == 'push' && !github.event.pull_request.head.repo.fork && format('type=registry,ref={0},mode=max', steps.cache.outputs.ref) || '' }} run: docker compose up -d --build --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 if: ${{ !cancelled() }} @@ -519,8 +545,24 @@ jobs: run: pnpm exec playwright install chromium --only-shell if: ${{ !cancelled() }} + - name: Setup Buildx + uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 + + - name: Resolve build cache + id: cache + run: | + ref=ghcr.io/immich-app/immich-server-build-cache:e2e-main-${{ runner.arch }} + echo "ref=$ref" >> "$GITHUB_OUTPUT" + if docker buildx imagetools inspect "$ref" > /dev/null 2>&1; then + echo "from=type=registry,ref=$ref" >> "$GITHUB_OUTPUT" + else + echo "from=" >> "$GITHUB_OUTPUT" + fi + - name: Docker build id: docker + env: + E2E_CACHE_FROM: ${{ steps.cache.outputs.from }} run: docker compose up -d --build --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 if: ${{ !cancelled() }} diff --git a/e2e/docker-compose.yml b/e2e/docker-compose.yml index 7c03cea653..bf9c62087f 100644 --- a/e2e/docker-compose.yml +++ b/e2e/docker-compose.yml @@ -16,8 +16,9 @@ services: context: ../ dockerfile: server/Dockerfile cache_from: - - type=registry,ref=ghcr.io/immich-app/immich-server-build-cache:linux-amd64-cc099f297acd18c924b35ece3245215b53d106eb2518e3af6415931d055746cd-main - - type=registry,ref=ghcr.io/immich-app/immich-server-build-cache:linux-arm64-cc099f297acd18c924b35ece3245215b53d106eb2518e3af6415931d055746cd-main + - ${E2E_CACHE_FROM:-} + cache_to: + - ${E2E_CACHE_TO:-} args: - BUILD_ID=1234567890 - BUILD_IMAGE=e2e diff --git a/server/Dockerfile b/server/Dockerfile index 5d604f6d23..419c650653 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -9,17 +9,16 @@ RUN npm install --global corepack@latest && \ corepack enable pnpm && \ pnpm config set store-dir "$PNPM_HOME" +WORKDIR /usr/src/app + +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .pnpmfile.cjs ./ + FROM builder AS server -WORKDIR /usr/src/app COPY ./server ./server/ COPY ./packages/sdk ./packages/sdk/ COPY ./packages/plugin-sdk ./packages/plugin-sdk/ RUN --mount=type=cache,id=pnpm-server,target=/buildcache/pnpm-store \ - --mount=type=bind,source=package.json,target=package.json \ - --mount=type=bind,source=.pnpmfile.cjs,target=.pnpmfile.cjs \ - --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ - --mount=type=bind,source=pnpm-workspace.yaml,target=pnpm-workspace.yaml \ pnpm --filter @immich/sdk --filter @immich/plugin-sdk --filter immich build && \ pnpm --filter immich --prod --no-optional deploy /output/server-pruned && \ SHARP_FORCE_GLOBAL_LIBVIPS=true pnpm --dir /output/server-pruned/node_modules/sharp exec npm run build @@ -29,26 +28,18 @@ FROM builder AS web ARG BUILD_ID ENV IMMICH_BUILD=${BUILD_ID} -WORKDIR /usr/src/app COPY ./web ./web/ COPY ./i18n ./i18n/ -COPY ./packages ./packages/ +COPY ./packages/sdk ./packages/sdk/ RUN --mount=type=cache,id=pnpm-web,target=/buildcache/pnpm-store \ - --mount=type=bind,source=package.json,target=package.json \ - --mount=type=bind,source=.pnpmfile.cjs,target=.pnpmfile.cjs \ - --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ - --mount=type=bind,source=pnpm-workspace.yaml,target=pnpm-workspace.yaml \ - pnpm --filter @immich/sdk --filter immich-web install --frozen-lockfile --force && \ + pnpm --filter @immich/sdk --filter immich-web install --frozen-lockfile && \ pnpm --filter @immich/sdk --filter immich-web build FROM builder AS cli -COPY ./packages ./packages/ +COPY ./packages/sdk ./packages/sdk/ +COPY ./packages/cli ./packages/cli/ RUN --mount=type=cache,id=pnpm-cli,target=/buildcache/pnpm-store \ - --mount=type=bind,source=package.json,target=package.json \ - --mount=type=bind,source=.pnpmfile.cjs,target=.pnpmfile.cjs \ - --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ - --mount=type=bind,source=pnpm-workspace.yaml,target=pnpm-workspace.yaml \ pnpm --filter @immich/sdk --filter @immich/cli install --frozen-lockfile && \ pnpm --filter @immich/sdk --filter @immich/cli build && \ pnpm --filter @immich/cli --prod --no-optional deploy /output/cli-pruned @@ -59,11 +50,10 @@ ARG TARGETPLATFORM COPY --from=ghcr.io/jdx/mise:2026.8.8@sha256:638270210fb690efc0a8492b2c173d51bee6cb33f26381f05790d90c8e646a80 /usr/local/bin/mise /usr/local/bin/mise -WORKDIR /app COPY ./mise.toml ./mise.toml COPY ./mise.lock ./mise.lock COPY ./packages/plugin-core/mise.toml ./packages/plugin-core/ -ENV MISE_TRUSTED_CONFIG_PATHS=/app/mise.toml +ENV MISE_TRUSTED_CONFIG_PATHS=/usr/src/app/mise.toml ENV MISE_DATA_DIR=/buildcache/mise ENV MISE_DISABLE_TOOLS=flutter RUN --mount=type=cache,id=mise-tools-${TARGETPLATFORM},target=/buildcache/mise \ @@ -75,10 +65,6 @@ COPY ./packages/plugin-sdk ./packages/plugin-sdk/ # Build plugins RUN --mount=type=cache,id=pnpm-packages,target=/buildcache/pnpm-store \ - --mount=type=bind,source=package.json,target=package.json \ - --mount=type=bind,source=.pnpmfile.cjs,target=.pnpmfile.cjs \ - --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ - --mount=type=bind,source=pnpm-workspace.yaml,target=pnpm-workspace.yaml \ --mount=type=cache,id=mise-tools-${TARGETPLATFORM},target=/buildcache/mise \ mise //:plugins @@ -92,8 +78,8 @@ ENV NODE_ENV=production \ COPY --from=server /output/server-pruned ./server COPY --from=web /usr/src/app/web/build /build/www COPY --from=cli /output/cli-pruned ./cli -COPY --from=plugins /app/packages/plugin-core/dist /build/plugins/immich-plugin-core/dist -COPY --from=plugins /app/packages/plugin-core/manifest.json /build/plugins/immich-plugin-core/manifest.json +COPY --from=plugins /usr/src/app/packages/plugin-core/dist /build/plugins/immich-plugin-core/dist +COPY --from=plugins /usr/src/app/packages/plugin-core/manifest.json /build/plugins/immich-plugin-core/manifest.json RUN ln -s ../../cli/bin/immich server/bin/immich COPY LICENSE /licenses/LICENSE.txt COPY LICENSE /LICENSE