Preview environment with our own docker registry

Hello,

I tried to enable preview environment that works perfectly with application from git provider but this is not working with docker application. How can I unable it ? I can’t choose the base branch like explained here : Getting Started with Preview Environments on AWS | Qovery

Thanks

Hello @Orkin,

For git provider applications, we are notified through a webhook that a PR is opened on a specific git repository for a given branch.
Preview environments are triggered in a different way for containers: this is based on your container tag.
What you can do in your pipeline is to:

  • push the image with a new tag
  • use this endpoint to trigger a preview env on Qovery (by passing the tag you pushed in previous step)

Thanks @Melvin_Zottola for your answer. This is my working solution so @rophilogene or @Pierre_Mavro if you want to write a guide feel free to use this if you want ;). My inspiration coming from this guide Build E2E Testing Ephemeral Environments with GitHub Actions and Qovery | Qovery that cover some of my usecase.

First one I created a blueprint environment like explain on the article.

:warning::warning::warning: be careful with your environment variable, by default when you have a variable that use only one other environment variable from Qovery, Qovery can change it with the value of the new service.

Let me give you an example : you have a variable from Qovery like QOVERY_CONTAINER_ABC_HOST_INTERNAL if you have a variable API_HOST={{QOVERY_CONTAINER_ABC_HOST_INTERNAL}} when you clone the environment for preview it will change QOVERY_CONTAINER_ABC_HOST_INTERNAL by the new one QOVERY_CONTAINER_XYZ_HOST_INTERNAL. The best is to use alias for that. But sometimes you will have to build more complexe variable like API_URL=https://{{QOVERY_CONTAINER_ABC_HOST_INTERNAL}}/foo the value of API_URL is not updated with the new QOVERY_CONTAINER_XYZ_HOST_INTERNAL environment variable

To avoid this problem you can create an alias for QOVERY_CONTAINER_ABC_HOST_INTERNAL with name API_HOST and build the API_URL like API_URL=https://{{API_HOST}}/foo. When environment is clone for preview, all variable are copied and works perfectly.

Let’s see now the github action configuration to start and deploy the preview environment. The preview environment is started when the PR is flagged with the label preview. In my use case I use arm instances so I have to build docker container compatible with arm. The default github runner are amd instance so building an arm docker image is very slow for that I used depot that speed up the build by sooooo much. With cache (around 10 seconds to build instead of 5-6 minutes)

name: PR Run preview environment

on:
  pull_request:
    types: [ labeled ]

