Hi everyone, in today's post we are going to talk about how to create images and publish to GitHub Container Registry using GitHub Actions.
Base Knowledge
For a deeper understanding of the subject, it's advisable to understand the concepts of Docker and GitHub Container Registry and to help you with this, I have left two useful links below.
Application Implementation (.NET)
The first step is basically to create a new project in .NET, feel free to use your favorite IDE to do this. We'll use a .NET API project, so we can containerize the application and publish it as an image on GitHub Container Registry.
When creating the project, remember to include support for docker on Linux if your IDE offers this option
Note: I'm using JetBrains Rider
In the project we will not implement anything new, we will only use what is already in the standard template, as the main objective is just to generate an image of the application. For more information about the project I created, you can see it here .NET Core API
If you forgot to enable docker support through the IDE or if the IDE does not have this type of support, let's manually add the dockerfile to the root of the project. Remember to review and make the necessary changes to the dockerfile, especially the application name if it's different.
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER $APP_UID
WORKDIR /app
EXPOSE 8080
EXPOSE 8081
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/83cihjqtpx8722tm137p.png)
.Api/ImageApplication.Api.csproj", "ImageApplication.Api/"]
RUN dotnet restore "ImageApplication.Api/ImageApplication.Api.csproj"
COPY . .
WORKDIR "/src/ImageApplication.Api"
RUN dotnet build "ImageApplication.Api.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "ImageApplication.Api.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ImageApplication.Api.dll"]
After creating the application and configuring the dockerfile, ensure that it works as expected. You can download Docker Desktop or Rancher Desktop and run it locally to ensure the image will build correctly.
Now, push the code to a new GitHub repository as for the next steps it's essential to have the repository created.
Generating GitHub Token
The next step is to generate the token that will represent the secret to authenticate to GitHub Container Registry and allow publication. In the right menu, go to Settings
In the left menu, go to Developer settings
Let's use a classic token
Click the Generate new token dropdown and select Generate new token (classic)
Set a name for your token, the expiration date and select the write:packages scope
At the bottom, click on the green Generate Token button to actually create the token and obtain the secret.
Go back to the repository you created for the .NET application. Now let's use the GitHub Secret to store the token to be used by the pipeline. To do this, in the repository. select Settings
In the left menu, select Secret and variables and click Actions.
Select New repository secret, define a name for the secret and in values paste the token we generated earlier. Finally, click Add secret.
Now we have the token that will be used for authentication and publication authorization as a GitHub Secret where it will be used by the pipeline.
Pipeline / Workflow
After creating our project, configuring the dockerfile and authentication token, it's time to prepare our CI/CD pipeline to generate the image and publish it to the Container Registry.
The pipeline itself is simple and easy to understand, as you can see below
Let's understand part by part
Name: Represents the name of the workflow
on: It's the trigger of workflows
push: It's the type of trigger, for example, the pipeline will be executed on every push
tags: As we defined the trigger of our pipeline as a push event, we also need to inform the push type, in our example it will be a tag push with a pre-defined format.
The pipeline/workflow will always be triggered every time a tag push occurs that follows the pattern
In the next part, we define the pipeline environment variable.
The registry variable represents the Container Registry URL, provided by GitHub.
The image name variable represents the name of my repository, which will also be used to name the image.
Next part, we have the definition of jobs where we need to define at least one job, the OS to be used by the Runner and the necessary steps.
Checkout Repository -> It's basically a git clone of the repository inside the VM (Runner) that will execute the steps.
Set up Docker Buildx -> Command for installing Docker Buildx that will be responsible for executing docker commands.
Log in to the GitHub Container Registry -> It's the authentication step in the Container Registry. Note that we pass 3 variables for step, registry, username and password. Registry is the URL defined in the environment variable at the beginning of the pipeline, username is your username on GitHub and is accessible by the standard variable github.actor provided by GitHub itself and the last is the password which is our token that we created previously and which is stored as secret where we reference it using the name REGISTRY_TOKEN.
In the last part we have...
Extract metadata... -> It's the command to make the git tag be used as the image version.
Build and Push Image -> Finally, this is the step that runs the dockerfile, creates the image, and pushes it to the Container Registry.
Executing the pipeline
To run the pipeline, you need to create a git tag and submit it, the commands are shown below.
git tag 1.3.0
git push origin 1.3.0
I've set a version of 1.3.0, but feel free to use whatever version you like. After push, the pipeline will run automatically.
To view packages, you can go to your profile again and select Packages
You can now download and run the image from any location. Remembering that the image is published as private, to make it public just click on the image and make it visible to everyone.
That's all folks, stay tuned for the next posts.
Top comments (0)