Gitlab-ci: build go app with docker as a docker image

Preparations

[TO BE UPDATED LATER]

My gitlab-ci.yml

variables:
  PACKAGE_PATH: /go/src/gitlab.com/[username_for_gitlab]/[project_name]

  # https://docs.gitlab.com/ee/ci/docker/using_docker_build.html
  CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
  CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest

stages:
  - dep
  - test
  - build

# A hack to make Golang-in-Gitlab happy
.anchors:
  - &inject-gopath
      mkdir -p $(dirname ${PACKAGE_PATH})
      && ln -s ${CI_PROJECT_DIR} ${PACKAGE_PATH}
      && cd ${PACKAGE_PATH}

dep:
  stage: dep
  image: golang:1.13.1-alpine
  before_script:
    - *inject-gopath
  script: go mod tidy && go mod vendor
  artifacts:
    name: "vendor-$CI_PIPELINE_ID"
    paths:
      - vendor/
    expire_in: 1 hour

test:
  stage: test
  dependencies:
    - dep
  image: docker:17
  services:
    - docker:dind
  before_script:
    - *inject-gopath
  script: docker build --target=test .

lint:
  stage: test
  dependencies:
    - dep
  image: docker:17
  services:
    - docker:dind
  before_script:
    - *inject-gopath
  script: docker build --target=lint .

build:
  stage: build
  dependencies:
    - dep
    - lint
    - test
  image: docker:17
  services:
    - docker:dind
  before_script:
    - *inject-gopath
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
registry
  script:
    - docker build --target=release --pull -t $CONTAINER_TEST_IMAGE .
    - docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
    - docker push $CONTAINER_TEST_IMAGE

My Dockerfile

FROM golang:1.13.1-alpine AS build
WORKDIR /go/src/gitlab.com/[username_for_gitlab]/[project_name]
COPY . .
RUN go get -u github.com/jessevdk/go-assets-builder
RUN apk add --no-cache make
RUN make build #some pareparations and after that: go build -i -o ./[path_to_bin] ./cmd/[...]

FROM alpine:3.10 AS release
COPY --from=build /go/src/gitlab.com/[username_for_gitlab]/[project_name]/[path_to_bin] /usr/local/bin/[appname]
RUN apk add --no-cache make bash curl tzdata
EXPOSE 3000 3001
ENTRYPOINT ["/usr/local/bin/[appname]"]

FROM golang:1.13.1-alpine AS test
ENV CGO_ENABLED=0
WORKDIR /go/src/gitlab.com/[username_for_gitlab]/[project_name]
COPY . .
RUN apk add --no-cache make bash
RUN make test

FROM golangci/golangci-lint:v1.20 AS lint
WORKDIR /go/src/gitlab.com/[username_for_gitlab]/[project_name]
COPY . .
RUN make lint-full

# to check things locally
# docker build --target=check_container .
# docker images
# docker run -it  /bin/bash
FROM golang:1.13.1-alpine AS check_container
WORKDIR /go/src/gitlab.com/[username_for_gitlab]/[project_name]
COPY . .
RUN apk add --no-cache make bash
RUN /bin/bash

FROM release

Pulling from your private registry

Create deploy token as described here.
After that, you can do this:

docker login -u [deploy_username] -p [deploy_token] registry.gitlab.com
docker pull registry.gitlab.com/[username_for_gitlab]/[project_name]:master
docker run -d --name [container_name_you_like] --env-file [path-to-.env] --net host --rm registry.gitlab.com/[username_for_gitlab]/[project_name]:master

Useful links:
https://dev.to/hypnoglow/how-to-make-friends-with-golang-docker-and-gitlab-ci-4bil
https://docs.gitlab.com/ee/ci/docker/using_docker_build.html
https://medium.com/@tonistiigi/advanced-multi-stage-build-patterns-6f741b852fae
https://docs.gitlab.com/ee/ci/yaml/ (full description of gitlab-ci.yml)
https://about.gitlab.com/blog/2017/11/27/go-tools-and-gitlab-how-to-do-continuous-integration-like-a-boss/
https://gitlab.com/hypnoglow/example-go-docker-gitlab/blob/master/.gitlab-ci.yml
Somewhat useful:
https://blog.lwolf.org/post/how-to-build-tiny-golang-docker-images-with-gitlab-ci/
https://angristan.xyz/build-push-docker-images-gitlab-ci/
https://docs.gitlab.com/ee/user/packages/container_registry/#use-images-from-gitlab-container-registry
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-centos-7 (it says to do sudo usermod -aG docker username to avoid sudo on every docker command invokation)
https://gitlab.com/[username_for_gitlab]/[project_name]/-/ci/lint (validate your gitlab-ci.yml)
https://blog.boatswain.io/post/build-go-project-with-gitlab-ci/

LEAVE A COMMENT