Skip to content

기획서: prego-docker GitHub Actions 기반 멀티아키텍처 이미지 빌드 및 Docker Hub 푸시

목적: prego-docker GitHub 레포지토리를 기준으로, 공식 frappe_docker APPS_JSON 빌드 방식을 사용해 Frappe ERPNext v15 + HRMS 커스텀 이미지를 GitHub Actions로 빌드하고 Docker Hub(iamfork/prego-erpnext)에 멀티아키텍처(linux/amd64, linux/arm64)로 푸시하는 기능 개발을 위한 기획·요구사항·산출물을 정의한다.
코드 생성 없음 — 기획·설계·트리·워크플로우 명세만 정리.


1. prego-docker 레포지토리 역할 및 범위

구분내용
Base 레포prego-docker — Docker 관련 이미지 빌드·설정커스텀 앱 정의를 관리하는 전용 GitHub 레포지토리.
역할(1) Frappe/ERPNext/HRMS 등 앱 조합 정의(apps.json), (2) 공식 frappe_docker 빌드 파이프라인 활용, (3) GitHub Actions로 빌드·푸시 자동화, (4) 향후 custom app·다른 이미지 변형 추가 시 단일 진입점.
비범위Ansible 배포·Pulumi 인프라·앱 소스 코드 개발 — 각각 prego-ansible, prego-pulumi, Prego(메인) 등 별도 레포.

2. 아키텍처 제약사항 (필수 준수)

제약설명
Dockerfile 금지수동 Dockerfile에서 bench get-app·bench build를 직접 호출하는 방식은 사용하지 않는다.
공식 파이프라인frappe_docker 리포의 images/custom/Containerfile 빌드 파이프라인을 사용한다.
앱 정의설치 앱은 apps.json으로만 정의한다.
ERPNext·HRMS 필수apps.json에 ERPNextHRMS를 명시적으로 포함한다.
멀티아키텍처linux/amd64, linux/arm64 두 플랫폼을 지원한다.
푸시 대상Docker Hub iamfork/prego-erpnext (단일 레포, 태그로 버전 구분).

3. 목표 저장소 트리 (구현 시 산출물)

prego-docker 레포 루트 기준으로, 구현 후 갖춰질 구조는 아래와 같다.

.
├── apps.json
├── .dockerignore
├── README.md
└── .github/
└── workflows/
└── docker-build.yml
  • apps.json: 설치할 앱(ERPNext, HRMS)의 url·branch 정의. 빌드 시 Base64 인코딩되어 APPS_JSON_BASE64 빌드 인자로 전달.
  • .dockerignore: 불필요한 파일(예: .git, 문서, 로컬 스크립트) 제외로 빌드 컨텍스트·캐시 효율화.
  • README.md: 빌드 원리, 필수 GitHub Secrets, 멀티아키텍처 동작, Hetzner CPX(amd64)에서 사용 방법 설명.
  • .github/workflows/docker-build.yml: 트리거·QEMU·buildx·로그인·Base64 인코딩·빌드·푸시·태그 전략을 정의하는 워크플로우.

frappe_docker Containerfile 위치: 워크플로우에서 **공식 frappe_docker 리포의 images/custom/Containerfile**을 참조해야 하므로, (1) 해당 파일을 prego-docker에 복사해 두거나, (2) checkout 시 frappe_docker를 서브모듈/별도 checkout으로 가져와 file: 경로를 그쪽으로 지정하는 방식 중 하나로 구현. 기획 단계에서는 구현 시 결정 사항으로 남긴다.


4. apps.json 내용 (필수 정의)

빌드 시 사용할 앱 목록. 순서: ERPNext → HRMS(의존성 순). Frappe는 bench init에 포함되므로 목록에 넣지 않는다.

urlbranch
ERPNexthttps://github.com/frappe/erpnextversion-15
HRMShttps://github.com/frappe/hrmsversion-15

JSON 구조 예시 (구현 시 그대로 사용 가능):

[
{
"url": "https://github.com/frappe/erpnext",
"branch": "version-15"
},
{
"url": "https://github.com/frappe/hrms",
"branch": "version-15"
}
]
  • Private 리포 사용 시: url에 Personal Access Token을 넣지 말고, 빌드 시점에만 환경변수 등으로 주입하는 방식 권장. GitHub Actions에서는 Secrets로 관리.
  • 버전 변경: version-16 등으로 올릴 때는 branch 값과 아래 빌드 인자 FRAPPE_BRANCH를 함께 맞춘다.

5. 빌드 인자 (Build Args)

인자설명
APPS_JSON_BASE64워크플로우에서 생성apps.json 내용을 Base64 인코딩한 문자열. GitHub Actions 단계에서 base64 -w 0 apps.json(Linux) 또는 호환 방식으로 생성 후 GITHUB_ENV 또는 build-arg로 전달.
FRAPPE_BRANCHversion-15Frappe 프레임워크 브랜치. ERPNext·HRMS 브랜치와 동일하게 유지.
PYTHON_VERSION3.11Python 버전. Frappe v15 호환.

