개발자의 오르막
Go, Makefile, Docker로 프로젝트 셋팅 및 빌드 정보 활용하기 본문
Keyword
golang , build , makefile , docker
Overview
실무에서 프로젝트를 구축할 때, 빌드 자동화, 버전관리 등에 대한 작업을 해야한다.
또한 배포할 때 우리가 빌드했던 프로젝트를 이미지화해서 원하고자 하는 버전을 서버에 배포할 수 있다. 이러한 작업들을 도와주는 Tool 이 바로 Makefile 과 Docker 이다.
- Makefile
- Dockerfile
Golang 프로젝트를 생성하고, Makefile 과 Dockerfile 을 활용해서 간단한 Golang 어플리케이션을 생성해 본다.
Go 프로젝트 실습
1. Go 프로젝트 디렉터리 생성
2. go 모듈 생성
Go module 은 go 패키지들의 종속성을 관리하는 패키지 관리 시스템이다.
go mod init {프로젝트 디렉터리명}
- 최초 디렉터리에서 go.mod 를 설치하기 위해 위의 명령어를 실행한다.
- go.mod 파일이 생성된다.
3. Go Application 실행 파일 생성
Go 에서 실행파일은 main package 의 *.go 파일이다.
Go 언어의 모든 코드는 반드시 패키지 선언으로 시작해야 한다.
main 패키지는 프로그램 시작점을 포함하는 특별한 패키지이다.
- watcher.go
package main
func main() {
}
- 실제로 main 패키지에 없이 코드상으로만 package main 을 명시하기만 하면 정상적으로 실행되지만 main 를 생성하여 *.go 파일을 만드는 것을 추천한다.
- 실행파일 watcher.go 에 코드가 많아질 경우 같은 main package 안의 .go 파일의 import 가 가능하기 때문이다.
- watcher.go 에서 Go 애플리케이션을 실행할 수 있다.
4. Build에 필요한 파일 생성
Build 를 하기에 앞서 해당 빌드 정보를 버전관리할 수 있도록 활용하는 방법이 있다.
- 현재 빌드하는 Go 모듈의 버전을 version 1.x.x 로 표기하기를 원한다.
- Go 모듈을 빌드하는 작업을 자동화하기 위해 Makefile 을 활용한다.
- Makefile 은 linux 상에서 반복적으로 발생하는 컴파일을 쉽게하기 위해서 사용하는 make 프로그램의 설정 파일이다.
- Makefile 을 통해 다양한 버전 정보, 빌드 옵션을 make 명령어로 자동화할 수 있다.
Makefile
Makefile 은 linux 상에서 반복적으로 발생하는 컴파일을 쉽게하기 위해서 사용하는 make 프로그램의 설정 파일이다.
Makefile 을 통해 다양한 버전 정보, 빌드 옵션을 make 명령어로 자동화할 수 있다.
Makefile 은 위의 이미지와 같이 해당 프로젝트 최상단에 Makefile 을 생성한다.
- build.num 파일을 생성한다.
0
- version.txt 파일을 생성한다.
1.0
- Makefile 예시
CC=go
PROJECT_PATH=$(shell pwd)
PROJECT_NAME=sample
MODULE_NAME=sample
TARGET_DIR=bin
VERSION_FILE=version.txt
VERSION=$$(cat version.txt)
BUILD_NUM_FILE=build_num.txt
OUTPUT=$(PROJECT_PATH)/$(TARGET_DIR)/$(MODULE_NAME)_$(VERSION).$$(cat $(BUILD_NUM_FILE))
MAIN_DIR=/main
LDFLAGS=-X main.BUILD_TIME=`date -u '+%Y-%m-%d_%H:%M:%S'`
LDFLAGS+=-X main.GIT_HASH=`git rev-parse HEAD`
LDFLAGS+=-X main.BUILD_NUMBER=$$(cat $(BUILD_NUM_FILE))
LDFLAGS+=-X main.VERSION_NUMBER=$$(cat $(VERSION_FILE))
LDFLAGS+=-s -w
all: clean sample
#go build -ldflags "$(LDFLAGS)" -o ${OUTPUT} .
sample:
@echo $$(($$(cat $(BUILD_NUM_FILE)) + 1 )) > $(BUILD_NUM_FILE)
CGO_ENABLED=0 GOOS=linux go build -ldflags "$(LDFLAGS)" -o $(OUTPUT) $(PROJECT_PATH)$(MAIN_DIR)
cp $(OUTPUT) ./docker/$(MODULE_NAME)
clean:
rm -f $(PROJECT_PATH)/$(TARGET_DIR)/$(MODULE_NAME)_$(VERSION)*
- Makefile 은 최상단에 사용할 변수들을 선언한다.
- CC 는 Makefile 에서 goalng compiler 를 의미한다.
- TARGET_DIR 은 해당 Makefile 로 만든 bulid 파일을 보관할 디렉터리를 의미한다.
- MAIN_DIR 은 go 어플리케이션에서 패키징할 패키지를 의미한다.
- LDFLAGS 는 golang 의 build 옵션으로 빌드 정보를 담아주는 역할을 한다.
- OUTPUT 은 go 어플리케이션을 패키징할 때 생성되는 파일의 위치이다.
- 그 후 매크로로 등록할 키워드와 명령어를 입력해준다.
- all : make all 명령어를 통해 all 에 표기된 clean 과 reporter 를 실행시켜준다.
- $(BUILD_NUM_FILE) : 다른 키워드가 실행되기 전에 먼저 실행되는 명령어이다.
- reporter : build 번호를 업데이트하며 go 프로젝트의 빌드 명령어를 수행한다.
- reporter 에서 생성되는 파일은 배포를 용이하게 하기 위해 /docker 디렉터리에 복사해준다.
- clean : 기존 build 했던 파일이 있는 디렉터리는 삭제한다.
- make 키워드를 해당 프로젝트 위치에서 실행시키면 Makefile 로 실행되는 명령어에 대한 로그와 함께 /bin/reporter실행파일이 생성됨을 알 수 있다.
Dockerfile
다음은 Dockerfile 을 작성해봅시다. 앞서 Makefile 로 생성한 실행파일을 서버환경에서 배포하기 위한 작업을 자동화해주는 것이 Dockerfile 입니다.
Docker 와 관련된 파일이 여러개가 될 수 있으니, docker 디렉터리를 생성해서 그 하위에 Dockerfile 을 생성해줍니다.
Docker 의 장점은 위에서 생성된 실행파일만을 서버에 배포하여 실행시키기 때문에 서버에 소스코드와 같은 파일 없이 배포할 수 있어 경량화를 유지할 수 있습니다.
Dockerfile 구문 및 옵션
- Dockerfile
FROM alpine
MAINTAINER jake <arneg0shua@gmail.com>
ENV APP_UID 2001
ENV APP_USER gig
ENV APP_GROUP gig
ENV API_LOG_PATH /home/gig/log/reporter.log
ENV API_PORT 8085
RUN apk add curl
# PID 2001로 gig User 생성
RUN adduser $APP_USER -h /home/$APP_USER -u $APP_UID -D
# gig에서 작업
WORKDIR /home/gig
USER gig
RUN mkdir /home/gig/log && chmod -R 777 /home/gig/log
COPY ./reporter /home/gig/reporter
CMD /home/gig/reporter
EXPOSE 8081
EXPOSE 443
- APP_UID : 사용자 식별자
- FROM : Docker Base Image (기반이 되는 이미지, <이미지 이름>:<태그> )
- MAINTAINER : 메인테이너 정보 (작성자 정보)
- RUN : Shell Script 또는 명령을 실행
- CMD : 컨테니어가 실행되었을 때 명령이 실행
- LABEL : 라벨 작성 (docker inspect 명령으로 label 확인 가능)
- EXPOSE : 호스트와 연결할 포트 번호를 설정
- ENV : 환경변수 설정
- ADD : 파일 / 디렉터리 추가
- COPY : 파일 복사
- ENTRYPOINT : 컨테니어가 시작되었을 때 스크립트 실행
- VOLUME : 볼륨 마운트
- USER : 명령 실행할 사용자 권한 지정
- WORKDIR : “RUN” , “CMD” , “ENTRYPOINT” 명령이 실행될 작업 디렉터리
- ARG : Dockerfile 내부 변수
- ONBUILD : 다른 이미지의 Base Image 로 쓰이는 경우 실행될 명령 수행
- SHELL : Default Shell 지정
이로써 우리는 Dockerfile 을 통해 도커 이미지를 생성할 수 있다.
그러나 우리는 도커 build 명령어부터 도커 Repository 에 이미지를 push 하는 것까지 명령어를 실행시켜줘야 한다.
이 부분은 shell script 를 통해 자동화를 한다.
Docker 쉘 스크립트 파일
- make_docker.sh
#!/bin/bash
BUILD_NUM=$(cat ../build_num.txt)
APP_VERSION=$(cat ../version.txt)
TARGET_VERSION="$APP_VERSION.$BUILD_NUM"
target="kjuiop/reporter"
function usage() {
echo 'Usage: ./make_docker.sh'
echo 'example: ./make_docker.sh'
echo 'or'
exit 1
}
function question() {
# 아래의 $1 은 이 함수의 파라미터 임.
while true; do
read -p "$1" yn
case $yn in
yes ) break;;
y ) break;;
no ) exit;;
n ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
}
question "Do you want to DOCKET BUILD to [$target:$TARGET_VERSION]? (yes/no) "
echo "========================================"
echo "BUILD_NUM : ${BUILD_NUM}"
echo "APP_VERSION : ${APP_VERSION}"
echo "TARGET_VERSION : ${TARGET_VERSION}"
echo "========================================"
docker build -f Dockerfile --tag $target:$TARGET_VERSION .
docker build -f Dockerfile --tag $target:latest .
question "Do you want to PUSH to [$target:$TARGET_VERSION]? (yes/no) "
docker push $target:$TARGET_VERSION
docker push $target:latest
- make_docker.sh 파일을 실행하기 위해서는 권한 부여가 필요하다. chmod 777 ./make_docker.sh
- make_docker.sh 파일을 실행하면 도커 이미지가 원격 레파지토리로 push 된다.
Reference
'GoLang' 카테고리의 다른 글
Golang 2차원 배열 문제를 통한 array, slice 의 개념정리 (0) | 2023.05.06 |
---|---|
Golang Logrus 로 Json Logging 하기 (0) | 2022.11.03 |
Golang 과 TDD (0) | 2022.10.02 |
golang과 Docker로 환경변수 제어하기 (0) | 2022.08.23 |
GoLang 의 포인터 (0) | 2022.07.03 |