개인적으로 제작하던 간단한 Golang 프로젝트의 컨테이너를 배포하던 와중 이러한 문제를 마주쳤습니다:
Checking SQLite3...
2023/07/06 13:01:29 Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub
해당 문제는 프로젝트가 특정한 라이브러리를 쓰고 있기 때문에 발생합니다.
빌드에서 문제가 되는 해당 라이브러리에서 CGO를 사용하고 있기 때문에 빌드가 되지 않을 것을 알 수 있습니다.
CGO는 이름에서 보이는 것 처럼 C + GO, C의 기능을 빠르게 Go로 바인딩할 수 있도록 Go에서 자체적으로 지원하는 기능입니다.
당연하게도 이런 C 코드를 포함하는 코드를 전체적으로 컴파일하기 위해선 CGO를 포함하도록 컴파일 옵션이 지정되어야 합니다.
저는 프로젝트에서 Base Image로 golang-alpine을 사용 중입니다만, 해당 이미지에선 CGO가 기본값으로 켜져있지 않습니다.
해당 옵션을 활성화하기 위해 CGO_ENABLED 값을 1로 설정해줍니다.
RUN CGO_ENABLED=1 GOOS=linux go build -o TARGET_NAME
하지만, 생각과는 달리 해당 오류가 발생해버리게 됩니다:
Removing intermediate container 4b817f1853d5
---> ebc4f80cc34b
Step 7/11 : RUN CGO_ENABLED=1 GOOS=linux go build
---> Running in 294f5372b5cb
# runtime/cgo
cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in $PATH
The command '/bin/sh -c CGO_ENABLED=1 GOOS=linux go build' returned a non-zero code: 1
오류 내용만 봐도 알 수 있습니다. 툴체인이 없어서 발생하는 문제입니다.
툴체인을 설치해줍시다.
RUN apk add --no-cache --update build-base
해당 툴체인을 설치할 시 크게 문제 없이 컴파일이 완료되는 모습을 볼 수 있습니다.
완성된 Dockerfile은 다음과 같습니다:
FROM golang:alpine AS builder
WORKDIR /app
COPY . .
COPY go.mod .
COPY go.sum .
RUN apk add --no-cache --update build-base
RUN go get -u -d -v
RUN CGO_ENABLED=1 GOOS=linux go build -o TARGET_NAME
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/TARGET_NAME ./
CMD [ "./TARGET_NAME" ]
해당 라이브러리가 요구하는 툴체인을 적절하게 설치해주면 됩니다.