This is a sample project to provide a quick-start for Golang developers to experience the deployment of their Golang applications to Microsoft Azure Web Apps.
- Login to https://dev.azure.com;
- Click on the "+ New Project" button at the top-right corner (It may not be visible to you if you are not admin);
- Click "Create" button to proceed after keying in the information about your project and deciding whether your repo should be Public or Private;
- Choose "Builds" under Pipelines at the left menu;
- Click on the "New Pipeline" button;
- Click on the link which says "Use the classic editor";
- Select the location of your repo (eg. Azure DevOps or GitHub, in this readme, I use GitHub because the code is on GitHub);
- Continue to next step after connecting to the repo;
- Search "go" in the search box and choose "Go (Preview)" as template;
- Leave the settings of the Pipeline as they are;
- Visit the "Triggers" tab;
- Enable the Continuous Integration and batch processing;
- Click "Save & Queue" button to proceed;
- Wait for the Build process to finish with all green ticks;
- Celebrate for setting up the Build Pipeline when the Artifact file is successfully generated and published.
- Login to https://portal.azure.com;
- Create a new Azure web app with the following options configured accordingly;
- Wait for the message saying "Your deployment is complete";
- Celebrate for setting up new Azure web app successfully.
- Back to Azure DevOps (https://dev.azure.com);
- Choose the project created in Section 1;
- Choose "Releases" under Pipelines at the left menu;
- Click on the "New Pipeline" button;
- Apply on the "Azure App Service deployment" template;
- Click on the "Add an artifact" box in the diagram and choose the Build pipeline created in Section 1;
- Click "Add" button to proceed;
- Enable the Continuous Deployment trigger;
- Edit the Stage 1 by clicking on the "1 job, 1 task";
- Connect with Azure by choosing the correct corresponding Azure Subscription and App Service Name for the web app created in Section 2 (You may need to click on the Authorize button to authorize this action so that Azure service connection can be configured);
- Click on the "+" button beside "Run on agent";
- Add two "Azure App Service Manage" tasks and surround the "Deploy Azure App Service" task, as shown in the screenshot below;
- Configured the two newly added tasks so that the first is to stop the Web App and the second is to start the Web App;
- Click on the "Deploy Azure App Service" task;
- Add in the following line under "Generate web.config parameters for Python, Node.js, Go and Java apps";
- Tick the checkbox "Select deployment method" and make sure both "Web Deploy" and "Take App Offline" is selected;
- Save the pipeline;
- Click "Create release";
- Choose "Releases" under Pipelines at the left menu;
- Wait for the "Release-1" to be having green tick;
- Visit the web app to check if the deployment is successful;
- Celebrate if you see the following page (You can also test /api to see JSON object returned).
The reason why we need to have two tasks in the Release Pipeline to first stop the Web App before the new code is deployed is that if we do not stop the Web App first then the code cannot be deployed with the following error message.
Error: Error Code: ERROR_FILE_IN_USE
More Information: Web Deploy cannot modify the file GoToAzure.exe on the destination because it is locked by an external process. In order to allow the publish operation to succeed, you may need to either restart your application to release the lock, or use the AppOffline rule handler for .Net applications on your next publish attempt. Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_FILE_IN_USE.
Error count: 1
In the app.go, we have the getPort() function is to get the actual port used in Azure Web App for the program. Hence, please do not hardcode ":80", instead read the port number from the HTTP_PLATFORM_PORT.
func getPort() string {
p := os.Getenv("HTTP_PLATFORM_PORT")
if p != "" {
return ":" + p
}
return ":80"
}
Whatever operating system we're using, the code that runs inside a container needs to be a Linux binary. Fortunately, this is really simple to obtain, thanks to the cross-compilation support in Golang.
On Windows, we can use the following commands to do so on Windows PowerShell.
$ $env:GOOS = "linux"
$ go build -o GoToAzure .
For simplicity, we can have Dockerfile as follows.
FROM scratch
EXPOSE 80
COPY GoToAzure /
COPY static static
ENV APPINSIGHTS_INSTRUMENTATIONKEY '' \
CONNECTION_STRING ''
CMD [ "/GoToAzure" ]
The first reason why I need to containerize my Golang web application on Azure Web App (there is Azure Web App for Containers) is because I want to use wkhtmltopdf. Hence, the following is the Dockerfile for this scenario.
FROM ubuntu:14.04
EXPOSE 80
RUN sed 's/main$/main universe/' -i /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y
# Download and install wkhtmltopdf
RUN apt-get install -y build-essential xorg libssl-dev libxrender-dev wget gdebi
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.trusty_amd64.deb --no-check-certificate
RUN gdebi --n wkhtmltox_0.12.5-1.trusty_amd64.deb
COPY GoToAzure /
COPY static static
ENV APPINSIGHTS_INSTRUMENTATIONKEY '' \
CONNECTION_STRING ''
CMD [ "/GoToAzure" ]
This project will continue to evolve. We will do modifications all the time as long as Azure DevOps and Azure Portal do not stop changing.
Any help will be appreciated. You can develop new features, fix bugs, improve the documentation, or do some other cool stuff.
If you have new ideas or want to complain about bugs, feel free to create a new issue.
Let's build the best documentation for Golang with Azure!
This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community.
This project is supported by the Azure Community Singapore (ACS).