Build and Deploy in Google Compute Engine using Github Actions

This GitHub Action is an example workflow to deploy a container to an existing GCE instance.

This code is intended to be an example of an elixir project. You will likely need to change or update values to match your setup.

Workflow description

For pushes to the master branch, this workflow will:

  • Download and configure the Google Cloud SDK with the provided credentials.

  • Build, tag, and push a container image to Google Container Registry.

  • Deploy the container image to a Google Compute Engine instance. Note that a GCE deployment requires an existing container-optimized VM.


name: Build and Deploy to Google Compute Engine Instance
on:
  push:
    paths-ignore:  # Don't trigger deployment when any of these files/folders changes.
      - '.github/**'
      - '!.github/workflows/prod.yml'
      - 'docs/**'
      - 'README.md'
      - '.gitignore'
      - '.gitmodules'
      - '.sobelow-conf'
      - '.tool-versions'
    branches:
      - master

env:
  PROJECT_ID: ${{ secrets.GCE_PROJECT }}
  GCE_INSTANCE: ${{ secrets.GCE_INSTANCE }}
  GCE_INSTANCE_ZONE:  ${{ secrets.GCE_INSTANCE_ZONE }}

jobs:
  setup-build-publish-deploy:
    name: Setup, Build, Publish, and Deploy
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v2
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
        submodules: true # Incase if the project have submodules

    - uses: nijel/rabbitmq-action@v1.0.0
      with:
        rabbitmq version: '3.7'

    - uses: actions/setup-elixir@v1
      with:
        otp-version: 22.1.7
        elixir-version: 1.9.4

    - uses: actions/cache@v1
      id: deps-cache
      with:
        path: deps
        key: ${{ runner.os }}-dependencies-${{ hashFiles('mix.lock') }}

    - uses: actions/cache@v1
      id: build-cache
      with:
        path: _build
        key: ${{ runner.os }}-build-${{ hashFiles('mix.lock') }}

    - uses: actions/cache@v1
      id: dialyzer-cache
      with:
        path: dialyzer
        key: ${{ runner.os }}-dialyzer-${{ hashFiles('mix.lock') }}

    # Setup gcloud CLI
    - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
      with:
        version: '290.0.1'
        service_account_key: ${{ secrets.GCE_SA_KEY }}
        project_id: ${{ secrets.GCE_PROJECT }}

    # Configure Docker to use the gcloud command-line tool as a credential
    # helper for authentication
    - run: |-
        gcloud --quiet auth configure-docker

    # Build the Docker image
    - name: Build
      run: |-
        docker build --tag "gcr.io/$PROJECT_ID/$GCE_INSTANCE:prod-$GITHUB_SHA" -f ./Dockerfile .

    # Push the Docker image to Google Container Registry
    - name: Publish
      run: |-
        docker push "gcr.io/$PROJECT_ID/$GCE_INSTANCE:prod-$GITHUB_SHA"


    - name: Deploy
      run: |-
        gcloud compute instances update-container "$GCE_INSTANCE" \
          --zone "$GCE_INSTANCE_ZONE" \
          --container-env-file /tmp/your-custom.env \
          --container-image "gcr.io/$PROJECT_ID/$GCE_INSTANCE:prod-$GITHUB_SHA" \
          --container-restart-policy on-failure