Search code examples
azuregoazure-web-app-servicegithub-actionsazure-webapps

Custom golang startup command on Azure Web App


I'm trying to deploy a Go webapp with Github actions to Azure App Services. The whole deployment succeeds until the point that the app needs to be deployed with azure/webapps-deploy@v2.

azure/webapps-deploy@v2 error message

To see where the problems raise I created just a simple Go 'Hello world' test app. Just deploying this really simple app works. However, while experimenting with deploying the test app I noticed a few things:

  • The app is completely rebuilt on Azure instead of using the executable file to run. My previous deployment file looked like this:
name: Go deployment

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

jobs:
  build:
    runs-on: ubuntu-latest
    environment: production
    steps:
    # checkout the repo 
    - uses: actions/checkout@master

    # setup Go
    - name: Setup Go
      uses: actions/setup-go@v3
      with:
       go-version: '1.20'

    - run: go version

    # install dependencies
    - name: go build
      working-directory: .
      run: |
       go build
      
    - name: Upload artifact for deployment job
      uses: actions/upload-artifact@v3
      with:
        name: go-app
        path: .

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v3
        with:
          name: go-app
          
      - name: 'Deploy to Azure Web App'
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: ${{ env.AZURE_WEBAPP_NAME }}
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE }}
          package: .

This deploys without a problem. The codebase app is fed to the Azure Web App. When I try to use the executable in the last step, the deployment fails. Of course Azure Web App has a custom field for setting a startup command. I tried setting this to ./main to just run the executable at startup but this still fails.

        with:
          app-name: ${{ env.AZURE_WEBAPP_NAME }}
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE }}
          package: main

Startup command

When building the Go app on my local machine with go build main.go and then executing ./main this app runs without a problem.

  • Because I couldn't just execute the executable in previous step I decided to roll back and just let Azure App Service execute the Go app as is. If so, the whole building step isn't necessary anymore and it's just fine to push the code to the Azure Web Service. Like so:
name: Go

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

jobs:
  build:
    runs-on: ubuntu-latest
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
    steps:
    # checkout the repo 
    - uses: actions/checkout@master

    - name: 'Deploy to Azure Web App'
      id: deploy-to-webapp
      uses: azure/webapps-deploy@v2
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        slot-name: 'Production'
        publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE }}
        package: .

Despite having to push the whole code base, this again runs beautifully. However in our production app the main.go file is for structural reasons not located in the root dir. To imitate this behaviour I placed the main.go file under a /cmd directory. And again the deployment of Azure Web App fails. As can be guessed, this is probably due to Azure not able to find the main.go file. I thought to use the startup command again but this time with go run cmd/main.go. Sadly, this also does not work. Startup command

Azure Web Apps shows everything that is it building while running the pipeline: Building on Azure

Any suggestions? Things I'm missing here?

Any solution on how I would be able to just upload the created executable in a previous step to Azure Web App and run this executable there?


Solution

  • First you should set in Azure Web App an environment variable: WEBSITE_RUN_FROM_PACKAGE to 1. This prevents running the build on Azure again. From this moment on you should be able to upload pre-built executables.

    I also had to set the startup command for running my specific executable. Set startup command

    After doing this I saw the following in the logs on https://APPNAME-HERE.scm.azurewebsites.net/api/logstream

    2023-04-26T17:20:12.596331026Z Detecting platforms...
    
    2023-04-26T17:20:12.805572634Z Could not detect any platform in the source directory.
    
    2023-04-26T17:20:15.792565274Z Running /home/site/wwwroot/go-test now
    
    2023-04-26T17:20:15.928193597Z /home/site/wwwroot/go-test: /lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.32' not found (required by /home/site/wwwroot/go-test)
    
    2023-04-26T17:20:15.934491135Z /home/site/wwwroot/go-test: /lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.34' not found (required by /home/site/wwwroot/go-test)
    

    The version GLIBC_2.34 happens because the app was built in pipeline with ubuntu-latest. This is Ubuntu-22.04 which has GLIBC_2.35 but the Azure machine to run on does not have this version. Use ubuntu-20.04 to built with version GLIBC_2.31 and it will run perfect.