What is the supported way to start a server in .gitlab-ci-yml, so you can run tests against it over http?

I am having a hell of a time trying to start a server, wait until it is up, then run tests against it in a Gitlab CI pipeline. We have a makefile; calling this target with make e2e works perfectly from the command line locally on my Mac:

.PHONY: e2e
e2e: ## Run the default e2e target (localhost) and start & stop the e2e server
	@echo "Starting the e2e server on port $(E2E_LOCAL_PORT)"
	E2E_LOCAL_PORT=$(E2E_LOCAL_PORT) go run integration/e2e/server/server.go & \
		echo $$! > server.pid
	until nc -v -z localhost $(E2E_LOCAL_PORT); do echo "waiting for server..."; sleep 1; done
	@echo "e2e server is responding PID=$$(cat server.pid)"
	@echo "Running e2e tests against ${E2E_BASE_URL}"
	E2E_BASE_URL=$(E2E_BASE_URL) go test -v ./integration/e2e/...
	@-pkill -P $$(cat server.pid)
	@rm server.pid

But when I call this from .gitlab-ci.yml as follows…

integration-tests:
    # ...
    script:
      - make e2e

… it gets stuck at the until.... In the output of the job I just get “waiting for server…” over and over but the server doesn’t start and the tests don’t run. I get no output from nc (I do when I run it on the command line) and no output from either of @echo "e2e server is responding... or @echo "Running e2e tests... is shown.

If I invoke a slightly simpler make target in before_script: it runs, but it starts slowly and the tests fail because the server hasn’t started by the time I get to make e2e-localhost:

start-server-background:
	@echo "Starting the server on port $(E2E_LOCAL_PORT)"
	@E2E_LOCAL_PORT=$(E2E_LOCAL_PORT) \
		DB_PROXY_ENDPOINT=$(DB_PROXY_ENDPOINT) \
		DB_PROXY_PORT=$(DB_PROXY_PORT) \
		DB_PROXY_USER=$(DB_PROXY_USER) \
		DB_PROXY_PASS=$(DB_PROXY_PASS) \
		DB_DATABASE=$(DB_DATABASE) \
		go run integration/e2e/server/server.go &
# ...

e2e-localhost: ## Run the e2e target against default localhost
	@echo "Running e2e tests against ${E2E_BASE_URL}"
	E2E_BASE_URL=$(E2E_BASE_URL) go test integration/e2e
integration-tests:
    # ...
    before_script:
        - make start-server-background
    # ...
    script:
      - make e2e-localhost

I can find no official advice on how to start a server, wait until it has started accepting connections and then run tests against it. What is the supported way to do this?

I build containers running systemd so that services can be started in them, see this post.

You say later in that thread that your solution doesn’t work anymore on newer GitLab versions?

In any case, thanks for the pointer but getting systemd to run under docker on a GitLab Runner sounds like a yak I don’t have the interest in shaving just to run a go http server in the background :frowning: .

It doesn’t work with 16.6 due to this issue so I’m running 16.5 but it’ll work again with 16.7 as the fix has been merged.

It was worth shaving this yak for me since I have lots of Ansible roles that start services using systemd and I wanted to use molecule to automatically test them using GitLab CI.