TrendShift 딥다이브 · 2026-07-02

Slasha 딥다이브
git push 한 번으로 내 서버가 나만의 PaaS가 된다

Slasha는 서버 한 대에 설치하는 단일 바이너리 셀프호스팅 PaaS(Platform as a Service, 서비스형 플랫폼)다. 평범한 리눅스 박스에 이 바이너리 하나만 올리면, 그 박스가 git push로 배포되고, 컨테이너로 실행되고, HTTPS로 트래픽을 받는 나만의 Heroku/Railway가 된다. Kubernetes도, YAML 매니페스트도, 외부 컨트롤 플레인도 없다 — 러스트(Rust)로 짠 서버 하나가 Git 서버·빌드 오케스트레이터·컨테이너 관리자·리버스 프록시를 한 프로세스 안에서 전부 해낸다. (저장소: slashacom/slasha · MIT 라이선스 · 최초 릴리스 v0.1.0 (2026-07-01) · TrendShift Daily 11위)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 저장소가 대체 무엇인가.

핵심 메시지

"내 서버를 위한 사설 Heroku" — git push만으로 빌드·배포·HTTPS·헬스체크·롤백까지 자동으로 이어지는, 서버 한 대에서 완결되는 배포 플랫폼.

Heroku나 Railway 같은 서비스에 앱을 배포해 본 적이 있다면, git push heroku main 한 줄로 코드가 서버에 올라가고 도메인이 생기고 HTTPS가 걸리는 마법을 경험했을 것이다. 문제는 그게 남의 서버(클라우드)에서 벌어지는 일이라 매달 요금을 내야 하고, 데이터도 그쪽 인프라에 머문다는 점이다. Slasha는 그 마법을 통째로 복제해 "내가 소유한 리눅스 서버 한 대" 위에서 돌린다.

비유하면: 개발자 = 이삿짐을 맡기는 사람, Kubernetes 기반 클라우드 PaaS = 대형 물류센터(강력하지만 계약서·창고·트럭 배차까지 다 알아야 함), Slasha = 내 집 마당에 지은 개인 창고. 짐(코드)을 문 앞(git push)에 가져다 놓기만 하면, 창고지기(Slasha 서버)가 알아서 정리(빌드)하고 진열(컨테이너 실행)하고 문패(도메인+HTTPS)까지 달아 준다.

README의 자기소개는 이렇다: "Slasha is a single binary you install on your server. It turns a plain Linux box into your own platform-as-a-service." 실제로 소스를 열어 보면 이 한 줄이 과장이 아니다. Cargo.toml 워크스페이스는 slasha-server(핵심 서버) · slasha-cli(CLI, 서버도 이 바이너리 안에 임베드) · slasha-db(Diesel ORM + SQLite) 세 크레이트로 구성되고, 최종 산출물은 정말로 실행 파일 하나(slasha)다. 이 바이너리 하나가 Git 서버 역할(HTTP Smart Protocol), 도커 빌드·컨테이너 관리자, Caddy 기반 리버스 프록시 컨트롤러, 웹 대시보드(React 빌드 결과를 rust-embed로 바이너리에 통째로 내장) 역할을 동시에 한다.

README가 소개하는 것보다 실제 코드베이스는 훨씬 넓다. 소스를 뜯어보면 Rust 소스만 약 2만 줄(87개 이상의 .rs 파일)에 달하며, README에 언급되지 않은 기능도 다수 구현돼 있다 — GitHub App 연동(웹훅으로 저장소 미러링), 알림/알럿 시스템(임계치 감시 + 알림 발송), Cron 작업 스케줄러, 서버·앱·서비스 메트릭 수집, litestream을 이용한 SQLite 연속 백업(S3 호환 스토리지로) 등이다. 즉 Slasha는 "git push 데모"가 아니라 실제 운영을 염두에 둔 본격 PaaS 서버다.

용어
PaaS (Platform as a Service, 서비스형 플랫폼)
클라우드 서비스의 세 계층 중 하나다. IaaS(서버·네트워크만 빌려줌, 예: AWS EC2)는 OS 설치부터 직접 해야 하고, SaaS(완성된 서비스, 예: Gmail)는 손댈 게 없다. 그 중간인 PaaS는 "코드만 주면 실행 환경(서버·네트워크·배포 파이프라인)은 알아서 관리해 주는" 계층이다 — Heroku가 원조 격이다. Slasha는 이 PaaS 경험을 클라우드 업체가 아니라 내가 소유한 서버에서 재현한다는 점이 다르다.

2왜 주목받는가

"Kubernetes 없는 PaaS" · Rust 단일 바이너리 · railpack 자동 빌드 · 헬스체크 기반 무중단 배포.

최근 몇 년간 "셀프호스팅 PaaS" 카테고리는 이미 Coolify·Dokku·CapRover 같은 검증된 프로젝트들이 자리 잡고 있다. Slasha가 이 붐비는 영역에서 TrendShift 상위권에 오른 이유는 기술적 선택의 결이 다르기 때문이다. 대부분의 경쟁자가 PHP/Node/Go + Bash 스크립트 조합인 반면, Slasha는 Rust 워크스페이스로 서버·CLI를 전부 짜고, 결과물을 의존성 없는 단일 바이너리로 배포한다. 최초 릴리스 v0.1.02026-07-01에 올라온 갓 며칠 된 소프트웨어라는 점, 그리고 README에 동작 원리를 그림(architecture.svg)으로 미리 공개한 점도 눈길을 끈다.

경쟁 셀프호스팅/관리형 PaaS와 무엇이 다른가

