Tools like Docker, Podman or Kubernetes make it easy to run your applications anywhere in a reproducible fashion.
The easiest way to host your container images is by using a container registry, for example ghcr.io from GitHub. The benefit of using ghcr.io aka GitHub Packages is that they are private by default, are well integrated with GitHub Actions CI/CD and they are for free. Of course there are far more container registries out there, but GitHub Packages fits my needs.
Prerequisites
- Quarkus CLI (optional)
- Quarkus application
- quarkus-container-image-jib dependency
- Java / Kotlin
- Gradle
- GitHub Account for GitHub Container Registry or other registry (Optional)
Creating a sample Quarkus project
The easiest way to create a Quarkus project locally is using the Quarkus CLI, which I'd usually install using SDKMan!.
quarkus create app dev.simonscholz:container-registry --gradle-kotlin-dsl --kotlin --extensions=container-image-jib,quarkus-config-yaml,quarkus-micrometer-registry-prometheus
Alternatively you also can go to https://code.quarkus.io/ to create a new Quarkus project.
Feel free to add any extension you'd like.
Adding container-image-jib to existing project (optional)
If you already have a Quarkus Project at hand you simply need to add the io.quarkus:quarkus-container-image-jib
dependency.
quarkus ext add io.quarkus:quarkus-container-image-jib
Creating a PAT (GitHub Personal Access Token)
In order to be able to push to the GitHub Container registry from your local machine a PAT (GitHub Personal Access Token) is required.
You can create one my logging in into GitHub and navigating to the Token Settings.
- Select
Tokens (classic)
- Click on `Generate new token (classic)
- The only necessary permission/scope to tick is
write:packages
.
Then click on the Generate token
button at the bottom and copy it, since you won't see it anymore after leaving the page.
Configure the application
For the username and PAT an .env
file in the project root is really helpful.
Please ensure that this .env
file will not be pushed to a remote github repository by adding it to your .gitignore
file.
CONTAINER_REGISTRY_USERNAME=your-username
CONTAINER_REGISTRY_PASSWORD=the-PAT-you-created-before
In case quarkus-config-yaml
also has been added the config can look like this:
quarkus:
application:
name: your-application
container-image:
name: your-application
registry: ghcr.io # 1
username: ${CONTAINER_REGISTRY_USERNAME} # 2
password: ${CONTAINER_REGISTRY_PASSWORD} # 3
group: ${CONTAINER_REGISTRY_USERNAME} # 4
tag: latest
build: true
push: false # 5
builder: jib
- Container image registry to push to, e.g., ghcr.io for GitHub Packages
- Username to login into the registry from .env file
- Password or PAT from .env file
- The group in the container registry, can be your organization or username (here it is the same as the username from .env)
- Avoid pushing the container image on during build, if set to true a simple
quarkus build
or./gradlew build
will automatically push the image to the registry
Since the push
property is set to false
the push property can be set in your terminal/command line:
# Using quarkus cli
quarkus build -Dquarkus.container-image.push=true
# Using gradle
./gradlew build -Dquarkus.container-image.push=true
# Using maven
./mvnw install -Dquarkus.container-image.push=true
By default the container image artifact will be private.
The container image can then be found here: https://github.com/your-org-or-user-name?tab=packages
When you click on the newly created package it should look similar to this:
Pull and run the image using docker
Since the container registry is private you'll first need to login:
echo "YOUR_GITHUB_PAT" | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin
Once logged in you can run the application like this:
docker run -p 8080:8080 ghcr.io/YOUR_GITHUB_USERNAME/your-application:latest
Since the sample application from above is using Micrometer with Prometheus, you should now be able to see exposed metrics in the browser: http://localhost:8080/q/metrics
Run the image using docker compose
Please be sure you've logged in before to the ghcr.io registry:
echo "YOUR_GITHUB_PAT" | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin
The docker-compose.yml
file could look like this then:
services:
your-application:
image: ghcr.io/simonscholz/your-application:latest
restart: "no"
ports:
- "8080:8080"
pull_policy: always
extra_hosts:
- "host.docker.internal:host-gateway"
Running docker compose up
in a terminal will then result in a similar output:
Since the sample application from above is using Micrometer with Prometheus, you should now be able to see exposed metrics in the browser: http://localhost:8080/q/metrics
Publish to container to ghcr registry using GitHub Actions
... to be continued ...