Since I started another repository for the SnailLife Genome Lab, I knew I’d want to test it against a running SnailLife server. I have some cli tests running against a server as well, but those are in the same repository and in that case I spin up the server and manage the process in the testing code itself.
I have worked with Docker a bit, but never in terms of setting up anything like this from scratch. Everyone says containers are meant to “just work”, but it took me days of debugging and experimentation to even get my mysql container and my server container to talk to each other and run database migrations. But once that was done it felt like I was mostly over the hump. Here is what my initial setup looks like.
I created a deploy/srv directory in my repo’s existing setup dir and put the following files in it:
deploy.shdocker-compose.ymlDockerfilewait-for-it.sh
Docker Compose
I am using Docker Compose to spin up three services: mysql, my SnailLife server, and adminer (for local debugging purposes).
My docker-compose.yml looks like this:
version: '3.1'
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'root'
MYSQL_DATABASE: 'snaillifego'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'root'
ports:
- 3306:80
snaillifesrv:
build: .
restart: always
environment:
MYSQL_HOST: 'db'
MYSQL_ROOT_PASSWORD: 'root'
SNAILLIFESRV_DEFAULT_ARGS: 'serve'
depends_on:
- db
ports:
- 49101:49101
adminer:
image: adminer
restart: always
ports:
- 8888:8080The Dockerfile looks like this:
FROM golang:1.12-stretch
RUN go version
RUN go get -u github.com/pressly/goose/cmd/goose
RUN apt-get update
RUN apt-get install -y git mysql-client
RUN git clone https://gitlab.com/drakonka/gosnaillife.git
WORKDIR gosnaillife/cmd/snaillifesrv
EXPOSE 49101
RUN go install
WORKDIR ../../migrations
CMD /bin/bash ../setup/deploy/srv/deploy.shAnd the deploy.sh looks like this:
#!/usr/bin/env bash
ls -l
/bin/bash ../setup/deploy/srv/wait-for-it.sh db:3306 -t 120
echo getting goose status...
goose mysql "root:root@tcp(db:3306)/snaillifego?parseTime=true" status
echo running migrations...
goose mysql "root:root@tcp(db:3306)/snaillifego?parseTime=true" up
echo starting server...
if [ -n "$SNAILLIFESLV_ARGS" ]; then
echo found args to pass to snaillifesrv
ARGS=${SNAILLIFESRV_ARGS}
else
echo using default args
ARGS=${SNAILLIFESRV_DEFAULT_ARGS}
fi
echo running snaillifesrv with args: $ARGS
snaillifesrv $ARGSThis should, I hope, let me start my server in different modes - like live mode or test mode, and also add any other arguments I want to run certain migrations, disable default seeding, etc.
I then added a deploy job to my gitlab-ci to deploy the SnailLife server docker image to my Gitlab registry (with help from this StackOverflow answer)
deploy_server_image:
stage: deploy
image: docker
services:
- docker:dind
script:
- docker version
- apk add --no-cache py-pip python-dev libffi-dev openssl-dev gcc libc-dev make
- pip install docker-compose
- cd $CI_PROJECT_DIR/setup/deploy/srv
- docker-compose build
- docker build -t $CI_REGISTRY_IMAGE:latest .
- "[[ -z $CI_BUILD_TAG ]] && exit 0"
- docker tag $CI_REGISTRY_IMAGE:latest $CI_REGISTRY_IMAGE:$CI_BUILD_TAG
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
- docker push $CI_REGISTRY_IMAGE:$CI_BUILD_TAGI am not using this for anything yet and I am sure I’ll have to debug other issues when I do, but this is a start and now when I do have tests that require a SnailLife server I should be able to use my prebuilt Docker image to do so in other repositories. I am not yet sure how I’ll handle spinning up the mysql service yet, since my docker-compose.sh wouldn’t be available in the other repository. Maybe I will duplicate it as needed or try to host it in some shared location that is reusable by multiple repos? I guess we will see.