87 lines
4.3 KiB
Markdown
87 lines
4.3 KiB
Markdown
---
|
|
kind: CONCEPT
|
|
slug: deploying-without-a-registry
|
|
title: 레지스트리 없이 tar 를 import 하는 배포 경로
|
|
topic: only-visible-after-deploying
|
|
topicName: 배포해 봐야 드러난 것
|
|
project: TechLog
|
|
status: 게시 전
|
|
basisVersion: k3s + containerd · hyeonworks.com 단일 배포 단위 · 2026-09 시점
|
|
sourceRevision: tech-log@2026-09-02
|
|
source:
|
|
- final/document.md#§1.3
|
|
- final/document.md#§12.2
|
|
---
|
|
|
|
# 레지스트리 없이 tar 를 import 하는 배포 경로
|
|
|
|
이 사이트는 이미지 레지스트리를 쓰지 않는다. 로컬에서 빌드한 이미지를 tar 로 말아 서버에 올리고, 클러스터 안에 일회성 Job 을 띄워 컨테이너 런타임으로 import 한 뒤 이미지 태그를 바꾼다. 이 경로 때문에 빌드 인자와 파일 권한이 배포에서만 드러난다.
|
|
|
|
## 관계
|
|
|
|
- **배포 인자를 빠뜨려 배포본이 존재하지 않는 주소를 불렀다**
|
|
이 경로에서 빌드 인자가 어떻게 새는지가 그 기록에 있다.
|
|
- **컨테이너는 healthy 였고 SPA 가 부팅에 필요한 파일 하나만 403 이었다**
|
|
이미지 안의 권한이 배포에서 드러난 사건이다. 여기서 SPA는 Single-Page Application을 뜻한다.
|
|
- **배포 전에 사람이 돌려야 하는 것과 그 함정**
|
|
이 경로에서 사람이 기억해야 하는 것들이 그 기준에 있다.
|
|
|
|
## 본문
|
|
|
|
<!-- body:start -->
|
|
|
|
## 레지스트리를 쓰지 않는다
|
|
|
|
이 블록은 복사해 실행하는 runbook이 아니라 배포 단계의 순서만 보여 주는 reference schematic이다.
|
|
|
|
```text
|
|
로컬 이미지 빌드
|
|
→ 이미지 tar 압축
|
|
→ 서버로 전송
|
|
→ 일회성 containerd import Job
|
|
→ 배포 이미지 교체
|
|
```
|
|
|
|
공개 Hub 는 소스가 들어간 이미지라 쓸 수 없다. k3s 의 containerd 소켓은 root 전용이라 사용자 셸에서 닿지 않는다. 그래서 클러스터 안의 일회성 Job 으로 tar 를 import 하는 경로를 쓴다. 다만 Job 이 `kube-system` 에 있거나 클러스터 RBAC 권한을 가진다는 이유만으로 host 소켓에 접근할 수 있는 것은 아니다. 이 경로에는 host 의 containerd 소켓을 명시적으로 mount 하고 그 소켓을 열 수 있는 권한으로 실행한다는 전제가 필요하다.
|
|
|
|
배포 단위는 `hyeonworks.com` 하나이고 서브도메인을 쓰지 않는다. 공개는 `/`, API 는 `/api` 다.
|
|
|
|
## 빌드 인자는 이미지에 굳는다
|
|
|
|
이 경로에서 설정은 두 가지 방식으로 들어간다. 런타임 환경 변수는 배포한 뒤에도 바꿀 수 있고, 빌드 인자는 이미지에 굳어 다시 빌드해야 바뀐다.
|
|
|
|
프론트 이미지가 요구하는 인자는 이만큼이다.
|
|
|
|
```text
|
|
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 가 서빙하기로 한 파일 목록 | 목록에 없는 파일을 요청할 때 |
|
|
| 빌드에 굳은 주소 | 배포본이 그 주소로 요청을 낼 때 |
|
|
|
|
셋 다 헬스 판정을 지난다. 헬스 엔드포인트는 그 파일도 그 목록도 그 주소도 쓰지 않기 때문이다.
|
|
|
|
<!-- body:end -->
|