Go, Docker 및 Gitlab 쉬운 구성

이것은 무엇에 관한 것인가?



하나의 프로젝트를 준비하는 데 필요한 하나의 서비스 때문에 며칠 전부터 Go 언어를 배우기 시작했습니다. 일부 이미지 처리 및 정적 서버로 전달하는 서비스입니다. 이 서비스에 대한 짧은 사례 연구도 나중에 작성하겠습니다. 👌

저는 컨테이너 팬이기 때문에 개발 환경을 Docker 컨테이너에 넣었습니다. 나는 Go 언어를 많이 좋아하고 MVP를 정말 빨리 작성할 수 있었습니다. 완료했을 때 Gitlab CI를 사용하여 내 앱의 Docker 이미지를 게시하는 것에 대한 영감을 얻기로 결정했습니다. 몇 가지 모범 사례나 주의 사항을 얻을 수 있습니다.

그리고 내가 찾은 복잡한(또는 구식) 구성에 정말 놀랐습니다.



나는 왜 내가 그들과 시간을 잃고 생각? 앱이 Docker 컨테이너에서 실행 중이므로 플랫폼별 빌드를 만들거나 ENV를 Gitlab PATH에 삽입하거나 기타 유사한 이상한 작업을 수행할 필요가 없습니다.

제가 직접 작성해서 여기에 보여드리겠습니다. Go, Docker 또는 마이크로 서비스에 관심이 있는 분들에게 도움이 되었으면 합니다. ✌️

Docker의 간단한 Go 앱