6. GitHub Actions 워크플로우 설계 (docker-build.yml 요구사항)

구현 시 작성할 워크플로우가 충족해야 할 요구사항만 정리. 실제 YAML 코드는 구현 단계에서 작성.

6.1 트리거

트리거동작
push (branches)기본 브랜치(예: main) 푸시 시 빌드·푸시 실행.
(선택) tag pushv* 시맨틱 태그 푸시 시 해당 버전 태그로 이미지 푸시. 구현 시 workflow_dispatch 등 추가 가능.

6.2 필수 단계 (순서)

순서단계액션/내용
1Checkoutactions/checkout@v4 — prego-docker 레포 체크아웃.
2Set up QEMUdocker/setup-qemu-action@v3 — linux/arm64 등 비호스트 아키텍처 에뮬레이션.
3Set up Docker Buildxdocker/setup-buildx-action@v3 — 멀티플랫폼 빌드용 buildx.
4Login to Docker Hubdocker/login-action@v3. username: secrets.DOCKERHUB_USERNAME, password: secrets.DOCKERHUB_TOKEN.
5Encode apps.jsonAPPS_JSON_BASE64=$(base64 -w 0 apps.json) (Linux Runner 기준). 출력을 GITHUB_ENV에 넣어 후속 단계에서 build-arg로 사용.
6Build and Pushdocker/build-push-action@v5. context·file(Containerfile 경로)·platforms·push·tags·build-args 설정.

6.3 Build-Push 설정 요구사항

항목
context. (또는 Containerfile이 있는 쪽에 맞춘 경로).
filefrappe_docker의 images/custom/Containerfile을 쓰는 경로(복사본이면 ./Containerfile 등).
platformslinux/amd64,linux/arm64
pushtrue
build-argsAPPS_JSON_BASE64, FRAPPE_BRANCH=version-15, PYTHON_VERSION=3.11
cache프로덕션 권장: type=gha 등으로 빌드 캐시 사용.

6.4 태그 전략

태그조건
latest기본 브랜치(예: main) 푸시 시 항상 푸시.
git commit SHAiamfork/prego-erpnext:${{ github.sha }} — 재현성·롤백용.
시맨틱 버전Git 태그가 v*(예: v1.0.0)일 때 iamfork/prego-erpnext:$version 푸시. (태그 이벤트 트리거 시.)

구현 시 브랜치 푸시만 할 경우 latest + SHA, 태그 푸시 시 v1.0.0 형태 태그 추가.

6.5 프로덕션 관행

항목내용
Build cachebuild-push-action에 cache-from/cache-to 또는 type=gha 사용으로 재빌드 시간 단축.
Fail fast불필요한 단계 최소화, 실패 시 즉시 종료.
SecretsDOCKERHUB_USERNAME, DOCKERHUB_TOKEN만 사용. 로그에 노출되지 않도록 액션 기본 동작 유지.

7. 필수 GitHub Secrets

Secret 이름설명설정 위치
DOCKERHUB_USERNAMEDocker Hub 로그인 아이디 (예: iamfork).GitHub 레포 → Settings → Secrets and variables → Actions.
DOCKERHUB_TOKENDocker Hub Access Token (Account Settings → Security → New Access Token). 비밀번호 대신 토큰 사용.동일.

README에는 “푸시 전 Docker Hub Secrets 설정 필요” 및 위 두 이름을 명시한다.


8. 멀티아키텍처 동작 방식

항목내용
빌드QEMU로 arm64 에뮬레이션, buildx로 linux/amd64·linux/arm64 동시 빌드.
매니페스트build-push-action이 매니페스트 리스트를 자동 생성해 Docker Hub에 푸시. 하나의 태그에 두 플랫폼이 연결됨.
Pull 시docker pull iamfork/prego-erpnext:latest 시 클라이언트의 OS/아키텍처에 맞는 이미지가 자동 선택.

9. Hetzner CPX(amd64)에서의 사용

항목내용
아키텍처Hetzner CPX 인스턴스는 linux/amd64.
사용법docker pull iamfork/prego-erpnext:latest (또는 :v1.0.0, :<sha>). 아키텍처 지정 불필요.
자동 선택Docker가 매니페스트를 보고 amd64 이미지를 자동으로 받아온다.
Ansible 연계prego-ansible의 frappe_bench_image 등에서 해당 이미지 태그를 지정하면, 노드(CPX)에서 pull 시 amd64 레이어만 받게 됨. docker-hub-stack-ansible-deploy-plan.md와 동일한 사용 패턴.

