Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/docker-layer-caching.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@cloudflare/sandbox': patch
---

Add cache mounts to Dockerfile for faster builds

Adds cache mounts for npm, apt, and pip package managers in the Dockerfile. This speeds up Docker image builds when dependencies change, particularly beneficial for users building from source.
17 changes: 15 additions & 2 deletions .github/workflows/pkg-pr-new.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ on:
jobs:
publish-preview:
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 15

steps:
- name: Checkout code
Expand Down Expand Up @@ -73,7 +73,20 @@ jobs:
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Build and push Docker image (preview)
run: npm run docker:publish --workspace=@cloudflare/sandbox
uses: docker/build-push-action@v6
with:
context: .
file: packages/sandbox/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: cloudflare/sandbox:${{ steps.package-version.outputs.version }}
cache-from: |
type=gha,scope=preview-pr-${{ github.event.pull_request.number }}
type=gha,scope=pr-${{ github.event.pull_request.number }}
type=gha,scope=release
cache-to: type=gha,mode=max,scope=preview-pr-${{ github.event.pull_request.number }}
build-args: |
SANDBOX_VERSION=${{ steps.package-version.outputs.version }}

- name: Publish to pkg.pr.new
run: npx pkg-pr-new publish './packages/sandbox'
Expand Down
27 changes: 25 additions & 2 deletions .github/workflows/pullrequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
unit-tests:
timeout-minutes: 10
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get-version.outputs.version }}
steps:
- uses: actions/checkout@v4

Expand All @@ -33,6 +35,12 @@ jobs:
- name: Build packages
run: npm run build

- name: Get package version
id: get-version
run: |
VERSION=$(node -p "require('./packages/sandbox/package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Run sandbox unit tests
run: |
set +e
Expand Down Expand Up @@ -64,6 +72,7 @@ jobs:

# E2E tests against deployed worker
e2e-tests:
needs: unit-tests
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -102,9 +111,23 @@ jobs:
cd tests/e2e/test-worker
./generate-config.sh ${{ steps.env-name.outputs.worker_name }}

# Build Docker image for test worker (needed before deployment)
# Build Docker image for test worker with caching
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build test worker Docker image
run: npm run docker:local -w @cloudflare/sandbox
uses: docker/build-push-action@v6
with:
context: .
file: packages/sandbox/Dockerfile
load: true # Load into Docker daemon for local testing
tags: cloudflare/sandbox-test:${{ needs.unit-tests.outputs.version || '0.0.0' }}
cache-from: |
type=gha,scope=pr-${{ github.event.pull_request.number }}
type=gha,scope=release
cache-to: type=gha,mode=max,scope=pr-${{ github.event.pull_request.number }}
build-args: |
SANDBOX_VERSION=${{ needs.unit-tests.outputs.version || '0.0.0' }}

# Deploy test worker using official Cloudflare action
- name: Deploy test worker
Expand Down
32 changes: 30 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
if: ${{ github.repository_owner == 'cloudflare' }}
runs-on: ubuntu-latest
timeout-minutes: 10
outputs:
version: ${{ steps.get-version.outputs.version }}

steps:
- uses: actions/checkout@v4
Expand All @@ -34,6 +36,12 @@ jobs:
- name: Build packages
run: npm run build

- name: Get package version
id: get-version
run: |
VERSION=$(node -p "require('./packages/sandbox/package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Run sandbox unit tests
run: |
set +e
Expand Down Expand Up @@ -106,7 +114,17 @@ jobs:
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Build and push Docker image (beta)
run: npm run docker:publish:beta --workspace=@cloudflare/sandbox
uses: docker/build-push-action@v6
with:
context: .
file: packages/sandbox/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: cloudflare/sandbox:${{ needs.unit-tests.outputs.version }}-beta
cache-from: type=gha,scope=release
cache-to: type=gha,mode=max,scope=release
build-args: |
SANDBOX_VERSION=${{ needs.unit-tests.outputs.version }}

- name: Publish to npm with beta tag
run: npm publish --tag beta --access public
Expand Down Expand Up @@ -153,7 +171,17 @@ jobs:
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Build and push Docker image
run: npm run docker:publish --workspace=@cloudflare/sandbox
uses: docker/build-push-action@v6
with:
context: .
file: packages/sandbox/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: cloudflare/sandbox:${{ needs.unit-tests.outputs.version }}
cache-from: type=gha,scope=release
cache-to: type=gha,mode=max,scope=release
build-args: |
SANDBOX_VERSION=${{ needs.unit-tests.outputs.version }}

- id: changesets
uses: changesets/action@v1
Expand Down
24 changes: 15 additions & 9 deletions packages/sandbox/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ WORKDIR /app
COPY --from=pruner /app/out/json/ .
COPY --from=pruner /app/out/package-lock.json ./package-lock.json

# Install ALL dependencies (including devDependencies for build)
RUN npm ci
# Install ALL dependencies with cache mount for npm packages
RUN --mount=type=cache,target=/root/.npm \
npm ci

# Copy pruned source code
COPY --from=pruner /app/out/full/ .
Expand All @@ -53,7 +54,8 @@ COPY --from=builder /app/packages ./packages
COPY --from=builder /app/tooling ./tooling

# Install ONLY production dependencies (excludes typescript, @types/*, etc.)
RUN npm ci --production
RUN --mount=type=cache,target=/root/.npm \
npm ci --production

# ============================================================================
# Stage 4: Runtime - Ubuntu 22.04 with only runtime dependencies
Expand All @@ -69,8 +71,12 @@ ENV DEBIAN_FRONTEND=noninteractive
# Set the sandbox version as an environment variable for version checking
ENV SANDBOX_VERSION=${SANDBOX_VERSION}

# Install essential runtime packages
RUN apt-get update && apt-get install -y --no-install-recommends \
# Install essential runtime packages with cache mounts
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
rm -f /etc/apt/apt.conf.d/docker-clean && \
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache && \
apt-get update && apt-get install -y --no-install-recommends \
curl \
wget \
ca-certificates \
Expand All @@ -82,8 +88,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
unzip \
zip \
jq \
file \
&& rm -rf /var/lib/apt/lists/*
file

# Set Python 3.11 as default python3
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
Expand All @@ -96,8 +101,9 @@ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
# Install Bun runtime from official image
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun

# Install essential Python packages for code execution
RUN pip3 install --no-cache-dir \
# Install essential Python packages with cache mount
RUN --mount=type=cache,target=/root/.cache/pip \
pip3 install \
matplotlib \
numpy \
pandas \
Expand Down
Loading