최소한 Docker 또는 컨테이너화에 대한 기본 지식이 있다고 가정합니다. 하지만 많은 초보자들도 관리할 것이라고 생각합니다. 💪
  • 먼저 컨텍스트를 파악할 수 있도록 프로젝트 구조를 보여 드리겠습니다.
  • 그럼 제가 Go 앱 개발 도커 환경을 준비한 방법을 적어보겠습니다.
  • 마지막으로 Gitlab CI를 사용하여 프로덕션 Go 앱 도커 이미지를 빌드하는 방법을 시연하겠습니다.

  • 프로젝트 구조



    오해하지 마세요. 이 구조는 수천 개 중 하나입니다. 그리고 나는 그것이 당신이 사용해야 할 최고의 것 또는 하나라고 말하는 것이 아닙니다. 나는 이것에 익숙해져서 거의 모든 곳에서 사용하고 있습니다.

    구성 파일 컨텍스트로 이동하여 경로의 출처를 알 수 있습니다.

    .
    ├── bin # helper docker-compose scripts
    │   ├── build
    │   ├── go
    │   └── start
    ├── dev-ops
    │   ├── dev.Dockerfile
    │   ├── docker-compose.yml
    │   └── prod.Dockerfile
    ├── README.md
    └── source # go source files
        ├── crop.go
        ├── delivery.go
        ├── go.mod
        ├── go.sum
        ├── main.go
        └── vendor # app's go dependencies source files
    

    Docker에서 개발 진행



    앱의 개발 이미지를 준비해야 합니다.

    더 가볍고 필요한 모든 것을 갖춘 golang alpine image 에서 빌드합니다.

    거기에서 watcher 명령을 볼 수 있습니다. Watcher는 이름에서 알 수 있듯이 파일 변경을 감시.go하고 변경이 감지되면 코드를 빌드하는 도구입니다. 따라서 매번 터미널에서 수동으로 수행할 필요가 없습니다.

    ## ./dev-ops/dev.Dockerfile
    
    FROM golang:1.15-alpine3.12
    
    ## Make app dir for source files
    ## Get git binary so that GO can download dependencies
    RUN mkdir /app \
        && apk add git
    
    ## Set app folder as work directory (default context in Docker container)
    WORKDIR /app
    
    ## get and install watcher
    RUN go get github.com/canthefason/go-watcher \
        && go install github.com/canthefason/go-watcher/cmd/watcher
    
    ## Turn on Go modules, it allows easier dependency managment
    ## Copy files with modules (dependencies) requirements, so that GO knows what to download
    ## Reminds me package.json and yarn.lock in JS development
    ENV GO111MODULE=on
    ADD ./source/go.mod /app
    ADD ./source/go.sum /app
    
    ## pull in all modules (dependencies)
    RUN go mod download
    
    ## Add source files to image work directory
    ADD ./source /app
    
    ## Command which applies when container from this image runs
    CMD ["watcher"]
    

    Watcher와 같은 유사한 Go 도구도 많이 있습니다. 예를 들어 진 또는 신선한. 또는 Nodemon을 사용할 수도 있습니다 (JS 환경에서 온 사람들 🙂)

    그리고 Go 앱으로 Docker 컨테이너를 실행하기 위한 docker-compose 파일이 있습니다.

    ## ./dev-ops/docker-compose.yml
    
    version: '3'
    services:
      ## ids is image delivery service (the service I wrote)
      ids:
        ## name of our image built from dev.Dockerfile above
        image: registry.gitlab.com/dashers/image-delivery-service/ids:dev
        container_name: dasher_ids
        ## sync your local source files with those in container
        volumes:
          - ../source/:/app/
    ...
    

    Docker 및 Gitlab CI에서 프로덕션 진행



    이제 프로덕션 Docker 이미지를 준비합니다.

    다시 이전과 같은 이유로 golang 알파인 이미지에서 빌드됩니다.

    ## ./dev-ops/prod.Dockerfile
    
    FROM golang:1.15-alpine3.12
    
    RUN apk add git
    
    WORKDIR /go/src/gitlab.com/dashers/image-delivery-service
    
    ## same as in dev... add files with dependencies requierments
    ENV GO111MODULE=on
    ADD ./go.mod .
    ADD ./go.sum .
    
    ## pull in any dependencies
    RUN go mod download
    
    ## add source files
    ADD . .
    
    ## our app will now successfully build with the necessary go dependencies included
    ## creates ./main binary executable file
    RUN go build -o main .
    
    ## runs our newly created binary executable
    CMD ["./main"]
    

    쉽죠? gitlab ci config를 살펴보겠습니다.

    여기에서는 BUILD 및 PUBLISH라는 한 단계만 보여주고 있습니다. 그것은 우리prod.Dockerfile를 빌드하고 풀에 사용할 수 있는 Gitlab 컨테이너 레지스트리에 이미지를 게시합니다.

    ## ./gitlab-ci.yml
    
    image: docker:stable
    
    variables:
      # SET DEFAULT BEHAVIOR FOR CI
      # Disable submodules on CI, we are not using submodules
      GIT_SUBMODULE_STRATEGY: none
    # important! we need to say gitlab that we run docker container in docker container..
    services:
      - docker:dind
    
    stages:
      - BUILD and PUBLISH
    
    ## template for build and publish stage
    .build-and-publish_template: &build-and-publish_template
      stage: BUILD and PUBLISH
      ## I version project using commit tags. 
      ## Here I say I want to trigger the stage only if commit tag has format ids-x.x.x
      rules:
        - if: $CI_COMMIT_TAG =~ /^(ids)-[0-9]+\.[0-9]+\.[0-9]+$/
          when: always
        - when: never    
      before_script:
        # accept ids-0.0.1 => 0.0.1 | master => master
        - VERSION=$(if [ "$CI_COMMIT_TAG" == "" ]; then echo $CI_COMMIT_REF_NAME; else echo $CI_COMMIT_TAG |awk -F- '{print $2}'; fi)
        - echo $VERSION
            # login to gitlab container registry
        - echo -n $CI_REGISTRY_PASSWORD | docker login --username $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
      after_script:
        # clean up
        - docker logout $CI_REGISTRY
    
    ## build and publish stage (using the template above)
    ids - build and publish: 
      <<: *build-and-publish_template
      script:
        # build our production image (prod.Dockerfile)
        # registry.gitlab.com/dashers/image-delivery-service/ids:x.x.x
        - >
          docker build \
            --network host \
            --tag ${CI_REGISTRY}/dashers/image-delivery-service/ids:${VERSION} \
            --file ${CI_PROJECT_DIR}/dev-ops/prod.Dockerfile \
            --rm \
            ${CI_PROJECT_DIR}/source
    
        # publish into docker registry
        - docker push ${CI_REGISTRY}/dashers/image-delivery-service/ids:${VERSION}
    

    그게 다야! 🎉

    이제 프로덕션 서버에서 보여드린 것과 유사한 docker-compose를 만들고(볼륨 섹션 없이) gitlab 레지스트리의 이미지를 사용하고 컨테이너를 실행하면 Go 앱이 준비되어 실행됩니다.

    전체 프로젝트의 구성을 보거나 서비스를 사용하려는 경우 Gitlab 저장소here에서 찾을 수 있습니다.

    댓글, 피드백 또는 질문을 자유롭게 하세요 ✌️

    좋은 하루 되세요!

    좋은 웹페이지 즐겨찾기