학회/전공 학습 내용을 업로드하고 공개 열람하는 관리자 1인 기반 지식 아카이브입니다.
- Next.js (App Router) + TypeScript
- PostgreSQL + Prisma
- 관리자 인증: Argon2 해시 + JWT(HttpOnly cookie)
- 파일 업로드: 서버단 MIME/크기 검증 + 랜덤 파일명 저장
- 인프라: Docker Compose + Nginx + HTTPS
/admin/*,/api/posts(POST),/api/upload프록시 보호- 로그인 rate limit 적용
- 보안 헤더(CSP, HSTS, X-Frame-Options, X-Content-Type-Options)
- 업로드 화이트리스트 검증(PDF/PNG/JPG/WEBP/GIF)
- 의존성 설치
npm install
- 환경 변수 준비
.env.example복사 후.env작성npm run dev로 로컬 접속할 때는NODE_ENV=production을 피하세요.BASE_URL이https://인데http://localhost로 접속하면 쿠키 Secure 설정 때문에 로그인 세션이 저장되지 않을 수 있습니다.- 필요하면
.env에COOKIE_SECURE=false를 추가하세요.
- Docker Compose로 앱까지 같이 띄울 때는
BASE_URL을 실제로 브라우저가 접속하는 공개 URL로 맞추세요.- 예: Nginx TLS로
https://localhost에 접속한다면BASE_URL=https://localhost .env에NODE_ENV=development가 남아 있으면(.env.example복사 실수) HTTPS 뒤에서도 Secure 쿠키가 꺼져 로그인 직후/admin에서 다시 로그인 화면으로 튕길 수 있습니다.- 이 repo의
infra/docker-compose.yml은 앱 컨테이너에NODE_ENV=production을 강제합니다.
- 이 repo의
- 예: Nginx TLS로
npm run dev는 호스트에서 실행되므로DATABASE_URL의 호스트가postgres처럼 Docker 내부 DNS면 연결이 실패할 수 있습니다.- 로컬 개발이면
localhost:5432같은 호스트로 맞추거나, Docker로 DB만 띄운 뒤 포트를 노출해 접속하세요. - 이 repo의
infra/docker-compose.yml은 Postgres를127.0.0.1:5432로 호스트에 노출합니다(외부 인터넷에는 안 열림).
- 로컬 개발이면
- Prisma 준비
npx prisma generatenpx prisma migrate dev --name init- (기존 DB를 스키마로 먼저 만든 경우)
npx prisma migrate resolve --applied 20260418103000_init
- 실행
npm run dev
.env작성- 인증서 배치
infra/nginx/certs/fullchain.peminfra/nginx/certs/privkey.pem
- 빌드 및 실행
cd infradocker compose up -d --build
- 마이그레이션
docker exec -it study-archive-app npx prisma migrate deploy
prisma/migrations/20260418103000_init/migration.sql
GET /api/health
- 스크립트:
infra/scripts/backup-db.sh - 예시 cron (매일 03:00)
0 3 * * * /path/to/infra/scripts/backup-db.sh
- DB 컨테이너 접속 가능한 환경에서 SQL 파일 준비
- 복구 명령
cat backup.sql | docker exec -i study-archive-db psql -U study_user -d study_archive
- 관리자 로그인 성공/실패 동작
- 비로그인 상태에서
/admin접근 차단 - 글 작성 및 첨부 업로드 성공
- 비허용 타입 업로드 차단
/archive,/archive/[slug]렌더링 확인
- Nginx rate limit 및 access 로그:
infra/nginx/default.conf(로그는nginx_logs볼륨) - VPS 방화벽·Fail2ban: infra/docs/SECURITY-VPS.md
- Fail2ban 필터 예시:
infra/fail2ban/filter.d/nginx-study-auth.conf - DB 복구 스크립트:
infra/scripts/restore-db.sh - CI:
.github/workflows/ci.yml(lint + Prisma generate + build)
cd /path/to/Studies
cp .env.example .env # 값 수정 (비밀번호·AUTH_SECRET·BASE_URL·DB)
# TLS: Let's Encrypt 또는 자체 인증서를 infra/nginx/certs/ 에 배치
cd infra
docker compose up -d --build
docker exec study-archive-app npx prisma migrate deploy
curl -k https://localhost/api/health