| # Railway PostgreSQL ์ค์ ๊ฐ์ด๋ | |
| Railway์์ PostgreSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์์ฑํ๊ณ Hugging Face Spaces์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. | |
| ## 1. Railway์์ PostgreSQL ์๋น์ค ์์ฑ | |
| ### ๋ฐฉ๋ฒ 1: ์ ํ๋ก์ ํธ์์ PostgreSQL ์ถ๊ฐ (๊ถ์ฅ) | |
| 1. **Railway ๋์๋ณด๋ ์ ์** | |
| - https://railway.app ์ ์ ๋ฐ ๋ก๊ทธ์ธ | |
| 2. **์ ํ๋ก์ ํธ ์์ฑ** | |
| - ์ข์ธก ์๋จ์ **"+ New Project"** ํด๋ฆญ | |
| - **"Deploy from GitHub repo"** ๋๋ **"Empty Project"** ์ ํ | |
| - ํ๋ก์ ํธ ์ด๋ฆ ์ ๋ ฅ (์: `soy-nv-ai-db`) | |
| 3. **PostgreSQL ์๋น์ค ์ถ๊ฐ** | |
| - ํ๋ก์ ํธ ๋ด์์ **"+ New"** ๋ฒํผ ํด๋ฆญ | |
| - **"Database"** ์ ํ | |
| - **"Add PostgreSQL"** ํด๋ฆญ | |
| - Railway๊ฐ ์๋์ผ๋ก PostgreSQL ์ธ์คํด์ค๋ฅผ ์์ฑํฉ๋๋ค (์ฝ 1-2๋ถ ์์) | |
| ### ๋ฐฉ๋ฒ 2: ๊ธฐ์กด ํ๋ก์ ํธ์ PostgreSQL ์ถ๊ฐ | |
| 1. ๊ธฐ์กด ํ๋ก์ ํธ ์ ํ | |
| 2. **"+ New"** ๋ฒํผ ํด๋ฆญ | |
| 3. **"Database"** > **"Add PostgreSQL"** ์ ํ | |
| ## 2. PostgreSQL ์ฐ๊ฒฐ ์ ๋ณด ํ์ธ | |
| PostgreSQL ์๋น์ค๊ฐ ์์ฑ๋๋ฉด: | |
| 1. **PostgreSQL ์๋น์ค ํด๋ฆญ** | |
| - ํ๋ก์ ํธ ๋ด์์ ์์ฑ๋ PostgreSQL ์๋น์ค๋ฅผ ํด๋ฆญ | |
| 2. **Variables ํญ ํ์ธ** | |
| - ์๋จ ๋ฉ๋ด์์ **"Variables"** ํญ ํด๋ฆญ | |
| - ๋ค์ ํ๊ฒฝ ๋ณ์๋ค์ด ์๋์ผ๋ก ์์ฑ๋์ด ์์ต๋๋ค: | |
| - `PGHOST`: ํธ์คํธ ์ฃผ์ | |
| - `PGPORT`: ํฌํธ ๋ฒํธ (๊ธฐ๋ณธ๊ฐ: 5432) | |
| - `PGDATABASE`: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๋ฆ | |
| - `PGUSER`: ์ฌ์ฉ์ ์ด๋ฆ | |
| - `PGPASSWORD`: ๋น๋ฐ๋ฒํธ | |
| - `DATABASE_URL`: ์ ์ฒด ์ฐ๊ฒฐ ๋ฌธ์์ด โญ (์ด๊ฒ์ ์ฌ์ฉํฉ๋๋ค!) | |
| 3. **DATABASE_URL ๋ณต์ฌ** | |
| - `DATABASE_URL` ๋ณ์์ **๊ฐ**์ ๋ณต์ฌํฉ๋๋ค | |
| - ํ์: `postgresql://postgres:password@hostname:port/railway` | |
| - ์์: `postgresql://postgres:abc123@containers-us-west-123.railway.app:5432/railway` | |
| ## 3. Hugging Face Spaces์ ์ฐ๊ฒฐ ์ ๋ณด ์ค์ | |
| ### 3-1. Hugging Face Spaces ์ ์ | |
| 1. https://huggingface.co/spaces ์ ์ | |
| 2. ํด๋น Space ํ์ด์ง๋ก ์ด๋ (์: `wiizm/soyailabs`) | |
| ### 3-2. ํ๊ฒฝ ๋ณ์ ์ถ๊ฐ | |
| 1. **Settings ํญ ํด๋ฆญ** | |
| - Space ํ์ด์ง ์๋จ์ **"Settings"** ํญ ํด๋ฆญ | |
| 2. **Repository secrets ์น์ ์ผ๋ก ์ด๋** | |
| - ์ข์ธก ๋ฉ๋ด์์ **"Repository secrets"** ํด๋ฆญ | |
| - ๋๋ ํ์ด์ง๋ฅผ ์๋๋ก ์คํฌ๋กคํ์ฌ **"Repository secrets"** ์น์ ์ฐพ๊ธฐ | |
| 3. **์ ํ๊ฒฝ ๋ณ์ ์ถ๊ฐ** | |
| - **"New secret"** ๋ฒํผ ํด๋ฆญ | |
| - ๋ค์ ์ ๋ณด ์ ๋ ฅ: | |
| - **Key**: `DATABASE_URL` | |
| - **Value**: Railway์์ ๋ณต์ฌํ `DATABASE_URL` ๊ฐ ๋ถ์ฌ๋ฃ๊ธฐ | |
| ``` | |
| postgresql://postgres:password@hostname:port/railway | |
| ``` | |
| - **"Add secret"** ๋ฒํผ ํด๋ฆญ | |
| 4. **ํ์ธ** | |
| - `DATABASE_URL`์ด secrets ๋ชฉ๋ก์ ์ถ๊ฐ๋์๋์ง ํ์ธ | |
| ## 4. Spaces ์ฌ๋น๋ ๋ฐ ํ์ธ | |
| ### 4-1. ์๋ ์ฌ๋น๋ | |
| ํ๊ฒฝ ๋ณ์๋ฅผ ์ถ๊ฐํ๋ฉด Hugging Face Spaces๊ฐ ์๋์ผ๋ก ์ฌ๋น๋๋ฅผ ์์ํฉ๋๋ค. | |
| 1. **Settings ํญ์์ ๋น๋ ์ํ ํ์ธ** | |
| - ๋๋ **"Logs"** ํญ์์ ๋น๋ ์งํ ์ํฉ ํ์ธ | |
| - ๋น๋ ์๋ฃ๊น์ง ์ฝ 2-5๋ถ ์์ | |
| ### 4-2. ์ฐ๊ฒฐ ํ์ธ | |
| ์ฌ๋น๋ ์๋ฃ ํ: | |
| **โ ๏ธ ์ค์: ๊ด๋ฆฌ์ ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธํ ์ํ์์๋ง ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.** | |
| 1. **๊ด๋ฆฌ์ ๋ก๊ทธ์ธ**: | |
| - ๋จผ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ด๋ฆฌ์ ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธํฉ๋๋ค | |
| - ๋ก๊ทธ์ธํ์ง ์์ ์ํ์์๋ ์ ๊ทผํ ์ ์์ต๋๋ค | |
| 2. **๋ธ๋ผ์ฐ์ ์์ ๋ค์ URL ์ ์** (GET ์์ฒญ): | |
| ``` | |
| https://wiizm-soyailabs.hf.space/api/admin/database/status | |
| ``` | |
| - โ ๏ธ **GET ๋ฉ์๋๋ง ์ง์**: POST๋ ๋ค๋ฅธ ๋ฉ์๋๋ก ์์ฒญํ๋ฉด "Method Not Allowed" ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค | |
| - ๋ธ๋ผ์ฐ์ ์ฃผ์์ฐฝ์ ์ง์ ์ ๋ ฅํ๊ฑฐ๋, ๊ฐ๋ฐ์ ๋๊ตฌ์์ `fetch()` ์ฌ์ฉ ์ GET ์์ฒญ์ธ์ง ํ์ธํ์ธ์ | |
| 3. **๋๋ ๊ฐ๋ฐ์ ๋๊ตฌ์์ ํ์ธ**: | |
| - ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ(F12) ์ด๊ธฐ | |
| - Console ํญ์์ ๋ค์ ๋ช ๋ น ์คํ: | |
| ```javascript | |
| fetch('/api/admin/database/status', { | |
| method: 'GET', // GET ๋ฉ์๋ ๋ช ์ | |
| credentials: 'include' // ์ฟ ํค ํฌํจ (๋ก๊ทธ์ธ ์ธ์ ) | |
| }) | |
| .then(res => res.json()) | |
| .then(data => console.log('DB ์ํ:', data)); | |
| ``` | |
| 4. **์๋ต ํ์ธ**: | |
| ```json | |
| { | |
| "config_count": 1, | |
| "connected": true, | |
| "error": null, | |
| "table_count": 11, | |
| "test_query": "ํ์ฌ ์๊ฐ: 2025-12-08 17:40:35.168889+00:00", | |
| "type": "PostgreSQL", | |
| "uri_masked": "postgresql://***@hopper.proxy.rlwy.net:15569/railway", | |
| "user_count": 1, | |
| "version": "PostgreSQL 17.7 (Debian 17.7-3.pgdg13+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) " | |
| } | |
| ``` | |
| 3. **์ฑ๊ณต ํ์ธ ์ฌํญ**: | |
| - โ `type: "PostgreSQL"` (SQLite๊ฐ ์๋) | |
| - โ `connected: true` | |
| - โ `version`์ PostgreSQL ๋ฒ์ ํ์ | |
| ## 5. ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ ์๋ ์์ฑ ํ์ธ | |
| ์ ํ๋ฆฌ์ผ์ด์ ์ด ์์๋๋ฉด ์๋์ผ๋ก ํ์ํ ํ ์ด๋ธ๋ค์ด ์์ฑ๋ฉ๋๋ค. | |
| 1. **Logs ํญ ํ์ธ**: | |
| - `[๋ฐ์ดํฐ๋ฒ ์ด์ค] PostgreSQL ์ฐ๊ฒฐ ์ฑ๊ณต!` ๋ฉ์์ง ํ์ธ | |
| - `[๋ฐ์ดํฐ๋ฒ ์ด์ค] ํ ์ด๋ธ ์์ฑ ์๋ฃ` ๋ฉ์์ง ํ์ธ | |
| 2. **Railway์์ ํ์ธ** (์ ํ์ฌํญ): | |
| - Railway ํ๋ก์ ํธ > PostgreSQL ์๋น์ค > **"Data"** ํญ | |
| - ์์ฑ๋ ํ ์ด๋ธ ๋ชฉ๋ก ํ์ธ | |
| ## 6. ์ค์ ์ ์ฅ ํ ์คํธ | |
| PostgreSQL ์ฐ๊ฒฐ์ด ํ์ธ๋๋ฉด: | |
| 1. **๊ด๋ฆฌ์ ํ์ด์ง ์ ์** | |
| - https://wiizm-soyailabs.hf.space/admin/settings | |
| 2. **Gemini API ํค ์ ์ฅ** | |
| - API ํค ์ ๋ ฅ ํ ์ ์ฅ | |
| 3. **์ ์ฅ ํ์ธ** | |
| - `/api/admin/database/status`์์ `config_count` ํ์ธ | |
| - `config_count`๊ฐ 1 ์ด์์ด๋ฉด ์ ์ฅ ์ฑ๊ณต | |
| 4. **์๊ตฌ ์ ์ฅ ํ์ธ** | |
| - Spaces๋ฅผ ์ฌ์์ํ๊ฑฐ๋ ์ ๋ฐ์ดํธํด๋ | |
| - `/api/admin/database/status`์์ `config_count`๊ฐ ์ ์ง๋๋์ง ํ์ธ | |
| ## ๋ฌธ์ ํด๊ฒฐ | |
| ### Method Not Allowed ์ค๋ฅ | |
| **์ฆ์**: `/api/admin/database/status` ์ ์ ์ "Method Not Allowed" ์ค๋ฅ ๋ฐ์ | |
| **์์ธ**: | |
| - ์๋ํฌ์ธํธ๋ **GET ๋ฉ์๋๋ง** ์ง์ํฉ๋๋ค | |
| - POST, PUT, DELETE ๋ฑ์ ๋ค๋ฅธ ๋ฉ์๋๋ก ์์ฒญํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค | |
| **ํด๊ฒฐ ๋ฐฉ๋ฒ**: | |
| 1. **๋ธ๋ผ์ฐ์ ์ฃผ์์ฐฝ์์ ์ง์ ์ ์**: | |
| - ๋ธ๋ผ์ฐ์ ์ฃผ์์ฐฝ์ URL์ ์ง์ ์ ๋ ฅํ๋ฉด ์๋์ผ๋ก GET ์์ฒญ์ด ๋ฉ๋๋ค | |
| - ์: `https://wiizm-soyailabs.hf.space/api/admin/database/status` | |
| 2. **๊ฐ๋ฐ์ ๋๊ตฌ์์ GET ๋ฉ์๋ ๋ช ์**: | |
| ```javascript | |
| fetch('/api/admin/database/status', { | |
| method: 'GET', // GET ๋ช ์ | |
| credentials: 'include' | |
| }) | |
| ``` | |
| 3. **๊ด๋ฆฌ์ ๋ก๊ทธ์ธ ํ์ธ**: | |
| - ๊ด๋ฆฌ์ ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธ๋์ด ์๋์ง ํ์ธ | |
| - ๋ก๊ทธ์ธํ์ง ์์๊ฑฐ๋ ์ผ๋ฐ ์ฌ์ฉ์ ๊ณ์ ์ด๋ฉด ์ ๊ทผํ ์ ์์ต๋๋ค | |
| 4. **curl ๋ช ๋ น์ด ์ฌ์ฉ ์**: | |
| ```bash | |
| curl -X GET https://wiizm-soyailabs.hf.space/api/admin/database/status | |
| ``` | |
| - `-X GET` ์ต์ ์ผ๋ก GET ๋ฉ์๋ ๋ช ์ (๊ธฐ๋ณธ๊ฐ์ด์ง๋ง ๋ช ์ํ๋ ๊ฒ์ด ์์ ) | |
| ### PostgreSQL ์ฐ๊ฒฐ ์คํจ | |
| **์ฆ์**: `/api/admin/database/status`์์ `connected: false` ๋๋ `type: "SQLite"` | |
| **ํด๊ฒฐ ๋ฐฉ๋ฒ**: | |
| 1. **ํ๊ฒฝ ๋ณ์ ํ์ธ**: | |
| - Hugging Face Spaces > Settings > Repository secrets | |
| - `DATABASE_URL`์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ค์ ๋์๋์ง ํ์ธ | |
| - ๊ฐ์ ๊ณต๋ฐฑ์ด๋ ์ค๋ฐ๊ฟ์ด ์๋์ง ํ์ธ | |
| 2. **์ฐ๊ฒฐ ๋ฌธ์์ด ํ์ ํ์ธ**: | |
| - `postgresql://` ๋๋ `postgres://`๋ก ์์ํด์ผ ํจ | |
| - ๋น๋ฐ๋ฒํธ์ ํน์๋ฌธ์๊ฐ ์์ผ๋ฉด URL ์ธ์ฝ๋ฉ ํ์ | |
| - `@` โ `%40` | |
| - `#` โ `%23` | |
| - `%` โ `%25` | |
| - `&` โ `%26` | |
| 3. **Railway ์ฐ๊ฒฐ ์ ๋ณด ์ฌํ์ธ**: | |
| - Railway > PostgreSQL ์๋น์ค > Variables ํญ | |
| - `DATABASE_URL` ๊ฐ์ ๋ค์ ๋ณต์ฌํ์ฌ ํ์ธ | |
| 4. **๋ก๊ทธ ํ์ธ**: | |
| - Hugging Face Spaces > Logs ํญ | |
| - `[๋ฐ์ดํฐ๋ฒ ์ด์ค] PostgreSQL ์ฐ๊ฒฐ ์คํจ: ...` ์ค๋ฅ ๋ฉ์์ง ํ์ธ | |
| - ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฌธ์ ํด๊ฒฐ | |
| ### Railway ์ธ๋ถ ์ฐ๊ฒฐ ๋ฌธ์ | |
| **์ฆ์**: Railway์์ ์ธ๋ถ ์ฐ๊ฒฐ์ด ์ ๋๋ ๊ฒฝ์ฐ | |
| **ํด๊ฒฐ ๋ฐฉ๋ฒ**: | |
| 1. **TCP Proxy ํ์ธ**: | |
| - Railway๋ ๊ธฐ๋ณธ์ ์ผ๋ก TCP Proxy๋ฅผ ํ์ฑํํฉ๋๋ค | |
| - PostgreSQL ์๋น์ค > **"Connect"** ํญ ํ์ธ | |
| - ์ธ๋ถ ์ฐ๊ฒฐ ์ ๋ณด ํ์ธ | |
| 2. **๋คํธ์ํฌ ์๊ธ ํ์ธ**: | |
| - Railway๋ ์ธ๋ถ ์ฐ๊ฒฐ ์ ๋คํธ์ํฌ ์ก์ ๋์ ๋ํ ์๊ธ์ด ๋ถ๊ณผ๋ ์ ์์ต๋๋ค | |
| - ์ฌ์ฉ๋ ๋ชจ๋ํฐ๋ง: Railway ๋์๋ณด๋ > Usage ํญ | |
| ### ์ฌ์ ํ SQLite ์ฌ์ฉ ์ค | |
| **์ฆ์**: ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ๋๋ฐ๋ `type: "SQLite"`๋ก ํ์๋จ | |
| **ํด๊ฒฐ ๋ฐฉ๋ฒ**: | |
| 1. **์ฌ๋น๋ ํ์ธ**: | |
| - ํ๊ฒฝ ๋ณ์ ๋ณ๊ฒฝ ํ Spaces๊ฐ ์ฌ๋น๋๋์๋์ง ํ์ธ | |
| - Settings > Build logs ํ์ธ | |
| 2. **ํ๊ฒฝ ๋ณ์ ์ด๋ฆ ํ์ธ**: | |
| - ์ ํํ `DATABASE_URL`์ธ์ง ํ์ธ (๋์๋ฌธ์ ๊ตฌ๋ถ) | |
| - ๋ค๋ฅธ ์ด๋ฆ์ผ๋ก ์ค์ ํ์ง ์์๋์ง ํ์ธ | |
| 3. **์ฝ๋ ํ์ธ**: | |
| - `app/core/config.py`์์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฝ๋์ง ํ์ธ | |
| - (์ด๋ฏธ ๊ตฌํ๋์ด ์์) | |
| ## Railway ์ถ๊ฐ ๊ธฐ๋ฅ | |
| ### ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฑ์ | |
| 1. **Railway ๋์๋ณด๋** > PostgreSQL ์๋น์ค | |
| 2. **"Backups"** ํญ์์ ๋ฐฑ์ ์ค์ | |
| 3. ์๋ ๋ฐฑ์ ์ค์ผ์ค ์ค์ ๊ฐ๋ฅ | |
| ### ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ํฐ๋ง | |
| 1. **Railway ๋์๋ณด๋** > PostgreSQL ์๋น์ค | |
| 2. **"Metrics"** ํญ์์ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง | |
| 3. ์ฐ๊ฒฐ ์, ์ฟผ๋ฆฌ ์ฑ๋ฅ ๋ฑ ํ์ธ ๊ฐ๋ฅ | |
| ### ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ฅ ๊ธฐ๋ฅ | |
| Railway๋ ๋ค์ PostgreSQL ํ์ฅ์ ์ง์ํฉ๋๋ค: | |
| - PostGIS (์ง๋ฆฌ ๊ณต๊ฐ ๋ฐ์ดํฐ) | |
| - TimescaleDB (์๊ณ์ด ๋ฐ์ดํฐ) | |
| - ๊ธฐํ PostgreSQL ํ์ฅ | |
| ํ์์ Railway ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ถ๊ฐํ์ธ์. | |
| ## ๋น์ฉ ์ ๋ณด | |
| - **Railway ๋ฌด๋ฃ ํฐ์ด**: $5 ํฌ๋ ๋ง/์ | |
| - **PostgreSQL**: ๋ฌด๋ฃ ํฐ์ด์์ ์ฌ์ฉ ๊ฐ๋ฅ | |
| - **์ธ๋ถ ์ฐ๊ฒฐ**: ๋คํธ์ํฌ ์ก์ ๋์ ๋ฐ๋ผ ์๊ธ ๋ถ๊ณผ ๊ฐ๋ฅ | |
| - **์ฌ์ฉ๋ ํ์ธ**: Railway ๋์๋ณด๋ > Usage ํญ | |
| ## ์ฐธ๊ณ ์๋ฃ | |
| - **Railway PostgreSQL ๋ฌธ์**: https://docs.railway.com/guides/postgresql | |
| - **Railway ํ๊ฒฝ ๋ณ์**: https://docs.railway.com/develop/variables | |
| - **PostgreSQL ์ฐ๊ฒฐ ๋ฌธ์์ด**: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING | |
| ## ํ์ธ ์ฒดํฌ๋ฆฌ์คํธ | |
| PostgreSQL ์ค์ ์๋ฃ ํ: | |
| - [ ] Railway์์ PostgreSQL ์๋น์ค ์์ฑ ์๋ฃ | |
| - [ ] `DATABASE_URL` ํ๊ฒฝ ๋ณ์ ๋ณต์ฌ ์๋ฃ | |
| - [ ] Hugging Face Spaces์ `DATABASE_URL` ํ๊ฒฝ ๋ณ์ ์ถ๊ฐ ์๋ฃ | |
| - [ ] Spaces ์ฌ๋น๋ ์๋ฃ | |
| - [ ] `/api/admin/database/status`์์ `type: "PostgreSQL"` ํ์ธ | |
| - [ ] `connected: true` ํ์ธ | |
| - [ ] Gemini API ํค ์ ์ฅ ํ `config_count` ์ฆ๊ฐ ํ์ธ | |
| - [ ] Spaces ์ฌ์์ ํ์๋ ๋ฐ์ดํฐ ์ ์ง ํ์ธ | |
| ๋ชจ๋ ํญ๋ชฉ์ด ์ฒดํฌ๋๋ฉด PostgreSQL ์ค์ ์ด ์๋ฃ๋ ๊ฒ์ ๋๋ค! ๐ | |