Multi-stage Docker builds help make Docker images smaller and safer by splitting the build area from the runtime area. Here's an example of multi-stage Dockerization for a Deno.js app. This example thinks you have a Deno.js app with a file called app.ts
as your starting point.
# Stage 1: Build Stage
FROM hayd/alpine-deno:1.15.3 as builder
WORKDIR /app
# Copy only the necessary files for downloading dependencies
COPY deps.ts .
RUN deno cache --unstable deps.ts
# Copy the rest of the application source code
COPY . .
# Compile the Deno application
RUN deno cache --unstable --unstable --import-map=import_map.json app.ts
# Stage 2: Runtime Stage
FROM hayd/alpine-deno:1.15.3
WORKDIR /app
# Copy only the compiled application from the builder stage
COPY --from=builder /app/app.ts /app/
# Expose the necessary port
EXPOSE 8080
# Run the Deno application
CMD ["deno", "run", "--unstable", "--allow-net", "app.ts"]
Explanation:
Stage 1 (Build Stage):
Uses the
hayd/alpine-deno
image as a base image for building the Deno application.Copies only the
deps.ts
file to leverage Docker caching for faster builds.Downloads the dependencies using
deno cache
.Copies the rest of the application source code.
Compiles the Deno application using
deno cache
.
Stage 2 (Runtime Stage):
Starts with a fresh
hayd/alpine-deno
base image for the runtime environment.Copies only the compiled
app.ts
file from the build stage, omitting unnecessary files and dependencies.Exposes the necessary port (e.g., 8080) that the Deno application might be using.
Specifies the
CMD
to run the Deno application.
This setup creates a Docker image with just the compiled Deno app and its needed parts, making the image smaller. The Deno runtime is only in the runtime stage, which makes the image safer.
Remember to change the --allow-net
flag or other Deno permissions based on your app's needs. Also, Deno is still changing, so you might need flags like --unstable
for features that aren't stable yet. Always look at the Deno documentation for the newest best practices.