Search code examples
dockerdockerfile

Ensure source code not included in Docker Image


I am trying to build a Github Action that automatically compiles and publishes my dotnet core container and pushes the image to our Container Registry. Below is my Github Action file. How do I ensure that the C# source code is not embedded into the container image?

name: .NET Build and Publish to GitHub Packages on Release

on:
  release:
    types: [created]
  push:
    branches:
      - main # Trigger on pushes to the main branch

permissions:
  contents: read
  packages: write  # Explicitly grant write permission for packages

jobs:
  build_and_publish:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup .NET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: 8.0.x

    - name: Restore dependencies
      run: dotnet restore

    - name: Build
      run: dotnet build --no-restore -c Release

    - name: Publish
      run: dotnet publish --no-build -c Release -o ./out

    # Docker Build steps removed (WIP)

    - name: Login to GitHub Container Registry
      uses: docker/login-action@v2
      with:
        registry: ghcr.io
        username: ${{ github.repository_owner }}
        password: ${{ secrets.GITHUB_TOKEN }}

Below is my Dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:8.0

COPY ./out .
ENTRYPOINT ["dotnet", "my.app.dll"]

Solution

  • Below is the Dockerfile I ended up with.

    In my example, my Dockerfile is in the root of the project folder. My source code is under the /src directory.

    In this example, Docker will copy the contents of /src into context. Build and publish the application to /app. Then, build the docker image using the contents of /app, which will only contain compiled code.

    Note: In my example below, I have logs being written to a /logs directory. Because I include the /logs directory in my repo, I am creating the directory when the container is run. That way the /logs directory is ready for NLog to write to.

    FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
    WORKDIR /source
    
    # copy csproj and restore as distinct layers
    COPY ./src .
    RUN dotnet restore
    
    # publish app and libraries
    RUN dotnet publish -c release -o /app
    
    # final stage
    FROM mcr.microsoft.com/dotnet/aspnet:8.0
    WORKDIR /app
    COPY --from=build /app .
    ENTRYPOINT [ "sh", "-c", "mkdir -p ./logs && dotnet my.app.dll" ]