10. .dockerignore 요구사항

  • 목적: 빌드 컨텍스트 경량화, 캐시 효율, 보안(불필요 파일 제외).
  • 포함 권장 제외 대상: .git, README.md, docs, .github, *.md, 로컬 테스트 스크립트 등. apps.json은 빌드 인자로 Base64 전달하므로 컨텍스트에 반드시 넣을 필요는 없지만, 인코딩 단계에서 읽기 위해 레포에는 포함. (컨텍스트에 포함해도 무방.)
  • 구현 시 frappe_docker 쪽에서 복사한 파일만 쓸 경우, prego-docker 루트 기준으로 최소한의 파일만 컨텍스트에 들어가도록 .dockerignore를 작성.

11. README.md 요구사항 (구현 시 포함할 설명)

섹션내용
빌드가 동작하는 방식apps.json → Base64 → frappe_docker custom Containerfile + build-args → buildx 멀티플랫폼 빌드 → Docker Hub 푸시. 수동 Dockerfile/bench get-app 미사용 이유 간단히.
필수 GitHub SecretsDOCKERHUB_USERNAME, DOCKERHUB_TOKEN 설명 및 Docker Hub에서 토큰 생성하는 위치 안내.
멀티아키텍처linux/amd64·linux/arm64 지원, 단일 태그로 pull 시 자동 선택.
Hetzner CPX(amd64)docker pull iamfork/prego-erpnext:latest로 사용 가능, 아키텍처 지정 불필요.
(선택)로컬에서 buildx로 동일 이미지 빌드하는 방법, 태그 규칙(latest/SHA/시맨틱).

12. frappe_docker Containerfile 참조 방식 (구현 시 선택)

방식장점단점
A. 복사 유지워크플로우가 단순. 레포 자체에 Containerfile 포함.frappe_docker 업스트림 변경 시 수동 반영.
B. 서브모듈/checkout업스트림 변경 반영 용이.워크플로우에서 두 레포 체크아웃·경로 처리 필요.
  • 권장: 초기에는 **A(복사)**로 시작해, images/custom/Containerfile을 prego-docker에 복사해 두고, 필요 시 주기적으로 frappe_docker와 동기화. 안정화 후 B 검토 가능.

13. 기존 기획서와의 연계

문서연계 내용
frappe-docker-hrms-custom-image-build-plan.md로컬 빌드·apps.json·layered/custom·buildx·멀티아키텍처 가이드(§10)와 동일한 원칙. 본 기획은 **CI(GitHub Actions)**에서 동일 파이프라인을 실행하도록 옮긴 것.
docker-hub-stack-ansible-deploy-plan.mdAnsible에서 사용할 앱 이미지가 iamfork/prego-erpnext:*. 배포 패턴 A(서버 분리)·이미지 소스 전략과 일치.
naming-conventions.md이미지명·태그 규칙은 프로젝트 접두사·소문자·하이픈 등과 맞출 것.
IMPLEMENTATION_INDEX.md구현 완료 후 “prego-docker: GitHub Actions 멀티아키텍처 빌드·Docker Hub 푸시” 항목 추가 권장.

14. 구현 시 체크리스트 (코드 작성 단계용)

  • prego-docker 레포에 apps.json 추가 (ERPNext + HRMS, version-15).
  • frappe_docker images/custom/Containerfile 복사 또는 참조 방식 결정 후, 워크플로우에서 사용할 file 경로 확정.
  • .github/workflows/docker-build.yml 작성: checkout, QEMU, buildx, Docker Hub login, apps.json Base64 인코딩, build-push(cache, platforms, tags, build-args).
  • 태그 전략 반영: latest, github.sha, (선택) Git tag 기반 시맨틱 버전.
  • .dockerignore 작성.
  • README.md 작성: 빌드 원리, Secrets, 멀티아키텍처, Hetzner CPX 사용법.
  • GitHub Secrets DOCKERHUB_USERNAME, DOCKERHUB_TOKEN 설정 안내 및 실제 설정 후 main 푸시로 빌드·푸시 검증.
  • Docker Hub에서 iamfork/prego-erpnext:latest 태그에 linux/amd64, linux/arm64 표시 확인.
  • (선택) IMPLEMENTATION_INDEX.md에 prego-docker 워크플로우 링크 추가.

15. 확장 가능 방향 (후속)

방향설명
태그 기반 시맨틱 버전v1.0.0 푸시 시 자동으로 iamfork/prego-erpnext:1.0.0 푸시.
staging / production 분리브랜치별 또는 환경별로 다른 태그/레포로 푸시.
Hetzner 자동 배포빌드 성공 후 SSH 또는 Ansible 호출로 특정 노드에 이미지 pull·재기동.
SKU별 이미지Core / Premium / Enterprise 등 앱 조합별로 apps.json·이미지명 분리.

다음 단계: 이 기획서를 바탕으로 prego-docker 레포에 apps.json, .github/workflows/docker-build.yml, .dockerignore, README.md를 구현한다.
관련 문서: frappe-docker-hrms-custom-image-build-plan.md, docker-hub-stack-ansible-deploy-plan.md, naming-conventions.md, IMPLEMENTATION_INDEX.md.

Help