NoctisNode
← 가이드셀프호스팅2026-10-239분

소형 VPS용 셀프호스팅 스택: 2 GB와 4 GB RAM에 들어가는 것

소형 VPS에서 현실적으로 시작하는 셀프호스팅 스택: Docker Compose, Caddy, Vaultwarden, Uptime Kuma, Forgejo, 서비스별 RAM 예산, 백업과 보안 기본 사항.

짧은 답변: 2 GB VPS는 Docker Compose로 Caddy(HTTPS 리버스 프록시), Vaultwarden(비밀번호), Uptime Kuma(모니터링), Forgejo(git)로 구성된 셀프호스팅 핵심 스택을 약 0.6~1 GB RAM으로 넉넉히 실행합니다. Nextcloud를 추가하려면 4 GB가 필요하며, Syncthing이나 File Browser 같은 가벼운 도구를 선택하면 여전히 2 GB로 충분합니다.

이 가이드는 작동하는 Compose 파일, 서비스별 RAM 예산, 그리고 대부분의 셀프호스팅 구성이 너무 늦을 때까지 놓치는 두 가지, 즉 오프사이트 백업과 잠긴 네트워크 노출면을 다룹니다. 명령어는 Docker 공식 저장소에서 설치한 Docker Engine과 Compose 플러그인이 있는 Debian 12/13 또는 Ubuntu 24.04를 가정합니다.

서비스별 RAM 예산

수치는 지원되는 경우 SQLite를 사용하는 1~5명 사용자 기준, 유휴~가벼운 사용 시의 일반적인 상주 메모리입니다. 업그레이드, 큰 저장소의 git clone, Nextcloud 미리보기 중에는 최대치가 더 높을 수 있으므로 최소 20%의 여유를 두고 1~2 GB 스왑 파일을 추가하세요.

서비스역할일반적인 RAM참고
OS + sshd + journald기본 시스템150–250 MBDebian 또는 Ubuntu 최소 설치
Docker Engine + containerd컨테이너 런타임80–120 MB컨테이너 사용의 고정 비용
Caddy리버스 프록시, 자동 HTTPS20–50 MB단일 바이너리, 데이터베이스 없음
VaultwardenBitwarden 호환 비밀번호 서버20–60 MBRust로 작성, SQLite
Uptime Kuma업타임 및 인증서 모니터링100–200 MBNode.js, 모니터 수에 따라 증가
ForgejoGit 호스팅, 이슈, CI 훅150–300 MBGo, 소규모 팀에는 SQLite로 충분
Nextcloud + MariaDB + Redis파일, 캘린더, 연락처600 MB–1.2 GBPHP-FPM 워커가 대부분 차지
Syncthing파일 동기화, 웹 스위트 없음50–150 MBNextcloud의 가벼운 대안
File Browser웹 파일 관리자20–40 MBHTTPS로 파일 업로드와 공유
RadicaleCalDAV 및 CardDAV30–50 MBNextcloud 없이 캘린더와 연락처

VPS 크기 선택

핵심 스택(Caddy, Vaultwarden, Uptime Kuma, Forgejo)과 기본 시스템을 합치면 약 0.6~1 GB이며, Syncthing과 Radicale을 위한 여유까지 포함해 2 vCPU / 2 GB 서버에 맞습니다. MariaDB와 Redis를 쓰는 Nextcloud는 합계를 약 1.5~2.2 GB로 끌어올리므로, 전체 스위트와 나머지 모두를 원한다면 현실적인 최소값은 4 GB입니다. 디스크도 중요합니다. Forgejo 저장소와 동기화 파일은 늘어나지만, 서비스 자체에는 몇 GB만 필요합니다.

NoctisNode에서는 Pulse 요금제(2 vCPU, 2 GB RAM, 40 GB NVMe, 28일당 $10)가 핵심 스택에, Umbra(4 vCPU, 4 GB, 60 GB NVMe, 28일당 $15)가 핵심 스택과 Nextcloud에 맞습니다. 둘 다 전체 root 권한과 전용 IPv4를 갖춘 KVM이며, Monero나 기타 크립토로 결제할 수 있습니다. 이 가이드의 어떤 내용도 특정 업체에 의존하지 않습니다.

