Go 1.16 embed 패키지로 정적 파일 관리하기
배경
회사 내부 CLI 도구를 Go로 작성하는데, SQL 마이그레이션 파일과 설정 템플릿을 함께 배포해야 했다. 기존에는 별도 디렉토리로 관리했는데, 배포 시마다 파일 누락 이슈가 발생했다.
Go 1.16부터 추가된 embed 패키지를 사용하면 빌드 타임에 정적 파일을 바이너리에 포함시킬 수 있다는 걸 알게 되어 적용했다.
적용 방법
package main
import (
"embed"
"fmt"
"io/fs"
)
//go:embed migrations/*.sql
var migrationFiles embed.FS
//go:embed templates
var templateDir embed.FS
func main() {
// 파일 목록 읽기
entries, _ := migrationFiles.ReadDir("migrations")
for _, entry := range entries {
fmt.Println(entry.Name())
}
// 파일 내용 읽기
content, _ := migrationFiles.ReadFile("migrations/001_init.sql")
fmt.Println(string(content))
}
디렉티브를 변수 바로 위에 작성하면 된다. //go:embed 주석은 반드시 변수 선언 직전에 위치해야 한다.
장점
- 단일 바이너리 배포: 실행 파일 하나만 복사하면 끝
- 파일 누락 방지: 빌드 시점에 파일 존재 여부 검증
- 표준 라이브러리: 외부 의존성 불필요
주의사항
- 대용량 파일은 바이너리 크기를 증가시킴
- 빌드 시점에 파일이 확정되므로, 런타임 수정 불가
.git,.svn등은 자동으로 제외됨
프로젝트 빌드 스크립트가 단순해지고, 배포 관련 문서도 줄일 수 있었다. Go로 CLI 도구 만들 때 유용한 기능이다.