jobs:
  build-preview:
    if: ${{ github.event.label.name == 'preview' }}
    runs-on: ubuntu-latest
    timeout-minutes: 14
    permissions:
      contents: read
      id-token: write
    steps:
      - name: Check out the repo
        uses: actions/checkout@v3

      - name: Set up depot.dev multi-arch runner
        uses: depot/setup-action@v1

      - name: Log in to Docker Hub
        uses: docker/login-action@v2.1.0
        with:
          registry: <registry_url>
          username: <username>
          password: <password>

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v4.1.1
        with:
          images: <registry_url>/<image_name>
          tags: |
            type=semver,pattern={{version}}
            type=sha,prefix=preview-,format=long #here you can use the prefix you want, I use preview but feel free to use the one you want

      - name: Build and push Docker image
        uses: depot/build-push-action@v1 # here is depot but you can use docker/build-push-action@v4 image instead for amd instances
        with:
          project: <project_id>
          context: .
          platforms: linux/arm64
          target: <your_target> # if you have one on your Dockerfile
          file: Dockerfile
          push: true
          build-args: |
            <VAR_ENV1>=${{ secrets.VAR_ENV1 }}
            <VAR_ENV2>=${{ secrets.VAR_ENV2 }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

  create-preview-environment:
    if: ${{ github.event.label.name == 'preview' }}
    runs-on: ubuntu-latest
    needs: [build-preview] # to not start the github workflow without a previous image build
    permissions:
      pull-requests: write
    steps:
      - id: create-environment
        name: Create and deploy Qovery preview environment
        env:
          QOVERY_CLI_ACCESS_TOKEN: <QOVERY_CLI_ACCESS_TOKEN>
        run: |
          # Download and install Qovery CLI
          curl -s https://get.qovery.com | bash

          echo "Organization name: ${{ vars.QOVERY_ORGANIZATION_NAME }}"
          echo "Project name: ${{ vars.QOVERY_PROJECT_NAME }}"
          echo "Blueprint name: ${{ vars.QOVERY_BLUEPRINT_ENVIRONMENT_NAME }}"
          
          new_environment_name="${GITHUB_HEAD_REF}"

          echo "Let's clone '${{ vars.QOVERY_BLUEPRINT_ENVIRONMENT_NAME }}' environment into '$new_environment_name' environment"

          qovery environment clone \
            --organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
            --project "${{ vars.QOVERY_PROJECT_NAME }}" \
            --environment "${{ vars.QOVERY_BLUEPRINT_ENVIRONMENT_NAME }}" \
            --cluster "${{ vars.QOVERY_CLUSTER_NAME }}" \ # don't forget to specify the cluster name if you have more than one to prevent bad cluster environment location
            --new-environment-name "$new_environment_name"

          qovery container update \
            --organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
            --project "${{ vars.QOVERY_PROJECT_NAME }}" \
            --environment "$new_environment_name" \
            --container "<container_name>" \
            --tag preview-${{ github.sha }}

          # repeat this step if you have many container to update
          
          qovery lifecycle update \
            --organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
            --project "${{ vars.QOVERY_PROJECT_NAME }}" \
            --environment "$new_environment_name" \
            --lifecycle "<lifecycle_name>" \
            --tag preview-${{ github.sha }}

          qovery environment deploy \
            --organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
            --project "${{ vars.QOVERY_PROJECT_NAME }}" \
            --environment "$new_environment_name" \
            -w

          qovery_status_markdown_output=`qovery service list \
            --organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
            --project "${{ vars.QOVERY_PROJECT_NAME }}" \
            --environment "$new_environment_name" \
            --markdown`

          echo "QOVERY_STATUS_MARKDOWN_OUTPUT<<EOF" >> "$GITHUB_OUTPUT"
          echo "$qovery_status_markdown_output" >> "$GITHUB_OUTPUT"
          echo "EOF" >> "$GITHUB_OUTPUT"

      - name: PR Comment with URL
        uses: mshick/add-pr-comment@v2
        with:
          message-id: qovery-preview-environment-status
          message: |
            ${{ steps.create-environment.outputs.QOVERY_STATUS_MARKDOWN_OUTPUT }}

And the final step, destroy the preview environment on PR close / merge

name: Destroy and clean up preview Environment

on:
  pull_request:
    types: [ closed ]

jobs:
  delete-preview-environment:
    runs-on: ubuntu-latest
    steps:
      - id: delete-environment
        name: Delete Qovery preview environment
        env:
          QOVERY_CLI_ACCESS_TOKEN: ${{ secrets.QOVERY_CLI_ACCESS_TOKEN }}
        run: |
          # Download and install Qovery CLI
          curl -s https://get.qovery.com | bash

          echo "Organization name: ${{ vars.QOVERY_ORGANIZATION_NAME }}"
          echo "Project name: ${{ vars.QOVERY_PROJECT_NAME }}"
          echo "Blueprint name: ${{ vars.QOVERY_BLUEPRINT_ENVIRONMENT_NAME }}"
          
          new_environment_name="${GITHUB_HEAD_REF}"

          echo "Let's delete '$new_environment_name' environment and release its resources"

          qovery environment delete \
            --organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
            --project "${{ vars.QOVERY_PROJECT_NAME }}" \
            --environment "$new_environment_name" \

Feel free if you have some advice to improve these github action :wink:

1 Like

Well done @Orkin ! I’ll definitely work on guide to make it simpler for anyone. Thanks for posting this

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.