How to make MySQL work in your GitHub Actions

GitHub Actions: MySQL service is unhealthy - error while starting

I spent too much time trying to make MySQL service work on GitHub Actions and after hours of googling and configuration tests I’d like to share with you my findings.

If you come to this post from a Google search, you may have already read a ton of tutorials that have this code running MySQL inside your workflow:

services:
  mysql:
    image: mysql:5.7
    env:
      MYSQL_DATABASE: test_db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: rootpassword
    ports:
      - 33306:3306
    options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

Some may have included additional information on why do you need env inside the MySQL service, some may not. But basically, services have stopped automatically receiving all env values from the job-level scope, and you need to copy-paste them manually.

There might be several variations of the ports value.

  1. Here you will need to use 3306 later in your workflow, but depending on your setup you may have port conflicts.
ports:
  - 3306:3306
  1. Here you redefine the local port to 33306. But in this case, you need to be able to redefine the port everywhere in your code.
ports:
  - 33306:3306
  1. Or even a bit more complicated solution, where later in your workflow steps you need to retrieve the port manually using ${{ job.services.mysql.ports['3306'] }}:
ports:
  - 3306

But in my experience, none of those ways worked and I was always receiving this error:

Failed to initialize, mysql service is unhealthy.

It looks like this:

GitHub Actions: "mysql service is unhealthy" error
Ubuntu can’t connect to the MySQL service

It most likely means that a host (ubuntu-20.04) can’t connect to a separate MySQL container that is created using your services:mysql details due to ports issues.

The easiest way to work with MySQL in GitHub Actions

Ever wondered why there are official PostgreSQL and Redis services guides available for you on docs.github.com, but not for MySQL?

That’s because MySQL 5.7 is pre-installed on Ubuntu 18.04 containers (and MySQL 8 on 20 and latest), but not running by default. Here is a related announcement by GitHub. That means you don’t need services:mysql at all, you just need to start the built-in mysql process.

I haven’t found this information in any official docs, but the default MySQL login and password are both root. Update: they have this information in their repository. Here is an example for ubuntu-20.04.

Below is the configuration code I crafted to make MySQL work for me:

env:
  DB_DATABASE: test_db
  DB_USER: root
  DB_PASSWORD: root

steps:
  - name: Set up MySQL
    run: |
      sudo /etc/init.d/mysql start
      mysql -e 'CREATE DATABASE ${{ env.DB_DATABASE }};' -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }}

The use of env variables is not mandatory, but I re-use those values in one of the workflow steps later so that’s why I put them separately.

Here is what you will see in GitHub interface:

Successfully started MySQL

That warning:

Using a password on the command line interface can be insecure.

is valid when you operate with a live/staging database. In my case, I was using MySQL to run tests so it’s not really relevant.

I hope this post and the approach above will help you save hours of googling and debugging various MySQL errors while using Ubuntu environment to run tests or do whatever you need.

By Slava Abakumov

// Be good, have fun, create things.

6 comments

  1. How can i run MYSQL 5.7 ? I tried it with the services:mysql but always MYSQL 8 gets started. If i run without services:mysql it runs but its MYSQL 8 again. I check it via mysql -V.

    1. There are several points here.
      1. You should definitely start using MySQL 8 🙂 This is an opinionated suggestion, I know.
      2. If you need exactly MySQL 5.7 – I’m afraid you need to either use ubuntu-18.04 image specifically, or go the long route: remove MySQL completely, install it again. But this remove-install step will take some time so your test runs or whatever you do via GH Actions will basically start running longer.

      With that said, either consider switching to MySQL 8 or use ubuntu-18.04 which has MySQL 5.7 preinstalled.

      1. OK, that helped me. I work with an CMS that is not 100% fit with MYSQL 8. So i wanted to work with it but i needed to change some modes like NO_ZERO_IN_DATE within MYSQL 8 but didn’t get it done in the workflow. So i decided to do the work on 5.7. Now 5.7 is running and hopefully in future MYSQL 8 will be fully supported. Thanks.

Leave a comment

Your email address will not be published. Required fields are marked *