MySQL: 5. GitLab CI

This documentation is part of the GitHub Actions & GitLab CI guide. View the full guide here: Spin up a real MySQL service from your GitHub Actions or GitLab CI pipeline, run your tests against it, and tear it down automatically.

👋 Welcome to the Stackhero documentation!

Stackhero provides a fully managed MySQL cloud service that simplifies deployment and management for production workloads:

  • Unlimited connections and data transfers.
  • Integrated phpMyAdmin web interface for easy database management.
  • Hassle-free updates with one-click upgrades.
  • Consistent performance and strong security on a private, dedicated infrastructure.

With Stackhero, you can have a reliable MySQL database ready in just a few minutes. Spend less time on setup and maintenance, and more time building your applications. Try MySQL cloud hosting on Stackhero today.

You can save this configuration as .gitlab-ci.yml. With this setup, every pipeline run spins up a fresh real MySQL for your tests.

test:
  image: ubuntu:24.04
  variables:
    STACK_NAME: "ci-mysql-$CI_PIPELINE_ID-$CI_JOB_ID"
    INSTANCE: "10G"   # Change this as needed (see step 3)
    REGION: "europe"
    SERVICE_STORE: "mysql"
  # STACKHERO_TOKEN comes from the CI/CD variable you created in step 1.
  script:
    - set -euo pipefail
    - curl -fsSL https://www.stackhero.io/install.sh | sh
    - apt-get update && apt-get install -y --no-install-recommends jq curl default-mysql-client
    - STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
    - echo "STACK_ID=$STACK_ID" >> deploy.env
    - SERVICE_ID=$(stackhero --format=script service-add --stack="$STACK_ID" --service-store="$SERVICE_STORE" --instance="$INSTANCE" --region="$REGION")
    - echo "SERVICE_ID=$SERVICE_ID" >> deploy.env
    - stackhero service-wait-for --service="$SERVICE_ID"
    - config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
    - host=$(echo "$config" | jq -r '.configuration.domain')
password=$(echo "$config" | jq -r '.configuration.mysqlRootPassword')
    # Run a trivial query against the database.
    - mysql --host="$host" --port=3306 --user=root --password="$password" --ssl-mode=REQUIRED -e "SELECT 1;"
    - echo "✅ MySQL is reachable from CI."
    # You can run your own test suite here using the credentials above ...
  after_script:
    - test -f deploy.env && . ./deploy.env || true
    - >
      if [ -n "${SERVICE_ID:-}" ]; then
        stackhero service-delete --service="$SERVICE_ID" --confirm
        stackhero service-wait-for --service="$SERVICE_ID"
      fi
    - >
      if [ -n "${STACK_ID:-}" ]; then
        stackhero stack-delete --stack="$STACK_ID" --confirm
      fi

In GitLab, cleanup happens inside after_script. This section is always executed, even if the job fails, so your MySQL resources are removed and you are not charged for resources you are not using.

In GitLab, after_script runs in a fresh shell. To handle this, the script writes the service and stack IDs to deploy.env during the job and reloads them before teardown. This makes sure that even if something fails mid-job, your resources are still cleaned up.

That is the complete CI lifecycle for MySQL: create a stack, add the service, wait, retrieve credentials, smoke-test, and always tear down. Each pipeline run gets a real, isolated service, nothing left running when you are done. For more information about available commands and non-interactive STACKHERO_TOKEN authentication, you may want to explore the full CLI documentation.