[서버 구축 가이드 01] 전체 지도 — Mac에서 개발한 웹앱을 집 Ubuntu 서버로 서비스하기까지
Mac에서 Django로 만든 웹앱을 집에 있는 Ubuntu 서버에 올려 https://proj.example.net으로 서비스한 과정을 정리한 시리즈의 첫 글입니다. 이 글은 전체 흐름을 한 장의 지도로 보여 주고, 다음 글부터 단계별로 명령어와 그 이유를 정리합니다.

최종 구성
[사용자 브라우저/휴대폰]
│ https://proj.example.net
▼
proj.example.net ─CNAME→ myhome.iptime.org (공유기 DDNS, 집 공인 IP 자동 갱신)
│
[집 공유기] 포트 포워딩: 80 → 서버 80, 443 → 서버 443 (그 외 포트는 닫힘)
│
[Ubuntu 24.04 서버 192.168.0.10]
├─ ufw 방화벽: 80·443은 누구나, 22(SSH)는 집 안에서만
├─ Nginx (80/443): HTTPS 처리, 정적 파일 직접 서빙, 나머지는 앱으로 전달
├─ Gunicorn (127.0.0.1:8001): Django 앱 프로세스 3개
├─ PostgreSQL 17 (localhost:5432): 운영 DB
└─ systemd: 앱 자동 시작 + 매일 03:30 백업 + 04:00 정리 작업
핵심은 "밖에서 보이는 문은 80·443 두 개뿐이고, 나머지는 모두 서버 안에서만 통신한다"는 것입니다. 앱 서버(8001)와 DB(5432)는 외부에서 접근할 수 없습니다.
전체 진행 순서
| 단계 | 하는 일 | 글 |
|---|---|---|
| 개발 준비 | Mac 개발 환경, 비밀값 분리 | 02 |
| 협업·검증 | Git 브랜치·PR, GitHub Actions CI | 03 |
| DB 전환 | SQLite → PostgreSQL (코드 쪽) | 04 |
| 운영 설정 | Django 운영 모드 설정·안전장치 | 05 |
| 서버 준비 | 공유기·방화벽·패키지 | 06 |
| DB 서버 | PostgreSQL 17 설치·DB 생성 | 07 |
| 코드 받기 | GitHub Deploy key, clone·pull | 08 |
| 앱 실행 | Gunicorn + systemd | 09 |
| 웹 서버 | Nginx 리버스 프록시 | 10 |
| 보안 연결 | HTTPS·도메인·인증서 | 11 |
| 데이터 이전 | Mac 데이터 → 서버 DB | 12 |
| 운영 | 업데이트·되돌리기 | 13 |
| 운영 | 백업·복구·타이머 | 14 |
| 정리 | 점검 목록과 실제로 부딪힌 문제들 | 15 |
실제 작업 순서는 "서버 준비 → DB → 코드 → 앱 → Nginx(임시) → 인증서 → Nginx(본 설정) → 데이터 이전 → 백업"입니다. Nginx를 두 번 설정하는 이유는 11편에서 설명합니다(인증서가 없으면 HTTPS 설정으로 Nginx가 뜨지 않기 때문).
시리즈 전체에 깔린 원칙 다섯 가지
- 비밀값은 저장소 밖에. SECRET_KEY, DB 비밀번호는 Git에 절대 넣지 않습니다. 개발은
.env(gitignore), 서버는/etc/proj/proj.env(권한 640)에 둡니다. - 개발·CI·운영의 버전을 맞춘다. Python 3.12, PostgreSQL 17, 정렬 규칙(C.UTF-8)까지 같게 해 "내 PC에선 되는데 서버에선 안 되는" 일을 줄입니다.
- 최소한만 연다. 공유기는 80·443만 포워딩, SSH는 집 안에서만, 앱·DB는 localhost에만 바인딩.
- 각 단계마다 확인 명령을 실행한다.
nginx -t,systemctl status,curl /healthz처럼 "됐다"를 눈으로 확인하고 다음 단계로 갑니다. - 되돌릴 수 있게 만든다. 업데이트 전 자동 백업, 이전 커밋으로 되돌리는 방법, 백업 복구 절차를 미리 준비합니다.
표기 규칙 (이 시리즈 전체)
| 표기 | 의미 |
|---|---|
proj.example.net |
서비스 도메인 (직접 산 도메인의 하위 주소) |
myhome.iptime.org |
공유기 DDNS 주소 |
192.168.0.10, 192.168.0.0/24 |
서버 내부 IP, 집 네트워크 대역 |
admin |
서버 로그인 계정(sudo 가능) / 앱 관리자 계정 |
user01 |
일반 사용자 예시 |
proj |
앱 이름 — 리눅스 사용자, DB 이름, 폴더(/srv/proj), 서비스 이름 |
<...> |
직접 정한 값으로 바꿔 넣는 부분 |
참고
- Django 배포 체크리스트: https://docs.djangoproject.com/en/stable/howto/deployment/checklist/
- Gunicorn 배포 문서: https://docs.gunicorn.org/en/stable/deploy.html