주소가 게시 시점에 굳어 저장되는 구조, 축 링크를 두 번 옮긴 순서, 한글 slug 가 간헐적으로 보인 두 가지 어긋남을 표로 갈랐다. 화면이 실패를 없음으로 그릴 때 작성 도구에서 왜 더 오래 숨는지, Promise.all 이 거절과 던짐에서 다른 경로를 타는 이유를 채웠다. CSS module 이 왜 전역 규칙에 닿지 않는지, 403 과 404 가 원인을 어떻게 좁혔는지도 적었다. link-audit.py 를 감사 Case 의 evidence 로 걸어 배정한 증거 하나를 메웠다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3.9 KiB
kind, slug, title, topic, topicName, project, status, basisVersion, sourceRevision, source
| kind | slug | title | topic | topicName | project | status | basisVersion | sourceRevision | source | ||
|---|---|---|---|---|---|---|---|---|---|---|---|
| CONCEPT | deploying-without-a-registry | 레지스트리 없이 tar 를 import 하는 배포 경로 | only-visible-after-deploying | 배포해 봐야 드러난 것 | TechLog | 게시 전 | k3s + containerd · hyeonworks.com 단일 배포 단위 · 2026-09 시점 | tech-log@2026-09-02 |
|
레지스트리 없이 tar 를 import 하는 배포 경로
이 사이트는 이미지 레지스트리를 쓰지 않는다. 로컬에서 빌드한 이미지를 tar 로 말아 서버에 올리고, 클러스터 안에 일회성 Job 을 띄워 컨테이너 런타임으로 import 한 뒤 이미지 태그를 바꾼다. 이 경로 때문에 빌드 인자와 파일 권한이 배포에서만 드러난다.
관계
- 배포 인자를 빠뜨려 배포본이 존재하지 않는 주소를 불렀다 이 경로에서 빌드 인자가 어떻게 새는지가 그 기록에 있다.
- 컨테이너는 healthy 였고 SPA 가 부팅에 필요한 파일 하나만 403 이었다 이미지 안의 권한이 배포에서 드러난 사건이다.
- 배포 전에 사람이 돌려야 하는 것과 그 함정 이 경로에서 사람이 기억해야 하는 것들이 그 기준에 있다.
본문
레지스트리를 쓰지 않는다
로컬 docker build → docker save | gzip → scp dh-server:/tmp/deploy.tar.gz
→ kube-system 의 containerd import Job → kubectl set image
공개 Hub 는 소스가 들어간 이미지라 쓸 수 없다. k3s 의 containerd 소켓은 root 전용이라 사용자 셸에서 닿지 않는다. 그래서 클러스터 안에 일회성 Job 을 띄워 tar 를 import 한다 — Job 은 클러스터 권한으로 도므로 그 소켓에 닿는다.
배포 단위는 hyeonworks.com 하나이고 서브도메인을 쓰지 않는다. 공개는 /, API 는 /api 다.
빌드 인자는 이미지에 굳는다
이 경로에서 설정은 두 가지 방식으로 들어간다. 런타임 환경 변수는 배포한 뒤에도 바꿀 수 있고, 빌드 인자는 이미지에 굳어 다시 빌드해야 바뀐다.
프론트 이미지가 요구하는 인자는 이만큼이다.
APP_PROFILE=production
VITE_ROUTER_BASE_PATH=/
RUNTIME_API_BASE_URL=https://hyeonworks.com/ ← 빠뜨리면 api.example.com
VITE_BUILD_ID / VITE_COMMIT_SHA / RELEASE_ID
CI_RUNNER_IMAGE=node@sha256:… ← 반드시 @sha256 다이제스트
SOURCE_DATE_EPOCH
넘기지 않으면 기본값이 굳는다. 빌드는 성공하고 이미지도 정상적으로 올라오므로, 잘못된 값은 배포본이 요청을 내보낼 때 처음 드러난다.
백엔드 이미지는 Dockerfile 이 src/ 아래에 있고 RELEASE_VERSION·BUILD_VERSION·GIT_SHA·SOURCE_URL 을 받는다. 태그는 짧은 SHA 일곱 자이고 배포된 것과 맞춰야 한다.
빌드 산출물에 커밋 해시가 들어간다
백엔드 빌드 산출물 이름에 커밋 해시가 들어간다. 작업 트리가 더러우면 해시가 달라져 stale 산출물 검사가 멈추므로, 커밋한 뒤에 빌드를 돌려야 한다.
이 순서는 산출물이 어느 커밋에서 나왔는지를 이름으로 추적하려고 둔 것이다. 그래서 순서를 지키지 않으면 검사가 통과하지 않고, 검사를 끄면 추적이 사라진다.
이 경로가 늦게 알려 주는 것
이미지가 healthy 로 올라오는 것과 사이트가 동작하는 것은 다르다.
| 무엇이 | 언제 드러나나 |
|---|---|
| 컨테이너 안의 파일 권한 | 그 파일을 처음 요청할 때 |
| nginx 가 서빙하기로 한 파일 목록 | 목록에 없는 파일을 요청할 때 |
| 빌드에 굳은 주소 | 배포본이 그 주소로 요청을 낼 때 |
셋 다 헬스 판정을 지난다. 헬스 엔드포인트는 그 파일도 그 목록도 그 주소도 쓰지 않기 때문이다.