Docker Compose 파일

웹 포트를 게시하는 것은 Caddy뿐이며, 앱들은 내부 Compose 네트워크를 통해서만 접근할 수 있습니다. Forgejo는 SSH를 통한 git을 위해 2222번 포트도 게시하므로 호스트의 OpenSSH는 자체 포트를 유지합니다. `.env` 파일에서 `FORGEJO_TAG`를 현재 Forgejo 메이저 버전으로 설정하고, 예시 도메인을 당신의 DNS 레코드로 바꾸세요.

# /srv/stack/compose.yaml
services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy/data:/data
      - ./caddy/config:/config

  vaultwarden:
    image: vaultwarden/server:latest
    restart: unless-stopped
    environment:
      DOMAIN: "https://vault.example.com"
      SIGNUPS_ALLOWED: "true"   # set to "false" after creating your account
    volumes:
      - ./vaultwarden:/data

  uptime-kuma:
    image: louislam/uptime-kuma:2
    restart: unless-stopped
    volumes:
      - ./uptime-kuma:/app/data

  forgejo:
    image: codeberg.org/forgejo/forgejo:${FORGEJO_TAG}
    restart: unless-stopped
    environment:
      USER_UID: "1000"
      USER_GID: "1000"
      FORGEJO__service__DISABLE_REGISTRATION: "true"
    volumes:
      - ./forgejo:/data
    ports:
      - "2222:22"

# /srv/stack/Caddyfile
# vault.example.com {
#     reverse_proxy vaultwarden:80
# }
# status.example.com {
#     reverse_proxy uptime-kuma:3001
# }
# git.example.com {
#     reverse_proxy forgejo:3000
# }

실행하기

  1. 01.`vault`, `status`, `git`의 A(및 AAAA) 레코드를 서버 IP로 지정해 Caddy가 첫 시작 시 인증서를 받을 수 있게 하세요.
  2. 02.`/srv/stack`을 만들고 그곳에 `compose.yaml`, `Caddyfile`, `.env`를 둔 뒤 `docker compose up -d`를 실행하세요.
  3. 03.Forgejo URL을 열고 설치 마법사를 완료하세요. 공개 가입이 비활성화되어 있으므로 여기서 처음 만든 계정이 관리자가 됩니다.
  4. 04.Vaultwarden 계정을 만든 다음 `SIGNUPS_ALLOWED`를 `"false"`로 설정하고 다시 `docker compose up -d`를 실행하세요. Argon2로 해시된 `ADMIN_TOKEN`을 설정하지 않았다면 관리자 패널은 비활성화된 상태로 두세요.
  5. 05.시작 직후 Uptime Kuma 관리자 사용자를 만드세요. 그전까지는 설정 페이지가 누구에게나 열려 있습니다.
  6. 06.각 서비스와 인증서 만료에 대한 모니터를 추가하세요. 같은 서버의 모니터는 자신의 장애를 보고할 수 없으므로 가급적 두 번째 위치에서 하세요.

Note · HTTPS는 Caddy가 자동으로 처리합니다. 헤더, 속도 제한, 더 복잡한 라우팅은 Caddy 리버스 프록시 가이드를 참고하세요.

실제로 복원되는 백업

보관할 가치가 있는 모든 것은 `/srv/stack` 아래에 있습니다. SQLite 데이터베이스, Forgejo 저장소, Caddy 인증서, 그리고 설정입니다. 업체 스냅샷에 의존하지 말고 restic 백업 가이드에서 설명하는 대로 restic으로 암호화된 오프사이트 사본을 직접 유지하세요.

서비스가 쓰는 도중에 복사한 SQLite 파일은 불일치할 수 있습니다. 소형 서버에서 가장 간단하고 안전한 방법은 백업이 걸리는 1분 동안 스택을 중지하는 것입니다. MariaDB를 쓰는 Nextcloud를 추가했다면 restic 실행 전에 `mariadb-dump`로 데이터베이스를 덤프하세요. 최소 한 번은 임시 디렉터리로 복원을 테스트하세요. 한 번도 복원해 보지 않은 백업은 추측일 뿐입니다.

