Skip to content

Commit 21fc552

Browse files
Merge pull request #149 from depot/docs-sync-updates
Update content from depot/app
2 parents 3e61444 + 569d6dc commit 21fc552

21 files changed

+1984
-263
lines changed

content/cache/reference/turbo.mdx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,50 @@ export TURBO_TEAM=DEPOT_ORG_ID
3131
## Using Depot Cache with Turborepo
3232

3333
Once Turborepo is configured to use Depot Cache, you can then run your builds as you normally would. Turborepo will automatically communicate with Depot Cache to fetch and reuse any stored build artifacts from your previous builds.
34+
35+
### Using Depot Cache with Turborepo in container builds
36+
37+
Container builds with `depot/build-push-action` don't automatically connect to Depot Cache. Unlike Depot GitHub Actions runners, container builds run on separate VMs and require manual configuration.
38+
39+
You need to pass Turborepo credentials as build secrets (not build arguments) to your container build for the following reasons:
40+
41+
- Build secrets avoid cache invalidation because the values of `TURBO_API` and `TURBO_TOKEN` change.
42+
- Build secrets keep tokens secure and prevent them from persisting in the final image.
43+
44+
Follow these steps to add your Turborepo credentials as build secrets.
45+
46+
1. Create GitHub Secrets for your Turborepo cache variables:
47+
- `TURBO_API`
48+
- `TURBO_TOKEN`
49+
- `TURBO_TEAM`
50+
51+
2. Configure your GitHub Action to pass secrets to the container build:
52+
53+
```yaml
54+
- name: Build and push
55+
uses: depot/build-push-action@v1
56+
with:
57+
context: .
58+
file: ./Dockerfile
59+
push: true
60+
tags: your-image:tag
61+
secrets: |
62+
"TURBO_API=${{ secrets.TURBO_API }}"
63+
"TURBO_TOKEN=${{ secrets.TURBO_TOKEN }}"
64+
"TURBO_TEAM=${{ secrets.TURBO_TEAM }}"
65+
```
66+
67+
3. Update your Dockerfile to mount the secrets as environment variables:
68+
69+
```dockerfile
70+
syntax=docker/dockerfile:1
71+
# ^ Required to use secret mounts with environment variables
72+
73+
# ... other Dockerfile instructions
74+
75+
# Mount secrets with IDs matching the environment variable names
76+
RUN --mount=type=secret,id=TURBO_API,env=TURBO_API \
77+
--mount=type=secret,id=TURBO_TOKEN,env=TURBO_TOKEN \
78+
--mount=type=secret,id=TURBO_TEAM,env=TURBO_TEAM \
79+
turbo build
80+
```
Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,40 @@
11
---
2-
title: Best practice Dockerfiles
3-
ogTitle: Best practice Dockerfiles
4-
description: A set of best practice Dockerfiles for building Docker images
2+
title: Optimal Dockerfiles
3+
ogTitle: Optimal Dockerfiles
4+
description: A set of optimal Dockerfiles for building Docker images
55
---
66

