Docker Containers for testing

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:

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:8080

The 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.sh

And 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 $ARGS

This 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_TAG

I 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.

comments powered by Disqus