Magento 배포 자동화 — GitHub Actions를 접고 Mac→SSH 직결로 간 이유
수동 트리거 + 메인 레포 없음 조합에서 GitHub Actions는 오버엔지니어링. Raycast에서 ssh -t로 서버 deploy.sh를 직접 실행하는 구조와, trap으로 점검모드 잠김·composer install 함정 피하기.
Magento + Hyvä 배포를 자동화하며 GitHub Actions를 진지하게 검토했다가 접고, Mac에서 SSH 직결로 정착한 기록. 수동 트리거 + 메인 레포가 없는 상황이라면 이 구조가 맞다.
TL;DR
[맥] Raycast 버튼 ──ssh -t (직결)──▶ [서버] deploy.sh → 각 모듈/테마 git pull → 빌드
# 맥: Raycast Script Command 한 줄 (사이트는 드롭다운)
ssh -t "$SSH_HOST" "cd '$REMOTE_PATH' && ./deploy.sh"# 서버 deploy.sh — 핵심 2가지
# 1) trap으로 실패해도 점검모드 자동 해제
cleanup() {
local code=$?
if [ "$code" -ne 0 ]; then
echo "✖ 실패(exit $code) — 유지보수 모드 해제"
bin/magento maintenance:disable || true
fi
}
trap cleanup EXIT
# 2) 모듈/테마는 배열 하나가 단일 레지스트리. 새 모듈은 여기 한 줄 추가
GIT_DIRS=(
"app/code/Yohan/ModuleA"
"app/code/Yohan/ModuleB"
"app/design/frontend/Hyva/Hyva_K-SALE"
)
for d in "${GIT_DIRS[@]}"; do git -C "$d" pull --ff-only; done배포 명령 체인은 composer update가 아니라 composer install(lock 그대로, 재현 가능). GitHub Secrets·배포 키·워크플로우 YAML은 전부 없다.
왜 GitHub Actions를 접었나
배포 한 번은 이 긴 명령이다: maintenance:enable → composer install → setup:upgrade → di:compile → tailwind build → static 정리 → static-content:deploy(로케일 9개) → cache:flush → maintenance:disable. 손으로 치기엔 길어 자동화는 필수. 후보는 GitHub Actions vs SSH 스크립트였고(맥 앱은 Raycast alias가 1초에 대체하니 탈락), 한동안 멋있어 보이는 Actions로 기울었다가 접었다.
- 메인 레포가 없다. Magento 루트가 아니라 커스텀 모듈들이 각각 별도 git 레포다. "어느 레포 push에 트리거를 걸지?"부터 애매하고 YAML 둘 곳도 없다.
- 승인 게이트도 자동 트리거도 필요 없다. Actions가 주는 가치(push 자동 트리거, 승인 게이트, 중앙 로그) 중 이 워크플로우에 필요한 게 없다. 트리거는 어차피 의도적 수동이다.
- **그러면 GitHub은 "SSH 한 줄 대신 실행해주는 중계소"**일 뿐. 그 중계 위해 배포 키 발급 + Secrets 등록 + YAML 위치 고민은 순수 오버헤드. 수동 배포 하나에 결재 시스템을 만드는 격이다.
함정 2개
&&체인은 사이트를 점검 모드에 가둔다. 증상: 중간 단계(특히 로케일 9개 static deploy) 하나 실패 → 체인이 멈춰maintenance:disable이 영영 안 돎 → 사이트가 점검 화면에 갇힘. 해결: 스크립트에trap cleanup EXIT(위 TL;DR)를 걸어 실패해도 종료 시 점검 해제.- 프로덕션에서
composer update는 위험. 증상: update는 composer.json 제약 범위 안 의존성을 전부 최신으로 올려, 코어·서드파티가 예고 없이 바뀜. 해결: 재현 가능한composer install(lock 고정). 본인 모듈만 올릴 땐composer update yohan/* --with-dependencies로 타겟팅.
워크플로우는 모듈마다 두는 게 아니다
배포 "트리거"는 소스 레포와 묶여 있지 않다. 모든 모듈을 git pull 하는 주체는 서버의 deploy.sh 하나이고, 그 안의 GIT_DIRS 배열이 "이 사이트는 이 모듈들 + 테마들로 구성된다"는 단일 레지스트리다. 모듈이 10개여도 트리거는 1개, 새 모듈은 배열에 한 줄 추가로 끝. 개별 모듈 레포는 그냥 코드 저장소일 뿐 CI도 워크플로우도 필요 없다.
그래서 GitHub Actions는 언제 쓰나
두 조건 중 하나가 생기면 그때 도입한다: 여러 사람이 배포에 관여해 "누가 언제 배포했는지" 기록·승인이 필요할 때, 또는 push하면 스테이징에 자동 배포되는 파이프라인을 원할 때. 그 전까진 직결이 정답.
배운 것
- 유행하는 도구가 내 상황의 정답은 아니다. 그 도구가 푸는 문제(팀 협업·자동 트리거·추적성)를 내가 안 갖고 있으면 순수 비용이다.
- "정석"을 따르기 전에 그 정석이 푸는 문제가 내게 있는지부터 물어라. 필요 없는 문제에 도구를 들이는 오버엔지니어링이 가장 큰 적이다.
- 손으로 치던
&&체인을 스크립트(trap)로 옮기는 것만으로 점검모드 잠김 사고 하나를 막는다.