비교 축Heroku / Railway / Render / Fly.ioCoolify / Dokku / CapRoverSlasha의 접근
호스팅 위치업체 클라우드(관리형, 월 요금)내 서버(셀프호스팅)내 서버(셀프호스팅)
구현 언어비공개(내부 인프라)PHP(Coolify) · Bash(Dokku) · Node(CapRover)Rust 단일 바이너리
배포 산출물해당 없음(SaaS)여러 서비스 조합(웹서버+DB+큐 등)을 설치실행 파일 1개 — 의존성은 Docker뿐
빌드 방식Buildpack(Heroku Buildpacks 등)Nixpacks(Coolify) · 직접 Dockerfilerailpack — Dockerfile 없이 자동 감지 빌드
오케스트레이션자체 대규모 인프라(비공개)Docker Compose 기반Docker API(bollard) 직접 호출, Kubernetes·YAML 없음
제어 범위업체 정책에 종속내가 전부 통제내가 전부 통제 + 코드까지 감사 가능(오픈소스)
주목 포인트 — "Kubernetes 없는 PaaS"라는 명시적 선언
"no Kubernetes, no YAML, no external control plane."

README가 스스로 못 박은 이 문장은 이 프로젝트의 정체성을 압축한다. Kubernetes는 강력하지만 러닝 커브가 가파르고 소규모 서버 한두 대에는 과한 오버헤드다. Slasha는 그 복잡도를 걷어내고, "서버 한 대 + Docker + git push"라는 훨씬 단순한 조합으로 같은 경험(자동 배포·HTTPS·스케일·헬스체크)을 제공한다. 실제 소스를 보면 정말로 쿠버네티스 관련 의존성이 전혀 없고, bollard(Docker Engine API 클라이언트)만으로 컨테이너를 직접 제어한다.

기대치 조정 — 이제 막 시작한 v0.1.0
최초 릴리스가 나온 지 며칠

이 문서를 쓰는 시점 기준 아직 알파~베타 초기 단계다. 실제 코드에는 GitHub App 연동, 알림, Cron, 메트릭, 백업(litestream) 등 README에 없는 기능도 이미 상당수 구현돼 있어 개발 속도는 빠르지만, 그만큼 스키마·API가 빠르게 바뀔 수 있다. 실제로 클론한 저장소의 DB 마이그레이션 폴더에는 2026-06-30·2026-06-29최근 며칠 사이에 추가된 마이그레이션이 다수 보인다 — 활발히 개발 중이라는 뜻이자, 프로덕션에 바로 쓰기 전에는 변화를 주시해야 한다는 뜻이기도 하다.

3기술 스택 전체 지도

Rust 서버(axum+diesel+bollard) + React Router 대시보드 + Docker/railpack/Caddy 인프라.

Slasha는 "서버(백엔드)"와 "대시보드(프론트엔드)"가 완전히 분리된 코드베이스이면서도, 최종적으로는 rust-embed로 대시보드 빌드 결과를 서버 바이너리 안에 통째로 넣어 파일 하나로 배포한다. 각 레이어를 실제 Cargo.toml/package.json 기준으로 뜯어보자.

백엔드 — Rust 워크스페이스 (crates/)

크레이트역할핵심 의존성(실제 Cargo.toml 기준)
slasha-serverHTTP API·Git 서버·Docker 오케스트레이션·프록시·터널의 본체axum 0.8(웹 프레임워크, WebSocket 포함) · bollard(Docker Engine API 클라이언트) · diesel(SQLite ORM) · git2(libgit2 바인딩) · tokio(비동기 런타임)
slasha-cli사용자가 로컬에서 쓰는 slasha 명령어. serve feature로 서버까지 같은 바이너리에 포함clap(명령줄 파싱) · comfy-table·colored(터미널 출력) · keyring(OS 자격 증명 저장소에 토큰 보관) · tokio-tungstenite(WebSocket, 로그 스트림/터널용)
slasha-dbDB 스키마·모델·마이그레이션 정의. 서버·CLI가 공유diesel + libsqlite3-sys(bundled-sqlite feature로 SQLite를 바이너리에 정적 링크) · ts-rs(Rust 타입 → TypeScript 타입 자동 생성, 프론트와 타입 공유)

인증·보안 관련 크레이트도 눈여겨볼 만하다: jsonwebtoken(JWT 발급/검증) · argon2(비밀번호 해시) · zeroize(민감한 값을 메모리에서 확실히 지움) · hmac+sha2(GitHub 웹훅 서명 검증). 그 외 sysinfo(서버 자원 모니터링) · x509-parser(TLS 인증서 파싱) · flate2/async-compression(백업 압축) 등도 포함돼 있다.

프론트엔드 — React Router 대시보드 (web/)

기술역할
React 19 + React Router 7(@react-router/fs-routes)파일 시스템 기반 라우팅. Next.js의 App Router와 비슷한 개념
Bun패키지 매니저 겸 런타임. bun install·bun run dev로 npm/node 대체
Vite 7번들러/개발 서버
TanStack Query(@tanstack/react-query)서버 상태(앱 목록·배포 상태 등) 캐싱·재검증
Radix UI + class-variance-authority접근성 갖춘 헤드리스 UI 프리미티브(드롭다운·다이얼로그 등) + 스타일 변형 관리
Tailwind CSS 4유틸리티 클래스 기반 스타일링
Recharts서버/앱 메트릭 대시보드의 차트
Tiptap리치 텍스트 에디터(멘션 기능 포함) — 메모/설명 입력 등에 사용 추정
BiomeESLint+Prettier를 대체하는 올인원 린터/포매터

