Deploy a Dockerized Go application to Azure
Fullstack Developer and Tech Author
As a software engineer, one of your goals is to ensure that your product can be accessed globally by your customers. If your bug-free app works on localhost
but fails in production due to a language version conflict, that won’t help customers, and it won’t impress your co-workers.
Docker was introduced to solve this “it works on my machine” problem. Using the power of containers, you can ensure consistency across different environments by packaging your application and its dependencies into a portable container image.
In this tutorial, I will show you how to Dockerize your Golang API. Using an already built Golang API project, you will build a container image out of it. Then, you’ll push the container image to the Azure Container Registry. I will then show you how to create an Azure web service as an application and connect the container image to it.
To wrap things up, I will guide you through creating a continuous integration and continuous deployment (CI/CD) pipeline to run automated tests and deployment using CircleCI.
Prerequisite
To follow along with this tutorial, you will need the following:
- Basic knowledge of Go programming language.
- Go installed on your system. Download instructions are available here.
- Docker Desktop installed on your local machine. You can follow Docker’s tutorial for Windows or macOS.
- A Microsoft Azure account.
- A CircleCI account.
- A GitHub account.
Setting up the demo project
To get started quickly, clone the Golang API project from GitHub. Review this tutorial to learn how this demo was built.
Run this command to download the project using Git:
git clone https://github.com/CIRCLECI-GWP/go-docker-azure.git
This will clone the project into a go-docker-azure
folder within your development directory.
Running and testing the application
Next, move into the project folder and run the application:
cd go-docker-azure
go run main.go
The application will run on the default port 8080
. Go to http://localhost:8080
to review it.
This endpoint returns a simple message. You can continue to test the remaining endpoints and run the unit tests to be sure that everything works as expected.
Creating a new company
Test this out using Postman or your preferred API testing tool. Send an HTTP POST request to http://localhost:8080/company
. Use this data as the request payload:
{
"name":"Shrima Pizza",
"ceo": "Demo CEO",
"revenue":"300 million"
}
Retrieving the list of companies
To retrieve the list of companies, set an HTTP GET
request to http://localhost:8080/companies
.
Running the unit test
Now, open a new terminal window and run the test by issuing this command:
GIN_MODE=release go test -v
At this point, the application works as expected, and the unit tests are passing. Stop the application from running using CTRL + C
.
Creating a deployment strategy
As mentioned, the objective of this tutorial is to Dockerize and deploy the Golang project to the Azure container instance. There is no need to modify the codebase other than the configuration file, so let’s go over the deployment strategy.
You will:
- Create a registry to host your container image on the Azure Container Registry (ACR) and get the Access key. ACR is a private registry owned by Microsoft for hosting Docker images. It works like DockerHub.
- Create a container image for the project, then build and run the container locally.
- Publish the Docker image to the Azure container registry.
- Create an Azure web app and link it with the published container image.
- Enable continuous deployment and create a configuration file to build and deploy your container image on CircleCI.
- Push the project to GitHub and connect with CircleCI.
- Deploy the container image to the Azure container registry.
Creating an Azure Container Registry
Next, you will create an Azure container registry that will store the image for this project. Go to the Azure portal homepage and click Create a resource.
Then select Containers > Container Registry to create a new registry.
On the registry creation page, add the details for the registry. I named mine godemo
:
Click Review + Create. You will be redirected to a page where you can review the registry information. Click Create to set up a new registry instance.
Getting the access key from the registry
In this section, you will enable Docker access in the Azure Container Registry, which is crucial to the deployment process. It lets you remotely log in to the ACR through the CLI and push images to it.
After the registry resources have been created, open it and locate the Access Keys link in the Settings section.
This will show you the registry name and login server. Use the toggle button to change Admin user to enabled. Copy the username and any of the passwords, preferably the first one. Keep this handy; it will be used later in the tutorial.
Containerizing the application locally
Next, you will write a custom Docker file that will build a container image. From the root of the application, open the Dockerfile
. Make sure its content matches this:
FROM golang:1.18.3-alpine3.16
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN go build -o main .
CMD ["/app/main"]
This file uses golang:1.18.3-alpine3.16
as its base image. It then creates a new folder named app
and adds all the content of the Golang project into it. Next, it sets the working directory in the container to th app
folder and includes the command to run the project.
Building the Docker image
To build a Docker image for the project, run:
docker build -t godemo.azurecr.io/go-demo:latest .
This command looks in the project for the Dockerfile and builds the container image based on the content of the Golang application. Note that the command uses the registry name and login server from the registry you created earlier. The benefit of this approach is that you can easily map the container image with the Azure container registry.
You will receive output when the container image has been built successfully.
Running the Docker image
Now that you have built the local version of the container image, run it with this command:
docker run -d -p 8080:8080 godemo.azurecr.io/go-demo
This will run the app on the same port as earlier. Visit http://localhost:8080
.
Pushing the Docker image to Azure Registry
Now, log in to the Azure container registry you created earlier and push the container image to it. Issue this command from the terminal:
docker login -u DOCKER_USER -p DOCKER_PASS godemo.azurecr.io
Replace these placeholders with your values:
- Replace
DOCKER_USER
with the username for the container registry. - Replace
DOCKER_PASS
with the password from the container registry.
Once you are logged in, use this command to push the image to the Azure registry:
docker push godemo.azurecr.io/go-demo:latest
This deploys the image to the Azure registry.
Creating an Azure web app for the container
Next, you will create an Azure web app and connect it with the container image. Go to the Azure portal homepage and click Create a resource. Select Containers > Web App for Containers to create a new web app service instance.
You will be redirected to the Create Web App page. Select an Azure subscription and a resource group. Docker container
should be selected by default.
Now, click on the Docker tab. Select the image source and its Docker image.
Click Review + Create. You will be redirected to a page where you can review the web app details. Click Create to set up a new Azure web app.
Once the process is completed, you can visit the URL, where you will be able to review the app as deployed to Azure.
Enabling continuous deployment
To ensure that each time your Docker image is updated, the app will receive the update, you need to enable continuous deployment for the web app service. To do that, click the app name. Then click Deployment Center under the Deployment section and scroll down. Below the Settings tab, turn on continuous deployment by selecting the radio button. Click Save.
With continuous deployment selected, the web app will trigger a new deployment of the Golang application each time the Docker image is rebuilt on Azure Container Registry.
Automating deployments with CircleCI
Next, you need to add the pipeline configuration. This configuration instructs CircleCI to automate testing and run the commands to build and push the image to the Azure container registry.
At the root of your project, open the .circleci/config.yml
file. Make sure the content matches this:
version: 2.1
orbs:
go: circleci/go@1.7.1
jobs:
build-and-run-test:
executor:
name: go/default
tag: "1.16"
steps:
- checkout
- go/load-cache
- go/mod-download
- go/save-cache
- run:
name: Run tests
command: go test -v
build-docker-image:
docker:
- image: cimg/go:1.18.3
steps:
- checkout
- setup_remote_docker:
docker_layer_caching: true
-run:
name: Build and push Docker image
command: |
docker build -t godemo.azurecr.io/go-demo:latest .
echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin godemo.azurecr.io
docker push godemo.azurecr.io/go-demo:latest
workflows:
test-and-deploy:
jobs:
- build-and-run-test
- build-docker-image:
requires:
- build-and-run-test
These scripts contain two jobs:
- The
build-and-run-test
job pulls in the Go orb for CircleCI, which allows common Go-related tasks such as installing Go, downloading modules, and caching to be carried out. It then checks out of the remote repository and issues the command to run the test. - The
build-docker-image
job builds the Docker container image for the project on CircleCI and pushes it to the Azure container registry.
The workflow ensures that the test is run successfully before building the container image and deploying it to Azure.
Next, you will need to set up a repository on GitHub and link the project to CircleCI. Review Pushing your project to GitHub for instructions.
Connecting your project with CircleCI
Log into your CircleCI account. If you signed up with your GitHub account, all your repositories will be available on your project’s dashboard. Search for the go-docker-demo
project:
Click Set Up Project. You will be prompted about whether you have already defined the configuration file for CircleCI within your project. Enter the branch name (for the tutorial, you are using main
). Click the Set Up Project button to complete the process.
The first job will run successfully while the second will fail. This is because it requires the Azure container registry credentials.
Fixing the credential issue
To fix the credential issue, click the Project Settings button, then click Environment Variables. Go ahead and add these two new variables:
DOCKER_USER
is the username for the container registry.DOCKER_PASS
is the password from the container registry.
Click Rerun Workflow from Start.
Your workflow will run successfully. You can make some changes to the codebase locally and push it to GitHub to be sure that continuous deployment has been implemented.
Conclusion
As you learned in this tutorial, each time you update the project and push it to GitHub, CircleCI will use the configuration details to build a new container image and update the Azure container registry with it. And with continuous deployment enabled on the Azure web app, a webhook resource will be fired to push a new version of the container image to the web app.
I hope that you found this tutorial helpful. Check here for the complete source code for the project.