Files
taxbaik/SERVER_SETUP_GUIDE.md
kjh2064 1d7dd71011
TaxBaik CI/CD / build-and-deploy (push) Successful in 41s
fix: unify TaxBaik deployment around CI
2026-06-27 01:34:17 +09:00

282 lines
7.4 KiB
Markdown

# 서버 설정 가이드
## 전제
- 서버: `178.104.200.7` (Ubuntu 26.04)
- 접속: `ssh kjh2064@178.104.200.7`
---
## Step 1: PostgreSQL 데이터베이스 생성 및 마이그레이션
서버에 SSH로 접속한 후 다음을 실행하세요:
```bash
# PostgreSQL에 접속 (로컬 unix socket, sudo 사용)
sudo -i -u postgres
# 그 다음 psql 프롬프트에서:
psql
# SQL 명령어 실행:
CREATE DATABASE taxbaikdb;
CREATE USER taxbaik WITH ENCRYPTED PASSWORD 'your_secure_password_here';
GRANT ALL PRIVILEGES ON DATABASE taxbaikdb TO taxbaik;
\q
exit
# 이제 taxbaik 사용자로 마이그레이션 실행
psql -U taxbaik -d taxbaikdb -h localhost
```
그러면 `taxbaik=#` 프롬프트가 나옵니다. 다음 SQL을 차례로 실행:
### V001__InitialSchema.sql 내용 (프롬프트에 복사):
```sql
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
slug VARCHAR(100) NOT NULL UNIQUE,
sort_order INT NOT NULL DEFAULT 0
);
CREATE TABLE admin_users (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(500) NOT NULL,
last_login_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE blog_posts (
id SERIAL PRIMARY KEY,
title VARCHAR(300) NOT NULL,
content TEXT NOT NULL,
slug VARCHAR(300) NOT NULL UNIQUE,
category_id INT REFERENCES categories(id) ON DELETE SET NULL,
tags TEXT,
author_id INT REFERENCES admin_users(id) ON DELETE SET NULL,
published_at TIMESTAMPTZ,
view_count INT NOT NULL DEFAULT 0,
seo_title VARCHAR(300),
seo_description VARCHAR(500),
thumbnail_url VARCHAR(500),
is_published BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_blog_slug ON blog_posts(slug);
CREATE INDEX idx_blog_published ON blog_posts(is_published, published_at DESC);
CREATE INDEX idx_blog_category ON blog_posts(category_id);
CREATE TABLE inquiries (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
phone VARCHAR(20) NOT NULL,
email VARCHAR(200),
service_type VARCHAR(100) NOT NULL,
message TEXT NOT NULL,
status VARCHAR(50) NOT NULL DEFAULT 'new',
ip_address VARCHAR(50),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_inquiry_status ON inquiries(status);
CREATE INDEX idx_inquiry_created ON inquiries(created_at DESC);
CREATE TABLE site_settings (
key VARCHAR(200) PRIMARY KEY,
value TEXT NOT NULL,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
INSERT INTO categories (name, slug, sort_order) VALUES
('사업자 세무', 'business-tax', 1),
('부동산 세금', 'real-estate-tax', 2),
('종합소득세', 'income-tax', 3),
('부가가치세', 'vat', 4),
('가족자산·증여', 'family-asset', 5);
INSERT INTO site_settings (key, value) VALUES
('site.title', '백원숙 세무회계 | 성북구 세무사'),
('site.description', '사업자 세무, 부동산 양도세·증여세, 종합소득세 상담. 성북구 백원숙 세무사.'),
('kakao.channel.url', ''),
('phone.main', ''),
('consultation.fee.text','상담료 7만~20만 원, 계약 체결 시 일부 차감');
```
### 확인:
```sql
\dt
-- 6개 테이블 출력 (categories, admin_users, blog_posts, inquiries, site_settings, 그리고 schema_migrations)
SELECT * FROM categories;
-- 5개 카테고리 확인
\q
```
---
## Step 2: systemd 서비스 파일 설치
로컬 컴퓨터에서 다음 파일을 서버에 복사:
```bash
# 로컬에서:
scp deploy/taxbaik.service kjh2064@178.104.200.7:~/
```
서버에서:
```bash
# 파일 복사
sudo cp ~/taxbaik.service /etc/systemd/system/
# 환경 변수 추가 (DB 연결 문자열)
sudo nano /etc/systemd/system/taxbaik.service
# 아래 줄을 [Service] 섹션에서 주석 해제:
# Environment=ConnectionStrings__Default=Host=localhost;Database=taxbaikdb;Username=taxbaik;Password=your_password
# systemd 재로드
sudo systemctl daemon-reload
# 서비스 활성화 (부팅 시 자동 시작)
sudo systemctl enable taxbaik
```
---
## Step 3: Nginx 설정 추가
로컬에서 `deploy/nginx-taxbaik-locations.conf` 내용을 복사하여, 서버에서:
```bash
# 현재 Nginx 설정 확인
cat /etc/nginx/sites-available/default
# 또는 기존 Nginx 설정 파일 확인
ls -la /etc/nginx/sites-available/
```
기존 설정 파일의 `http` 또는 `server` 블록에 다음을 **추가**:
```nginx
location /taxbaik {
proxy_pass http://127.0.0.1:5001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
}
```
설정 검증 및 재로드:
```bash
sudo nginx -t
sudo systemctl reload nginx
```
---
## Step 4: Gitea 저장소 Secrets 추가
1. Gitea 웹UI (`http://178.104.200.7/`) 접속
2. `kjh2064/taxbaik` 저장소 이동
3. **Settings****Secrets****Add Secret**
다음 3개 secrets 추가:
| Secret 이름 | 값 |
|-----------|-----|
| `DEPLOY_USER` | `kjh2064` |
| `DEPLOY_HOST` | `178.104.200.7` |
| `DEPLOY_SSH_KEY` | SSH 개인키 (매우 민감!) |
SSH 개인키는:
```bash
# 로컬에서 (.ssh/id_rsa 또는 현재 사용 중인 키)
cat ~/.ssh/id_rsa
# 전체 내용 복사
```
Gitea Secret 창에 전체 붙여넣기.
---
## Step 5: 배포 디렉토리 생성
서버에서:
```bash
mkdir -p ~/deployments
mkdir -p ~/taxbaik_active
# 권한 확인
ls -la ~/ | grep taxbaik
```
---
## Step 6: 초기 배포 테스트
로컬에서:
```bash
# 솔루션 빌드
dotnet build TaxBaik.sln -c Release
# 배포는 Gitea Actions가 처리
# 수동 publish/rsync 절차는 사용하지 않음
```
---
## Step 7: 확인 체크리스트
```bash
# 로컬에서 또는 서버에서:
# 1. DB 확인
psql -U taxbaik -d taxbaikdb -c "\dt"
# 6개 테이블 출력
# 2. 서비스 상태
sudo systemctl status taxbaik
# 3. Nginx 로그 확인
sudo tail -f /var/log/nginx/error.log
# 4. 앱 로그 확인
journalctl -u taxbaik -n 50
# 5. 엔드포인트 테스트
curl -v http://127.0.0.1:5001/health
curl -v http://127.0.0.1/taxbaik
# 6. 문의 폼 E2E 테스트
curl -X POST http://178.104.200.7/taxbaik/contact \
-d "name=테스트&phone=010-1234-5678&service_type=기장&message=상담요청"
```
---
## 문제 해결
| 증상 | 해결 |
|------|------|
| "Connection refused" | systemd 서비스 시작 안 됨: `sudo systemctl start taxbaik` |
| "Permission denied" | systemd 서비스 파일 권한 확인: `sudo chmod 644 /etc/systemd/system/taxbaik.service` |
| Nginx 404 | 설정 재로드: `sudo nginx -t && sudo systemctl reload nginx` |
| DB 연결 오류 | 환경 변수 확인: `systemctl cat taxbaik \| grep ConnectionStrings` |
---
## 다음 단계
서버 설정 완료 후:
- [ ] Git 저장소에 push: `git push -u origin main`
- [ ] 초기 블로그 포스트 5개 작성 (W6.2)
- [ ] 사이트 설정 입력 (전화번호, KakaoTalk URL)
- [ ] Lighthouse 감사 실행