인프라 — 빌드·실행·네트워킹

기술역할
railpack사용자 앱을 Dockerfile 없이 자동 빌드하는 오픈소스 Buildpack 계열 도구. 런타임 이미지에 curl -fsSL https://railpack.com/install.sh로 직접 설치돼 있음
Caddy(Admin API 경유)리버스 프록시 + 자동 HTTPS(Let's Encrypt). Slasha는 Caddy를 reqwest로 호출해 라우팅 설정을 동적으로 밀어 넣음
Docker Engine API(bollard)이미지 빌드·컨테이너 생성/시작/정지·네트워크·볼륨 관리를 전부 API 호출로 수행(쉘로 docker 명령을 직접 실행하지 않음)
litestreamSQLite를 S3 호환 스토리지로 실시간 복제(연속 백업). 관리형 DB 컨테이너에 사이드카 형태로 주입
OpenSSH(sshd)Git over SSH + slasha services proxy 같은 보안 터널의 기반. 포트 2222에서 별도로 대기
systemd서버에서 Slasha 프로세스를 서비스로 상시 구동·재시작 관리
cargo-chef + 멀티스테이지 Dockerfile공식 빌드 파이프라인. 의존성 레이어를 캐싱해 CI 빌드 속도 개선
용어
axum & bollard
axum은 Rust의 대표 비동기 웹 프레임워크로, Tokio(비동기 런타임) 위에서 라우팅·미들웨어·WebSocket을 처리한다(Express.js의 Rust 버전에 가깝다). bollard는 Docker Engine이 제공하는 REST API를 Rust 타입으로 감싼 클라이언트 라이브러리다 — 즉 Slasha는 터미널에서 docker run을 실행하는 대신, 이 라이브러리를 통해 Docker 데몬과 직접 HTTP(유닉스 소켓)로 대화하며 컨테이너를 만들고 지운다.

4아키텍처 심화 분석

git push부터 헬스체크·프록시 동기화까지 — 한 번의 배포가 거치는 전체 파이프라인.

Slasha의 심장은 "git push 하나가 실제 서비스 트래픽 전환까지 자동으로 이어지는 파이프라인"이다. 사용자가 git push slasha main을 치는 순간부터 벌어지는 일을 실제 소스 코드(routing/git.rs·docker/deployment/executor.rs·docker/deployment/build.rs·proxy/sync.rs) 기준으로 재구성하면 이렇다.

로컬 컴퓨터 Slasha 서버 (단일 바이너리) ──────────── ────────────────────────────────────────── $ git push slasha main │ │ HTTPS (git-receive-pack) ▼ ① GIT SMART HTTP 서버 (routing/git.rs) axum 라우터가 /git/{slug}/git-receive-pack 요청을 받음 → 진짜 git 프로세스를 서브프로세스로 실행해 pack 수신 → 저장소는 서버 로컬 디스크(bare repo)에 저장 │ │ auto_deploy=true 인 앱이면 ▼ ② 빌드 전략 감지 (dockerfile_parser.rs → detect_build_strategy) 커밋에 Dockerfile이 있으면 BuildStrategy::Dockerfile 없으면 BuildStrategy::Railpack (기본값) │ ┌─────────────┴──────────────┐ ▼ ▼ ③A build_docker() ③B build_railpack() git archive → tar 컨텍스트 railpack 서브프로세스 실행 → Docker 데몬에 스트리밍 빌드 → 언어/프레임워크 자동 감지 → Dockerfile 없이 이미지 생성 └─────────────┬──────────────┘ ▼ ④ 컨테이너 기동 (container.rs) Procfile 또는 기본 web 프로세스만큼 컨테이너 생성 slasha.app_id / slasha.process_type=web 라벨을 부착 전용 Docker 네트워크(app_network_name)에 연결 │ ▼ ⑤ 헬스 확인 & 이전 버전 정지 (is_web_running + rollback) 새 컨테이너가 running 상태가 될 때까지 확인 실패 시 Rollback 스택을 역순 실행(생성물 정리) → Failed 기록 성공하면 이전 배포의 컨테이너를 정지 │ ▼ ⑥ 프록시 동기화 (proxy/sync.rs → CaddyClient) slasha.managed=true 라벨 컨테이너를 Docker API로 스캔 앱별 컨테이너 IP를 모아 Caddy Admin API(:2019)에 PUSH Caddy가 라우팅 갱신 + 필요시 TLS 인증서 자동 발급/갱신 │ ▼ 사용자 도메인 → Caddy(:80/:443) → 컨테이너 IP:PORT

① Git 서버 — 진짜 git 프로세스를 감싼 Smart HTTP

많은 사람이 오해하는 부분인데, Slasha는 "git 프로토콜을 처음부터 구현"하지 않는다. routing/git.rs를 보면 axum 라우터가 /git/{slug}/info/refs·git-upload-pack·git-receive-pack 세 엔드포인트를 노출하고, 요청이 오면 서버에 설치된 진짜 git 바이너리를 서브프로세스로 실행해 표준 입출력을 HTTP 스트림과 연결한다. 이것이 GitHub·GitLab이 쓰는 것과 같은 "Smart HTTP" 프로토콜이다. push가 끝나면 post-receive 훅을 임시 디렉터리에 동적으로 만들어, 배포 성공 메시지를 사용자의 git push 콘솔 출력에 그대로 띄운다 — Heroku에 push했을 때 보이는 그 익숙한 초록색 로그가 바로 이 방식이다.

이런 상황을 상상해봐

택배 접수 창구(axum 엔드포인트) 직원이 손님이 내민 물건을 직접 포장하지 않는다. 대신 뒤편의 숙련된 포장 전문가(진짜 git 프로세스)에게 넘기고, 그 결과를 손님에게 그대로 전달할 뿐이다. 창구는 "누가 왔는지 확인하고(인증), 어디로 넘길지 정하는(라우팅)" 역할만 하고, 실제 무거운 작업은 이미 검증된 전문 도구에 위임한다 — 잘 만든 래퍼(wrapper)의 전형적인 설계다.

② 빌드 전략 자동 선택 — Dockerfile이 없어도 되는 이유

dockerfile_parser.rsdetect_build_strategy()는 커밋 루트에 Dockerfile이 있는지만 확인하는 간단한 로직이지만, 그 갈림길이 크다. 있으면 사용자의 Dockerfile로 build_docker()가 그대로 빌드하고, 없으면 railpack이 대신 언어(Node·Python·Rust·Go 등)를 감지해 최적화된 이미지를 자동 생성한다(build_railpack()). 이 두 경로 모두 git archive --format=tar {commit}로 해당 커밋의 스냅샷만 뽑아 빌드 컨텍스트로 쓰기 때문에, 저장소 전체 히스토리가 이미지에 섞여 들어가지 않는다.

③ 컨테이너 명명·라벨링 — 상태를 DB가 아니라 Docker 자체에 새긴다

인상적인 설계 선택 하나는, Slasha가 "지금 뭐가 실행 중인가"를 판단할 때 자체 DB만 믿지 않고 Docker에 직접 물어본다는 점이다. container.rsis_web_running()slasha.app_id·slasha.process_type=web 라벨과 status=running 필터로 Docker 데몬에게 직접 질의해 답을 얻는다. proxy/sync.rs도 마찬가지로 slasha.managed=true 라벨이 붙은 실행 중 컨테이너를 스캔해 프록시 라우팅 표를 만든다. 이렇게 하면 DB와 실제 컨테이너 상태가 어긋나는(desync) 상황에서도 Docker 자체가 진실의 원천(source of truth)이 되어 자연스럽게 복구된다.

④ 무중단 배포와 롤백 — "선 기동, 후 전환, 실패시 청소"

docker/rollback.rs는 일반적인 try/catch가 아니라 보상 트랜잭션(compensating transaction) 스택을 구현한다 — 배포 단계마다 "실패하면 되돌릴 동작"을 Rollback::register()로 하나씩 쌓아 두고, 정상 완료되면 disarm()으로 무효화하고, 중간에 실패하면 execute()쌓인 순서의 역순으로 모두 실행한다. 실제 배포 흐름(run_deployment_inner)에서는 새 컨테이너를 먼저 띄우고 is_web_running으로 살아있음을 확인한 뒤에야 이전 배포를 정지시킨다 — 새것이 확실히 뜬 다음 헌것을 끈다는 순서 자체가 무중단의 핵심이다. 이는 완전한 트래픽 레벨 블루-그린(구버전과 신버전에 동시에 트래픽을 흘리며 서서히 전환하는 방식)이라기보다, "기동 확인 후 전환"에 가까운 실용적 무중단 패턴이라는 점은 짚어 둘 만하다.

⑤ 프록시 동기화 — Caddy를 설정 파일이 아니라 API로 조종

proxy/caddy_client.rs는 Caddy를 설정 파일을 고쳐 재시작하는 전통적 방식이 아니라, Caddy의 Admin API(:2019)에 JSON을 POST해 무중단으로 설정을 갈아 끼운다. sync_routes()가 라벨 기반으로 컨테이너 IP 목록을 모으면, CaddyClient::apply_routes()가 이를 Caddy의 라우트 JSON으로 변환해 밀어 넣는다. 운영 환경에서는 여기에 automatic_https가 켜져 Let's Encrypt로 인증서를 자동 발급/갱신하고, 개발 환경(SLASHA_ENV=development)에서는 자체 서명 내부 인증서로 대체되며 리다이렉트가 꺼진다 — 코드에 이 분기가 명시적으로 존재한다.

용어
리버스 프록시(Reverse Proxy) & Caddy
사용자의 요청을 대신 받아 뒤에 있는 여러 서버(컨테이너) 중 하나로 전달해 주는 중개자다. 도메인 하나(myapp.com)로 들어온 요청을 실제로는 172.18.0.5:8080 같은 내부 컨테이너로 몰래 넘겨준다. Caddy는 이 역할을 하는 오픈소스 웹서버로, 특히 HTTPS 인증서를 별다른 설정 없이 자동으로 발급·갱신해 주는 것으로 유명하다(Nginx+Certbot 조합을 한 프로그램으로 대체). Slasha는 Caddy를 자식 프로세스로 띄워 놓고, 그 설정을 실시간으로 원격 조종하는 "지휘자" 역할을 한다.

⑥ 보안 터널 — 포트를 열지 않고 관리형 DB에 접속하기

tunnel/mod.rs의 구현 방식은 예상외로 단순하면서 영리하다. 포트 포워딩이나 SSH 터널을 새로 짜는 대신, Docker의 exec 기능을 그대로 활용한다 — CLI가 서버와 WebSocket을 열면, 서버는 해당 서비스 컨테이너 안에서 psql/mysql/redis-cli류 클라이언트(또는 Redis는 nc)를 docker exec로 실행하고, 그 표준 입출력을 WebSocket으로 그대로 중계한다. 즉 데이터베이스 포트를 인터넷에 노출하지 않고도, "컨테이너 안에서 로컬로 접속하는 것"을 원격에서 그대로 재현하는 방식이다.

5디렉토리 구조 해부

최상위 레이아웃 + crates/slasha-server의 실제 모듈 구성.

slasha/ ├── crates/ # Rust 워크스페이스 — 여기가 진짜 엔진 │ ├── slasha-server/src/ # HTTP API + Git 서버 + 오케스트레이션 (핵심) │ │ ├── routing/ # git.rs(Smart HTTP) + api/(REST 엔드포인트 전부) │ │ │ └── api/apps/ # deployments·domains·env·scale·backups·crons·metrics... │ │ ├── docker/ # bollard 기반 Docker 제어 총본산 │ │ │ ├── deployment/ # build.rs·executor.rs·container.rs·litestream.rs 등 │ │ │ └── service/ # 관리형 DB(postgres 등) 프로비저닝 │ │ ├── proxy/ # caddy_client.rs·sync.rs — 리버스 프록시/TLS 제어 │ │ ├── tunnel/ # WebSocket ↔ docker exec 보안 터널 │ │ ├── connections/github/ # GitHub App 연동(웹훅·미러링) │ │ ├── alerts/ # 임계치 감시 + 알림 발송 워커 │ │ ├── cron/ # 앱 내 Cron 작업 스케줄러/러너 │ │ ├── metrics/ # 서버/앱/서비스 메트릭 수집 │ │ ├── extractors/ # axum 인증·앱 컨텍스트 추출기 │ │ ├── middleware/ # 관리자 권한·레이트리밋 │ │ ├── ssh.rs · auth.rs · assets.rs · state.rs │ │ │ ├── slasha-cli/src/ # 사용자가 실제로 치는 slasha 명령어 │ │ ├── clap_app.rs # 전체 명령 트리 정의 │ │ ├── deployments.rs · apps.rs · services.rs · scale.rs │ │ ├── domains.rs · auth.rs · token.rs · ssh_keys.rs │ │ └── git_ssh.rs # 숨김 서브커맨드 — SSH 경유 git 인증 브릿지 │ │ │ └── slasha-db/ # Diesel 스키마 + 마이그레이션 (20개 이상) │ └── migrations/ # 2026-04-03(users) ~ 2026-06-30(github_app_config) 순 │ ├── web/app/ # React Router 7 대시보드 │ ├── routes/ # 파일 기반 라우팅 — URL 구조 = 폴더 구조 │ ├── components/apps|alerts|monitoring|settings|users │ ├── queries/ · hooks/ · models/ # TanStack Query + Diesel↔TS 공유 타입(ts-rs) │ ├── docker/ │ ├── Dockerfile # frontend-builder → cargo-chef → runtime 3단 빌드 │ ├── docker-compose.yml # network_mode: host + 소켓 마운트로 원클릭 실행 │ └── docker-entrypoint.sh # sshd 기동 + docker.sock GID 동기화 + slasha 유저 전환 │ ├── scripts/ │ ├── setup.sh # 서버 셋업 원스크립트(Docker·ufw·sshd 설치) │ ├── install.sh # CLI 로컬 설치 스크립트 │ └── release/ # 릴리스 빌드 자동화 │ ├── Cargo.toml # 워크스페이스 정의 (3개 멤버 크레이트) ├── Makefile # dev/dev-cli/dev-bundle/docker-up/format/lint ├── .env.example # SLASHA_ENV·PLATFORM_DOMAIN·PORT·JWT_SECRET └── README.md · LICENSE(MIT)
한눈에 읽는 법

routing/이 "바깥세상과 만나는 문", docker/가 "실제 일을 하는 손발", proxy/·tunnel/이 "네트워크 배관"이라면, slasha-db/migrations/는 이 프로젝트의 성장 일기장이다. 폴더 이름 자체가 YYYY-MM-DD 타임스탬프라, 순서대로 읽으면 "사용자 → 앱 → SSH 키 → 배포 → 서비스 → 환경변수 → 스케일 → 도메인 → 메트릭 → 백업 → 서버메트릭 → 알림 → 커넥션 → Cron → GitHub 연동" 순으로 기능이 실제로 쌓여 온 개발 역사를 그대로 볼 수 있다. 처음 읽는다면 routing/git.rs(입구) → docker/deployment/executor.rs(심장) → proxy/sync.rs(출구) 순으로 따라가는 것을 추천한다.

6학습 포인트 (기술별)

이 저장소에서 실제로 무엇을 배울 수 있는가 + 각 주제 실습 아이디어.

학습 1 · Rust로 실전 웹 서버 짜기 (axum)

"타입 시스템으로 인증·상태를 강제하는 법"

extractors/auth.rs·extractors/app.rs는 axum의 Extractor 패턴을 실전에서 어떻게 쓰는지 보여준다 — 핸들러 함수의 파라미터 타입 자체가 "이 요청은 인증된 사용자만 접근 가능"·"이 요청은 특정 앱 컨텍스트가 필요"를 컴파일 타임에 강제한다. 미들웨어를 뒤섞어 쓰는 대신, 함수 시그니처만 보고도 권한 요구사항을 알 수 있다.

실습: 작은 axum 서버를 만들어, JWT 토큰이 있어야만 통과하는 커스텀 Extractor를 직접 구현해 보기.

학습 2 · Docker Engine API 직접 다루기 (bollard)

"쉘 명령이 아니라 API로 컨테이너를 다스리는 법"

docker/deployment/container.rs·docker/service/provision.rsstd::process::Command::new("docker")로 쉘을 흉내 내는 대신, Docker Engine의 REST API(bollard)를 타입 안전하게 호출한다. 컨테이너 생성·네트워크 연결·라벨 부착·헬스 상태 조회를 전부 구조체로 표현한다.

실습: bollard(또는 Python이면 docker-py)로 "이미지 pull → 컨테이너 생성 → 로그 스트리밍 → 정지·삭제"를 코드 몇 줄로 구현해 보기.

학습 3 · Git 서버를 직접 구현하는 법 (Smart HTTP)

"내 서버로 push 받는 건 생각보다 진입장벽이 낮다"

routing/git.rsGit Smart HTTP 프로토콜의 핵심을 30줄 남짓한 라우터로 보여준다 — 진짜 git 바이너리를 서브프로세스로 감싸는 것만으로 나만의 "미니 GitHub"를 만들 수 있다는 사실이 인상적이다. post-receive 훅으로 배포를 트리거하는 부분도 실전 CI/CD 파이프라인의 원형이다.

실습: 로컬에서 git init --bare로 저장소를 만들고, 간단한 post-receive 훅으로 "push되면 자동으로 스크립트 실행"을 직접 만들어 보기.

학습 4 · 무중단 배포 & 보상 트랜잭션 패턴

"실패를 가정하고 되돌릴 수 있게 설계하기"

docker/rollback.rsRollback 구조체는 매우 작지만(30줄) 실전에서 자주 쓰이는 보상 트랜잭션(Saga) 패턴의 미니멀한 구현이다. "각 단계가 실패할 수 있다"는 전제 하에, 실행한 단계를 스택에 쌓고 실패 시 역순으로 되돌리는 아이디어는 배포 파이프라인뿐 아니라 결제·재고 관리 등 여러 분산 시스템에서 재사용된다.

실습: "단계 A 성공 → 단계 B 실패 → A를 되돌림" 흐름을 Rollback과 비슷한 구조로 직접 구현해, 실패 시 실제로 역순 정리가 되는지 테스트 작성.

학습 5 · 리버스 프록시를 API로 조종하기 (Caddy Admin API)

"설정 파일 재작성 대신 실시간 API 갱신"

proxy/caddy_client.rs는 전통적인 "nginx.conf 고치고 nginx -s reload" 방식과 다른 길을 보여준다. Caddy의 Admin API에 JSON POST로 라우팅 테이블 전체를 무중단 교체하는 방식은, 동적으로 변하는 컨테이너 환경(앱이 계속 뜨고 죽는 PaaS)에 훨씬 잘 맞는다.

실습: 로컬에 Caddy를 띄우고, curl -X POST localhost:2019/load로 라우팅 설정을 바꿔가며 무중단 갱신을 직접 체험.

학습 6 · 프론트-백엔드 타입 공유 (ts-rs)

"Rust 구조체를 TypeScript 타입으로 자동 변환"

slasha-db가 의존하는 ts-rs 크레이트는 #[derive(TS)]를 붙인 Rust 구조체에서 TypeScript 타입 정의(.ts)를 자동 생성한다. 백엔드 모델이 바뀌면 프론트엔드 타입도 동기화되어, "API 응답 필드가 바뀌었는데 프론트는 몰랐다"는 흔한 버그의 원천을 차단한다.

실습: 작은 Rust 구조체에 ts-rs를 붙여 TS 타입을 생성해 보고, React 프로젝트에서 그 타입으로 fetch 응답을 받아보기.

학습 7 · 단일 바이너리 배포 전략 (rust-embed + 멀티스테이지 빌드)

"프론트엔드 빌드 결과를 백엔드 실행 파일 안에 통째로 굽기"

docker/Dockerfile의 3단계(frontend-builder → cargo-chef builder → debian runtime)와 rust-embed(bundle feature)를 함께 보면, "React 앱을 정적 파일로 빌드 → 그 바이트를 Rust 바이너리에 내장 → 서버가 스스로 정적 파일을 서빙"하는 전체 흐름을 배울 수 있다. 배포 산출물이 파일 하나로 줄어드는 실전 기법이다.

실습: 작은 정적 사이트를 빌드해 rust-embed로 Rust 바이너리에 내장하고, axum의 static handler로 서빙해 보기.

7하드웨어 / 시스템 요구사항

서버(운영)와 로컬(개발) 요구사항을 나눠서.

구분항목요구사항
서버 (운영)운영체제64비트 리눅스 + systemd 필수
네트워크 포트80·443(HTTP/HTTPS) + 22(git over SSH) 외부에서 접근 가능해야 함
권한root 또는 sudo — 셋업 스크립트가 Docker·ufw·sshd를 직접 설치·설정
도메인HTTPS·대시보드 접근용으로 서버를 가리키는 도메인 1개 필요
자동 설치되는 것Docker(Compose·Buildx 포함) · ufw(방화벽) · sshd
CLI (로컬)운영체제Linux · macOS · Windows 모두 지원(HTTPS로 서버와 통신)
설치curl -fsSL https://slasha.com/install.sh | bash
인증 저장OS 자격 증명 저장소(keyring 크레이트) — 토큰이 평문 파일로 안 남음
필요 권한일반 사용자 권한으로 충분(서버 접속용 SSH 키만 있으면 됨)
개발 환경Rustrustupnightly 툴체인도 필요(cargo +nightly fmt용)
Bunbun.sh — 웹 대시보드 패키지 매니저 겸 실행기
Docker배포된 앱을 실제로 빌드·실행하려면 필수
라이선스MIT — 상업적 이용·수정·재배포 자유
용어
systemd & ufw
systemd는 대부분의 최신 리눅스 배포판(Ubuntu·Debian 등)이 쓰는 서비스 관리자다 — 서버가 재부팅돼도 Slasha 프로세스가 자동으로 다시 켜지도록 등록해 준다("백그라운드에서 계속 살아있게 하는 집사"). ufw(Uncomplicated Firewall)는 리눅스 방화벽(iptables)을 쉬운 명령으로 다루게 해주는 도구로, "80·443·22 포트만 열고 나머지는 막는" 기본 보안선을 셋업 스크립트가 자동으로 그어 준다.

8직접 해볼 수 있는 실습 과제

난이도별 5단계 — 설치해 굴려 보고, 코드를 고쳐 보고, 직접 만들어보기.

과제 1 · 로컬에 Slasha 통째로 띄워보기 난이도 ★☆☆☆☆

가장 먼저 할 일은 실제로 굴려 보는 것이다. 저장소를 클론해 make dev 한 줄이면 .env.example.env로 복사되고, 서버(cargo run)와 웹 대시보드(bun run dev)가 동시에 뜬다. SLASHA_PLATFORM_DOMAIN=slasha.localhost로 브라우저에서 대시보드에 접속해 계정을 만들고 화면 구조를 익히는 것이 목표다.

# 저장소 클론 후
git clone https://github.com/slashacom/slasha.git
cd slasha
make dev              # .env 자동 생성 + 서버·대시보드 동시 실행
# 브라우저에서 http://slasha.localhost:3000 접속

과제 2 · 첫 앱을 git push로 배포해 보기 난이도 ★★☆☆☆

대시보드나 CLI로 앱을 하나 만들고(slasha create my-app), Node/Python 같은 아주 간단한 "Hello World" 웹 서버 프로젝트를 git push slasha main으로 배포해 본다. Dockerfile을 일부러 넣지 않고 push해서 railpack이 언어를 자동 감지해 빌드하는 과정을 로그로 관찰하고, 그다음엔 직접 Dockerfile을 추가해 빌드 전략이 어떻게 바뀌는지 비교한다.

// 핵심 골격 (README CLI 사용법 요약)
slasha create my-app
slasha link --app my-app        // cwd에 .slasha 파일 기록
git remote add slasha <서버가 알려준 git URL>
git push slasha main            // 여기서 build_railpack() 또는 build_docker() 실행
slasha deployments logs --follow

과제 3 · 관리형 PostgreSQL을 붙이고 터널로 접속하기 난이도 ★★★☆☆

slasha provision --kind postgres --name db --version 16로 관리형 DB를 띄운 뒤, 앱 코드에서 ${{db.DATABASE_URL}} 같은 서비스 참조 환경변수로 연결한다. 그다음 로컬 컴퓨터에서 slasha services proxy db --port 5432로 터널을 열어 psql로 직접 접속해 본다 — 포트를 서버에 열지 않고도 DB에 접속되는 걸 확인하는 것이 핵심이다.

과제 4 · 커스텀 도메인 + 자동 HTTPS 확인하기 난이도 ★★★☆☆

실제 소유한 도메인(서브도메인도 가능)의 DNS를 서버 IP로 돌린 뒤 slasha domains add app.example.com을 실행하고, Caddy가 Let's Encrypt 인증서를 자동 발급하는 과정을 proxy/caddy_client.rs 코드와 나란히 관찰한다. 브라우저 개발자 도구에서 인증서 발급자·유효기간을 확인해 본다.

과제 5 · 새로운 CLI 서브커맨드를 직접 추가해 보기 난이도 ★★★★☆

clap_app.rsCommand enum에 새 항목(예: 배포 히스토리를 CSV로 내보내는 export 명령)을 추가하고, 대응하는 서버 API 엔드포인트를 routing/api/에 만들어 연결한다. 기존 deployments.rsdispatch() 패턴을 그대로 따라 하면 큰 어려움 없이 구조를 익힐 수 있다. Rust 워크스페이스에서 CLI ↔ 서버 ↔ DB 세 크레이트가 어떻게 서로 참조하는지 실전으로 배우는 과제다.

9관련 기술 심화 학습 로드맵

이 레포 하나로 웹서버·컨테이너·네트워킹·배포 이론을 8주에 걸쳐 정리하는 코스.

주차주제무엇을 하나
1주Rust 비동기 기초Tokio 튜토리얼 완주 → slasha-server/src/lib.rs·state.rs 읽으며 서버 초기화 흐름 파악
2주axum 웹 프레임워크axum 공식 예제로 라우터·Extractor·미들웨어 실습 → extractors/·middleware/ 코드와 비교
3주Diesel ORM & SQLiteDiesel 공식 가이드로 마이그레이션·쿼리 작성 → slasha-db/migrations/ 20여 개를 순서대로 읽어 스키마 진화 추적
4주Docker Engine APIDocker API 문서 + bollard 예제 → docker/deployment/container.rs로 실전 컨테이너 라이프사이클 학습
5주Git 내부 구조"Pro Git" 9장(Git 내부) 읽기 → routing/git.rs로 Smart HTTP 프로토콜 실습, 미니 git 서버 직접 구현
6주리버스 프록시 & TLSCaddy 공식 문서(Admin API) + ACME/Let's Encrypt 원리 → proxy/ 모듈 전체 정독
7주React Router 7 & 상태 관리React Router 7 파일 기반 라우팅 튜토리얼 + TanStack Query 문서 → web/app/routes·queries/ 구조 분석
8주종합 — 미니 PaaS 만들기지금까지 배운 것으로 "git push → Docker 빌드 → 컨테이너 실행 → nginx/Caddy 라우팅"을 축소판으로 직접 구현

10핵심 키워드 사전

이 문서에 등장한 전문 용어를 한 곳에 모음.

용어
railpack
Dockerfile 없이 소스 코드만 보고 언어·프레임워크를 자동 감지해 컨테이너 이미지를 빌드해 주는 오픈소스 도구(railpack.com). Heroku Buildpacks·Nixpacks와 같은 계열(Buildpack)이다. Slasha는 런타임 이미지에 이 도구를 직접 설치해 사용한다.
용어
Buildpack
"이 프로젝트가 Node인지 Python인지 Go인지"를 package.json·requirements.txt 같은 파일 존재 여부로 알아서 판단해, 그에 맞는 빌드·실행 절차를 자동 적용하는 도구/규칙의 총칭이다. 개발자가 매번 Dockerfile을 쓰지 않아도 되게 해 준다.
용어
Git Smart HTTP
HTTP로 git push/pull을 주고받는 표준 프로토콜. info/refs로 먼저 능력을 협상하고, git-upload-pack(pull)·git-receive-pack(push)으로 실제 데이터를 주고받는다. GitHub·GitLab·Slasha 모두 이 프로토콜 위에서 동작한다.
용어
보상 트랜잭션(Compensating Transaction) / Saga 패턴
여러 단계로 이루어진 작업 중 일부가 실패했을 때, 이미 완료된 단계들을 "거꾸로 되돌리는 별도의 되돌림 작업"을 실행해 전체를 정합적인 상태로 복구하는 설계 패턴. 데이터베이스의 트랜잭션 롤백과 달리, 여러 시스템(컨테이너·파일·외부 API)에 걸친 작업에서 쓰인다.
용어
무중단 배포(Zero-downtime Deployment)
새 버전을 배포하는 동안에도 서비스가 끊기지 않게 하는 기법. Slasha는 "새 컨테이너를 먼저 띄워 살아있음을 확인한 뒤에야 기존 컨테이너를 정지"하는 방식으로 이를 구현한다. 완전한 트래픽 점진 전환(카나리·블루-그린)까지는 아니지만, 짧은 전환 창을 최소화하는 실용적 접근이다.
용어
Argon2
비밀번호를 안전하게 저장하기 위한 해시 함수. 단순 SHA 계열과 달리 일부러 계산을 느리고 메모리를 많이 쓰게 설계해, 공격자가 무차별 대입으로 비밀번호를 추측하기 어렵게 만든다. Password Hashing Competition(2015)의 우승 알고리즘으로, Slasha는 이를 사용자 비밀번호 저장에 쓴다.
용어
JWT (JSON Web Token)
"이 사용자는 인증됐다"는 정보를 서버가 서명해 발급하는 토큰. 서버는 JWT_SECRET이라는 비밀 값으로 서명하고, 이후 요청이 올 때마다 그 서명이 유효한지만 검증하면 되므로 매번 DB를 조회할 필요가 없다(무상태 인증). Slasha CLI가 로그인 후 저장하는 토큰이 바로 이것이다.
용어
litestream
SQLite 데이터베이스 파일의 변경사항을 실시간으로 S3 호환 오브젝트 스토리지에 복제(replicate)해 주는 오픈소스 도구. SQLite는 원래 파일 하나짜리 DB라 별도 백업 인프라가 없는데, litestream이 이를 지속적으로 원격에 미러링해 재해 복구를 가능하게 한다.
용어
보안 터널(Secure Tunnel)
데이터베이스처럼 인터넷에 직접 노출하면 위험한 서비스에, 포트를 열지 않고도 안전하게 접근하는 통로. Slasha는 WebSocket과 docker exec을 조합해, "컨테이너 내부에서 로컬로 접속하는 것"을 CLI 사용자의 터미널까지 그대로 중계한다.
용어
Diesel (ORM)
Rust의 대표적인 ORM(Object-Relational Mapping, 객체-관계 매핑) 라이브러리. SQL을 문자열로 직접 쓰는 대신 Rust 타입과 매크로로 쿼리를 표현해, 컴파일 시점에 오타나 타입 불일치를 잡아낸다. Slasha는 SQLite와 함께 이를 사용한다.
용어
rust-embed
빌드 시점에 지정한 폴더(예: 프론트엔드 빌드 결과물)의 파일들을 통째로 Rust 바이너리 안에 내장시켜 주는 매크로 라이브러리. 실행 파일 하나만 옮기면 정적 파일까지 다 딸려가므로, "폴더 여러 개를 서버에 복사해야 하는" 번거로움이 사라진다.

11참고 링크

더 깊이 파고들고 싶다면.

링크설명
GitHub 저장소소스 코드 전체 (slashacom/slasha)
slasha.com공식 웹사이트
공식 문서 — 서버 셋업설치·초기 설정 가이드
railpack.comSlasha가 빌드에 사용하는 Buildpack 도구
Caddy Admin API 문서Slasha가 리버스 프록시/TLS 제어에 쓰는 API
bollard 문서Slasha가 Docker 제어에 쓰는 Rust 클라이언트
Diesel 공식 사이트Slasha가 쓰는 Rust ORM
React Router 공식 문서대시보드가 쓰는 프레임워크(v7)
litestream.ioSlasha의 SQLite 백업/복제 도구