1. Overview
In this tutorial, we’ll explore how to retrieve the commit hash from a running Docker container. This is particularly useful when debugging or verifying the exact version of the code running in our containerized applications.
2. Understanding the Importance of Commit Hash
The commit hash uniquely identifies a specific state of our codebase in version control. Having this information readily accessible can be critical for tracking changes, debugging, and ensuring consistency across different environments. A typical commit hash looks like this: ce85e2ebe299cf9a8237556c86dbcaaa2d571a3e.
3. Tagging Docker Images with Commit Hash
When building Docker images, it’s a common practice to tag them with the commit hash. This provides a clear linkage between the image and the exact state of the source code it was built from.
3.1. Building and Tagging an Image
To tag our Docker image with the commit hash during the build process, we can use the following command:
$ docker build --build-arg GIT_COMMIT=$(git rev-parse HEAD) -t my_image:$(git rev-parse HEAD)
In this command, –build-arg GIT_COMMIT=$(git rev-parse HEAD) passes the current commit hash to the Docker build process, and -t my_image:$(git rev-parse HEAD) tags the built image with the same commit hash, creating a direct link between the Docker image and the specific state of the source code.
3.2. Dockerfile Configuration
We can also pass the commit hash as a build argument and set it as an environment variable within the Dockerfile:
FROM alpine
ARG GIT_COMMIT
ENV GIT_COMMIT=$GIT_COMMIT
4. Retrieving Commit Hash from a Running Container
Once the container is running, we can retrieve the commit hash using various methods. Let’s explore a few of them.
4.1. Using Docker Inspect
The docker inspect command offers a comprehensive view of a container’s details, including its environment variables. This method is useful when we want to retrieve the commit hash without entering the container itself. Here’s an example command to achieve this:
$ docker inspect --format='{{.Config.Env}}' <container_id>
For example, we can use the command:
$ docker inspect --format='{{.Config.Env}}' my_container
This will produce the output:
[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin GIT_COMMIT=ce85e2ebe299cf9a8237556c86dbcaaa2d571a3e]
4.2. Directly Accessing Environment Variables
If the build process sets the commit hash as an environment variable within the image, we can access it directly from the running container. This approach proves useful when we need the commit hash for scripting purposes inside the container. Here’s the command to retrieve an environment variable:
$ docker exec <container_id> printenv GIT_COMMIT
For example, we can apply this command:
$ docker exec my_container printenv GIT_COMMIT
The result of this command is:
ce85e2ebe299cf9a8237556c86dbcaaa2d571a3e
5. Automating the Process
To make the retrieval process seamless, consider automating these steps within our CI/CD pipeline.
Integrate the commit hash tagging and retrieval into our CI/CD pipeline to ensure consistency and automate verification steps:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Build Docker image
run: docker build --build-arg GIT_COMMIT=${{ github.sha }} -t my_image:${{ github.sha }} .
6. Handling Errors
Sometimes, retrieving information from a stopped or non-existent container can result in errors. Ensure proper error handling in our scripts to manage such scenarios gracefully.
If we try to inspect a non-running container, we might encounter the following error:
Error: No such object: <container_id>
We should incorporate error handling in our scripts to manage such cases:
if ! docker inspect <container_id>; then
echo "Container not found or not running"
fi
7. Conclusion
In this article, we’ve covered various methods to get the commit hash from a running Docker container.
By tagging our images with the commit hash and setting it as an environment variable, we can easily retrieve this critical information for debugging and verification purposes. Implementing these practices in our CI/CD pipeline ensures consistency and streamlines our development workflow.