Skip to main content

A GitLab CI script for Drupal 8 + Docker

In an effort to Automate All the Things, I've been honing in on a project-agnostic, drop-in CI script for GitLab CI, my hosted in-house continuous integration workflow. The goal is to:

  1. Have a single file that I can drop in to new Drupal 8 projects, with the project-specific configuration handled with CI environment variables;
  2. Work toward a fully-automated Docker workflow, where I push successful builds to a private repository (and later, re-start containers with the new image);
  3. Offload one-time build tasks such as CSS compilation and composer installation to the build server, instead of bloating the size of my Docker container with unnecessary tools;
  4. Support for unit (and hopefully soon, functional) testing both out of the box from Drupal and for my own code.

I've gone through a few iterations internally, and the product is posted below. The script assumes it's running inside a Docker CI runner container and the application containers are running as siblings to the runner.

I've also created a public repository for CI-related scripts, to track my improvements over time. Let me know if you've got ideas for improvement.

.gitlab-ci.yml
Code

stages:
  - test
  - spawn
  - phpunit
  - deploy
  - cleanup

build_image:
  cache:
    untracked: true
  script:
    - whoami && docker info && docker-compose -v
    - if [[ -n "$GITHUB_API_KEY" ]]; then composer config -g github-oauth.github.com "$GITHUB_API_KEY"; fi
    - composer install --ignore-platform-reqs
    - docker login -u="${DEPLOY_USER}" -p="${DEPLOY_PW}" -e="${DEPLOY_EMAIL}" "${DEPLOY_SERVER}"
    # This could be improved by https://github.com/BradJonesLLC/gitlab-docker-ci/issues/2
    #- docker run -u $(id -u) -w "${PWD}/web/themes/THEME" --volumes-from=$(docker ps --filter "name=${HOSTNAME}" -q)
    #  my-repository/ruby:2 bash -c "bundle install --path vendor &&
    #  bundle exec compass compile -e production --force"
    - docker-compose -f docker-compose.ci.yml build

spawn_containers:
  stage: spawn
  script:
    - docker-compose -f docker-compose.ci.yml up -d

unit_test:
  stage: phpunit
  script:
    - docker exec -t $(docker-compose -f docker-compose.ci.yml ps -q web)
      su -c '~www-data/html/tests/scripts/unit-testing.sh' -s /bin/bash www-data

deploy:
  stage: deploy
  only:
    - tags
  script:
    - docker tag $(docker inspect --format='{{.Image}}' $(docker-compose -f docker-compose.ci.yml ps -q web)) "$DEPLOY_SERVER"/"$DEPLOY_REPO"
    - docker push "$DEPLOY_SERVER"/"$DEPLOY_REPO"
    - docker rmi "$DEPLOY_SERVER"/"$DEPLOY_REPO"

cleanup:
  stage: cleanup
  when: always
  script:
    - docker logout "${DEPLOY_SERVER}"
    - docker-compose -f docker-compose.ci.yml down --rmi all --volumes
    - composer config -g --unset github-oauth.github.com

Photo