Setting up multiple containers in github actions

Viewed 1316

I'm trying to set up our CI with github actions. After trying for a couple days to do it on my own, I come here looking for help.

Actually I have a Go API that uses a postgres database and my tests directly call the API, so I need the API and the database to be running for the tests.

Locally I don't have any problem, my API runs in a docker container I build using commands in my Makefile. But I can't get my tests to work on github actions.

Here's my Makefile:

GOCMD=go
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
GOGET=$(GOCMD) get
BINARY_NAME=ATS-user

all: test build

build: 
    $(GOBUILD) -o $(BINARY_NAME) -v
test: 
    $(GOTEST) -v ./...

clean: 
    $(GOCLEAN)
    rm -f $(BINARY_NAME)
run:
    $(GOBUILD) -o $(BINARY_NAME) -v ./...
    ./$(BINARY_NAME)

start_db:
    sudo docker network create network_app
    sudo docker run --name postgresdb --net network_app -p5432:5432 -e POSTGRES_PASSWORD=***** -e POSTGRES_DB=userdb -d postgres

migrate_db:
    migrate -path tests/migrate/ -database postgres://postgres:*****@localhost:5432/userdb?sslmode=disable -verbose up

start_server:
    sudo docker build . -t app
    sudo docker run -p 8080:8080 --net network_app app

remove_db:
    sudo docker container stop postgresdb
    CONTAINER_ID=$(shell sudo docker ps -aqf "name=postgresdb");\
    sudo docker container rm $$CONTAINER_ID

remove_server:
    sudo docker container stop app
    CONTAINER_ID=$(shell sudo docker ps -aqf "name=app");\
    sudo docker container rm $$CONTAINER_ID

And my Dockerfile for the app

FROM golang:1.16-alpine

WORKDIR /app

COPY go.mod ./
COPY go.sum ./

RUN go mod download

COPY . ./

RUN go build -o /mdr

EXPOSE 8080

CMD [ "/mdr" ]

What I do locally is basically make start_db make migrate_db make start_server make test

On github actions I use that:

name: build and test

# Controls when the action will run. 
on:
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "test"
  test:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    #Add services, aka Docker containers that runs in paralell
    services:
      #Name the service
      postgres:
        #Set the Docker image to use, find images on Dockerhub.com
        image: postgres
        # Set environment variables
        env: 
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: *****
          POSTGRES_DB: userdb
        # Expose ports
        ports: 
          - 5432:5432
        # Add some health options to make sure PostgreSQL is running fully before moving on
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
          
          
    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2
      # Sets up and installs Golang
      - name: Setup Go environment
        uses: actions/setup-go@v2.1.3
        with:
          go-version: 1.16
      - name: Get migrate
        run: go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
      - name: migrate DB
        run: make migrate_db
      - name: create network
        run: docker network create network_app
      - name: Connect Postgresdb to network
        run: docker network connect network_app postgres
      - name: Build docker
        run: docker build . --file Dockerfile -t app
      - name: Run docker
        run: docker run -p 8080:8080 app
      # Run tests that are available
      - name: Test
        run: |
          go test -v ./tests/test_routes/
          echo Complete

The actual problem is I can't connect postgres to the created network, but even if that worked, I feel like I shouldn't build my docker container the way I do it in the yml file.

I'm quite lost right now and I've been searching for quite some time so I hope I can get help here.

Thank you for your time, have a nice day.

1 Answers

According to this you don't need any kind of fancy docker network setup for the service container to be reachable, in this example the postgres host just becomes "postgres" if your tests are assuming localhost you could consider a command line flag or env variable that sets the postgres host instead of having it hardcoded

Related