#!/bin/sh
# /usr/local/sbin/stack-backup (run nightly from cron or a systemd timer)
# needs RESTIC_REPOSITORY and RESTIC_PASSWORD_FILE in the environment
cd /srv/stack || exit 1
docker compose stop
rc=0
restic backup /srv/stack --tag stack || rc=$?
docker compose start
[ "$rc" -eq 0 ] || exit "$rc"
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

보안 기본 사항

  • ▹SSH: 키 전용, root 비밀번호 로그인 금지, 선택적으로 비표준 포트. [SSH 강화 가이드](/guides/ssh-hardening)를 참고하세요.
  • ▹방화벽 주의: Docker는 자체 iptables/nftables 체인을 작성하므로 Docker가 게시한 포트는 `ufw` 규칙을 우회합니다. 반드시 공개해야 하는 것(80, 443, 2222)만 게시하고 데이터베이스나 관리자 포트는 절대 게시하지 마세요.
  • ▹업데이트: 호스트에 `unattended-upgrades`를 활성화하고, 실제로 지킬 수 있는 일정으로 `docker compose pull && docker compose up -d`를 실행하세요.
  • ▹가입: Vaultwarden과 Forgejo의 공개 가입은 꺼 두고 사용자를 초대하세요.
  • ▹디스크 암호화: 복사된 디스크 이미지가 아무것도 드러내지 않도록 `/srv`를 [암호화된 루트](/guides/luks-encrypted-root)에 두세요. 원격 서버에서는 [SSH를 통한 LUKS 원격 잠금 해제](/guides/luks-remote-unlock-ssh)를 사용하고, [LUKS2 vs LUKS1](/guides/luks2-vs-luks1)에서 설명하는 LUKS2 형식을 선호하세요.
  • ▹비밀 정보: `.env`와 Vaultwarden 데이터 디렉터리는 root만 읽을 수 있어야 합니다(`chmod 600`/`700`).

FAQ

Q셀프호스팅에는 RAM이 얼마나 필요한가요?

ACaddy, Vaultwarden, Uptime Kuma, Forgejo로 구성된 핵심 셀프호스팅 스택은 OS와 Docker를 포함해 약 0.6~1 GB로 실행되므로 2 GB VPS면 충분합니다. MariaDB와 Redis를 쓰는 Nextcloud를 추가하면 실질적인 최소값은 4 GB입니다.

Q2 GB VPS에서 Nextcloud를 실행할 수 있나요?

A실행은 되지만 다른 서비스와 함께라면 여유가 거의 없고 미리보기나 동기화가 몰릴 때 느려집니다. 2 GB에서는 Syncthing과 File Browser, Radicale로 훨씬 적은 메모리로 파일, 캘린더, 연락처를 처리할 수 있습니다.

QVaultwarden을 셀프호스팅해도 안전한가요?

AVaultwarden은 종단 간 암호화된 금고 데이터만 저장하므로, 서버가 침해되어도 평문 비밀번호가 직접 노출되지는 않습니다. 가입은 꺼 두고, 관리자 패널은 비활성화하거나 해시된 토큰으로 보호하고, 정기적으로 업데이트하고, 데이터 디렉터리를 백업하세요.

Q셀프호스팅 Docker 스택에 가장 좋은 리버스 프록시는 무엇인가요?

A몇 줄의 설정만으로 HTTPS 인증서를 자동 발급·갱신하므로 소규모 구성에는 Caddy가 가장 쉽습니다. Nginx와 Traefik도 작동하지만 더 많은 설정이 필요합니다.

Qufw가 Docker 컨테이너를 보호하나요?

A기본적으로는 아닙니다. Docker가 자체 방화벽 규칙을 삽입하므로 Docker의 `ports:` 옵션으로 게시한 포트는 ufw를 우회합니다. 공개되어야 하는 포트만 게시하세요.

소형 VPS용 셀프호스팅 스택: 2 GB와 4 GB RAM에 들어가는 것 · NoctisNode