7-
We've assembled some best practice Dockerfiles for building Docker images for several different languages:
7+
The following guides provide optimal Dockerfiles that are tailored for Depot container build cache and your preferred programming language. You can use these Dockerfiles as reference implementations or starting points for your own projects.
8+
9+
If you already have a Dockerfile and want to optimize it for your Depot builds, refer to the _Understanding BuildKit Cache Mounts_ section in each guide. This section explains:
10+
11+
- How to add cache mounts to your existing `RUN` commands
12+
- Cache mount parameters (`id`, `target`, `sharing`)
13+
- Language-specific cache strategies and optimization techniques
14+
15+
The cache mount integration is the core enhancement that makes builds significantly faster on Depot, and these sections provide everything you need to retrofit your existing Dockerfiles. For more in-depth information on BuildKit cache mounts, please refer to the blog post [How to use cache mounts to speed up Docker builds](https://depot.dev/blog/how-to-use-cache-mount-to-speed-up-docker-builds).
816

917
## Guides
1018

11-
- [Dockerfile for Node.js using `pnpm`](/docs/container-builds/how-to-guides/optimal-dockerfiles/node-pnpm-dockerfile)
12-
- [Dockerfile for Python using `uv`](/docs/container-builds/how-to-guides/optimal-dockerfiles/python-uv-dockerfile)
13-
- [Dockerfile for Python using `poetry`](/docs/container-builds/how-to-guides/optimal-dockerfiles/python-poetry-dockerfile)
19+
### Node.js
20+
21+
- [Node.js Dockerfiles](/docs/container-builds/how-to-guides/optimal-dockerfiles/node)
22+
23+
### Python
24+
25+
- [Python Dockerfiles](/docs/container-builds/how-to-guides/optimal-dockerfiles/python)
26+
27+
### Java
28+
29+
- [Java Dockerfiles](/docs/container-builds/how-to-guides/optimal-dockerfiles/java)
30+
31+
### .NET
32+
33+
- [.NET Dockerfiles](/docs/container-builds/how-to-guides/optimal-dockerfiles/dotnet)
34+
35+
### Other Languages
36+
37+
- [Dockerfile for Go](/docs/container-builds/how-to-guides/optimal-dockerfiles/go-dockerfile)
38+
- [Dockerfile for PHP using Composer](/docs/container-builds/how-to-guides/optimal-dockerfiles/php-composer-dockerfile)
39+
- [Dockerfile for Ruby using Bundler](/docs/container-builds/how-to-guides/optimal-dockerfiles/ruby-bundler-dockerfile)
1440
- [Dockerfile for Rust](/docs/container-builds/how-to-guides/optimal-dockerfiles/rust-dockerfile)
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
---
2+
title: Optimal Dockerfile for .NET ASP.NET Core
3+
ogTitle: Optimal Dockerfile for .NET ASP.NET Core
4+
description: A sample optimal Dockerfile for building images for .NET ASP.NET Core applications from us at Depot.
5+
---
6+
7+
Below is an example `Dockerfile` that we recommend at Depot for building images for .NET ASP.NET Core applications.
8+
9+
```dockerfile
10+
# syntax=docker/dockerfile:1
11+
12+
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
13+
14+
WORKDIR /src
15+
16+
COPY src/WebApp/WebApp.csproj src/WebApp/
17+
COPY src/WebApp.Core/WebApp.Core.csproj src/WebApp.Core/
18+
COPY Directory.Build.props ./
19+
COPY *.sln ./
20+
21+
RUN --mount=type=cache,target=/root/.nuget/packages \
22+
--mount=type=cache,target=/root/.local/share/NuGet/v3-cache \
23+
--mount=type=cache,target=/root/.local/share/NuGet/plugins-cache \
24+
--mount=type=cache,target=/tmp/NuGetScratchroot \
25+
dotnet restore
26+
27+
COPY src/ src/
28+
29+
RUN --mount=type=cache,target=/root/.nuget/packages \
30+
--mount=type=cache,target=/root/.local/share/NuGet/v3-cache \
31+
--mount=type=cache,target=/root/.local/share/NuGet/plugins-cache \
32+
--mount=type=cache,target=/tmp/NuGetScratchroot \
33+
dotnet publish "src/WebApp/WebApp.csproj" \
34+
--no-restore \
35+
--configuration Release \
36+
--output /app/publish
37+
38+
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
39+
40+
RUN groupadd -g 1001 appgroup && \
41+
useradd -u 1001 -g appgroup -m -d /app -s /bin/false appuser
42+
43+
WORKDIR /app
44+
45+
COPY --from=build --chown=appuser:appgroup /app/publish .
46+
47+
USER appuser
48+
49+
ENV DOTNET_RUNNING_IN_CONTAINER=true \
50+
DOTNET_EnableDiagnostics=0 \
51+
HTTP_PORT=8080 \
52+
ASPNETCORE_ENVIRONMENT=Production
53+
54+
ENTRYPOINT ["dotnet", "WebApp.dll"]
55+
```
56+
57+
## Explanation of the Dockerfile
58+
59+
At a high level, here are the things we're optimizing in our Docker build for a .NET ASP.NET Core application:
60+
61+
- Multi-stage builds for smaller final images
62+
- NuGet cache mounts for dependency caching
63+
- Security optimizations with non-root users
64+
- Production-optimized ASP.NET Core configuration
65+
66+
### Stage 1: `FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build`
67+
68+
```dockerfile
69+
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
70+
71+
WORKDIR /src
72+
```
73+
74+
We use the official .NET 8 SDK image for the build stage, providing all necessary tools for compilation and publishing.
75+
76+
#### Project file and dependency restoration
77+
78+
```dockerfile
79+
COPY src/WebApp/WebApp.csproj src/WebApp/
80+
COPY src/WebApp.Core/WebApp.Core.csproj src/WebApp.Core/
81+
COPY Directory.Build.props ./
82+
COPY *.sln ./
83+
84+
RUN --mount=type=cache,target=/root/.nuget/packages \
85+
--mount=type=cache,target=/root/.local/share/NuGet/v3-cache \
86+
--mount=type=cache,target=/root/.local/share/NuGet/plugins-cache \
87+
--mount=type=cache,target=/tmp/NuGetScratchroot \
88+
dotnet restore
89+
```
90+
91+
We copy only the project files and solution file first for optimal layer caching. This pattern ensures that package restoration only runs when dependencies change, not when source code changes. The cache mount persists NuGet packages between builds.
92+
93+
#### Source code and publishing
94+
95+
```dockerfile
96+
COPY src/ src/
97+
98+
RUN --mount=type=cache,target=/root/.nuget/packages \
99+
--mount=type=cache,target=/root/.local/share/NuGet/v3-cache \
100+
--mount=type=cache,target=/root/.local/share/NuGet/plugins-cache \
101+
--mount=type=cache,target=/tmp/NuGetScratchroot \
102+
dotnet publish "src/WebApp/WebApp.csproj" \
103+
--no-restore \
104+
--configuration Release \
105+
--output /app/publish
106+
```
107+
108+
After copying the source code, we publish the application:
109+
110+
- `--no-restore` skips restoration since we've already restored packages
111+
- `--configuration Release` builds in release mode for production
112+
- `--output /app/publish` specifies the output directory for the published files
113+
114+
### Stage 2: `FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime`
115+
116+
```dockerfile
117+
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
118+
119+
RUN groupadd -g 1001 appgroup && \
120+
useradd -u 1001 -g appgroup -m -d /app -s /bin/false appuser
121+
122+
WORKDIR /app
123+
124+
COPY --from=build --chown=appuser:appgroup /app/publish .
125+
```
126+
127+
The runtime stage uses the ASP.NET Core runtime image, which is much smaller than the SDK. We create a non-root user for security and copy only the published application files.
128+
129+
#### Runtime configuration
130+
131+
```dockerfile
132+
USER appuser
133+
134+
ENV DOTNET_RUNNING_IN_CONTAINER=true \
135+
DOTNET_EnableDiagnostics=0 \
136+
HTTP_PORT=8080 \
137+
ASPNETCORE_ENVIRONMENT=Production
138+
139+
ENTRYPOINT ["dotnet", "WebApp.dll"]
140+
```
141+
142+
We configure the runtime environment:
143+
144+
- Run as non-root user for security
145+
- `DOTNET_RUNNING_IN_CONTAINER=true` enables container-optimized settings
146+
- `DOTNET_EnableDiagnostics=0` disables diagnostics for production
147+
- `HTTP_PORT=8080` sets the HTTP port
148+
- `ASPNETCORE_ENVIRONMENT=Production` sets the environment
149+
150+
## Understanding BuildKit Cache Mounts
151+
152+
Cache mounts are one of the most powerful features for optimizing Docker builds with Depot. This Dockerfile uses the following cache mount syntax:
153+
154+
```dockerfile
155+
RUN --mount=type=cache,target=/root/.nuget/packages \
156+
--mount=type=cache,target=/root/.local/share/NuGet/v3-cache \
157+
--mount=type=cache,target=/root/.local/share/NuGet/plugins-cache \
158+
--mount=type=cache,target=/tmp/NuGetScratchroot \
159+
dotnet restore
160+
```
161+
162+
### Cache Mount Parameters Explained
163+
164+
- **`type=cache`**: Specifies this is a cache mount that persists across builds.
165+
166+
- **Multiple cache targets**:
167+
- **`/root/.nuget/packages`**: Global NuGet package cache
168+
- **`/root/.local/share/NuGet/v3-cache`**: NuGet v3 API cache
169+
- **`/root/.local/share/NuGet/plugins-cache`**: NuGet plugins cache
170+
- **`/tmp/NuGetScratchroot`**: Temporary extraction directory
171+
172+
For more information regarding NuGet cache mounts, please visit the official [Microsoft documentation](https://learn.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders).

0 commit comments

Comments
 (0)