Multistage & Layers
Previously, in Topic 2, Working with Code, we have dockerfile to create isolated DEV environment, but we still have to manually dotnet new/build/run
Target: Use multistage dockerfile to automatically setup DEV & PROD environment, where we only need to modify source code.
What is Docker Image Layering?
dockerfile lay layers on top of another. So often changed layers should be in bottom to save image building time
General DEV + PROD multistage dockerfile structure
######## Dev stage #########
# Start from a base image (Layer 1)
FROM base-SDK-image-here
# install dependencies (Layer 2)
RUN pip install \npm install \go get
# Copy source code into image (Layer 3)
COPY source
# Run assembly to build app based on source code (Layer 4)
RUN build
Above is the dockerfile for a development environment. To product ready, we can use multistage. By giving above codes an alias, we can build multi-stage images
continue dockerfile
####### Runtime stage #########
# Using a runtime image instead of full SDK (Layer 5)
FROM another-image
# Copy compiled app into runtime image to save space (Layer 6)
COPY output-from-stage-1
# Start app or entrypoint
RUN application
Benefit of this multistage, we can use debug tools in dev stage, but also keep product small in stage 2
Modify dockerfile and docker-compose for multistage building
Add build target in docker-compose
Adding build target in build
, so docker-compose can be directly used to create DEV/PROD image.
build:
context: ./c#
target: dev
Modify dockerfile
############# DEV IMAGE #################
# Define a dev stage using `as`
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch as dev
# Defining a working directory
RUN mkdir /app/
WORKDIR /app/
# ????
COPY ./src/work.csproj /app/work.csproj
RUN dotnet restore
# Copy the remaining source file
COPY ./src/ /app/
RUN mkdir /out/
RUN dotnet publish --no-restore --output /out/ --configuration Release
############## PRODUCT IMAGE #############
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch-slim as prod
RUN mkdir /app/
WORKDIR /app/
# Copy binary into folder
COPY --from=dev /out/ /app/
RUN chmod +x /app/
CMD dotnet work.dll