I'm trying to have google datastore emulator run as part of the CI. I've added a services
section to .gitlab-ci.yml
but there's an error.
Here's the full configuration YAML:
image: python:3.9-slim
# Change pip's cache directory to be inside the project directory since we can
# only cache local items.
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
# Pip's cache doesn't store the python packages
# https://pip.pypa.io/en/stable/reference/pip_install/#caching
#
# If you want to also cache the installed packages, you have to install
# them in a virtualenv and cache it as well.
cache:
paths:
- .cache/pip
variables:
DATASTORE_DATASET: project-007
DATASTORE_EMULATOR_HOST: google-cloud-sdk:8081
DATASTORE_EMULATOR_HOST_PATH: google-cloud-sdk:8081/datastore
DATASTORE_HOST: http://google-cloud-sdk:8081
DATASTORE_PROJECT_ID: project-007
before_script:
- apt-get update && apt-get install -y ffmpeg make
- python --version # Print out python version for debugging
- cd backend
- python -m pip install -r dev-requirements.txt
test:
services:
- name: google/cloud-sdk:latest
command: ["gcloud", "beta", "emulators", "datastore", "start", "--host-port", "0.0.0.0:8080"]
variables:
CLOUDSDK_CORE_PROJECT: project-007
script:
- make test
The error I see in the CI logs is:
*** WARNING: Service runner--azerasq-project-26594908-concurrent-0-aababf5d82e87691-google__cloud-sdk-0 probably didn't start properly.
Health check error:
service "runner--azerasq-project-26594908-concurrent-0-aababf5d82e87691-google__cloud-sdk-0-wait-for-service" health check: exit code 1
Health check container logs:
2021-11-25T15:49:31.057994970Z FATAL: No HOST or PORT found
Service container logs:
2021-11-25T15:49:30.783697828Z Executing: /usr/lib/google-cloud-sdk/platform/cloud-datastore-emulator/cloud_datastore_emulator create --project_id=gitlab-ci-plan-free-5-6ef84d /root/.config/gcloud/emulators/datastore
*********
Any ideas how to fix this or a better way to run the datastore emulator in the gitlab CI? Thanks!
Given the emulator runs correctly when you run docker run -it -e CLOUDSDK_CORE_PROJECT=test google/cloud-sdk:latest gcloud beta emulators datastore start --host-port 0.0.0.0:8080
, it's not a problem with your container command. That means that it's an issue within GitLab's runner setup, or within the way that you're using the runner setup. Specifically, how the services health check works.
The issue you're seeing is that the google/cloud-sdk
image has no PORT exposed, because it's meant to be an CLI (not a web app) and the act of exposing a port is a byproduct of the emulator. This means that the services health check can't find a port to check for the container health, and instantly fails. To resolve this issue, simply build your own image based on the SDK, and expose port 8080, as such:
FROM google/cloud-sdk
EXPOSE 8080
then update your services block to use that container instead:
services:
- name: $CI_REGISTRY_IMAGE:latest
alias: google-test
command: ["gcloud", "beta", "emulators", "datastore", "start", "--host-port", "0.0.0.0:8080"]
variables:
CLOUDSDK_CORE_PROJECT: project-007
and your service will now pass healthcheck appropriately. Here is the output from my test in a gitlab repo:
Running with gitlab-runner 14.4.0-rc1 (bc99a056)
on blue-5.shared.runners-manager.gitlab.com/default -AzERasQ
Preparing the "docker+machine" executor 01:26
Using Docker executor with image alpine:latest ...
Starting service registry.gitlab.com/patrick/service-test:latest ...
Authenticating with credentials from job payload (GitLab Registry)
Pulling docker image registry.gitlab.com/patrick/service-test:latest ...
Using docker image sha256:954ea7f75a0a88b281d46cbaa1c359e0782268a6c5390a722ebea387893e7a47 for registry.gitlab.com/patrick/service-test:latest with digest registry.gitlab.com/patrick/service-test@sha256:8d240acba0977cc8deea217026d23678e471a5453ffd4dbeeb4197aa1b6e024d ...
Waiting for services to be up and running...
Pulling docker image alpine:latest ...
Using docker image sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18 for alpine:latest with digest alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300 ...
Preparing environment 00:01
Running on runner--azerasq-project-31673063-concurrent-0 via runner-azerasq-shared-1638120050-4cf20e79...
Getting source from Git repository 00:02
$ eval "$CI_PRE_CLONE_SCRIPT"
Fetching changes with git depth set to 50...
Initialized empty Git repository in /builds/patrick/service-test/.git/
Created fresh repository.
Checking out a4825851 as main...
Skipping Git submodules setup
Executing "step_script" stage of the job script
Using docker image sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18 for alpine:latest with digest alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300 ...
$ ping google-test
PING google-test (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.070 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.066 ms