diff --git a/QUICK-START.md b/QUICK-START.md new file mode 100644 index 0000000..0eda7a7 --- /dev/null +++ b/QUICK-START.md @@ -0,0 +1,223 @@ +# ๐Ÿš€ ๋น ๋ฅธ ์‹œ์ž‘ ๊ฐ€์ด๋“œ + +Document Server๋ฅผ Synology DS1525+์— ๋ฐฐํฌํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. + +## ๐Ÿ“‹ ์ค€๋น„์‚ฌํ•ญ + +- Synology DS1525+ (32GB RAM, SSD ์บ์‹œ ํ™œ์„ฑํ™”) +- Docker ํŒจํ‚ค์ง€ ์„ค์น˜ (Package Center์—์„œ ์„ค์น˜) +- SSH ์ ‘์† ๊ฐ€๋Šฅ +- Git ์„ค์น˜ (์„ ํƒ์‚ฌํ•ญ) + +## ๐ŸŽฏ ํ•œ ๋ฒˆ์— ๋ฐฐํฌํ•˜๊ธฐ + +### ๋ฐฉ๋ฒ• 1: Git ํด๋ก  (๊ถŒ์žฅ) โญ + +```bash +# 1. NAS์— SSH ์ ‘์† +ssh admin@your-nas-ip + +# 2. ํ”„๋กœ์ ํŠธ ํด๋ก  +cd /volume1/docker/ +git clone https://git.hyungi.net/hyungi/document-server.git +cd document-server + +# 3. ์ž๋™ ๋ฐฐํฌ (ํ™˜๊ฒฝ ์„ค์ • + ๋ฐฐํฌ) +./scripts/deploy-synology.sh +``` + +### ๋ฐฉ๋ฒ• 2: ํŒŒ์ผ ์—…๋กœ๋“œ + +```bash +# 1. ๋กœ์ปฌ์—์„œ NAS๋กœ ํŒŒ์ผ ์ „์†ก +scp -r ./document-server admin@your-nas-ip:/volume1/docker/ + +# 2. NAS์— SSH ์ ‘์† +ssh admin@your-nas-ip +cd /volume1/docker/document-server + +# 3. ์ž๋™ ๋ฐฐํฌ +./scripts/deploy-synology.sh +``` + +## โš™๏ธ ํ™˜๊ฒฝ ์„ค์ • (์ž๋™) + +๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์‹œ ์ž๋™์œผ๋กœ ํ™˜๊ฒฝ ์„ค์ •์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค: + +``` +=== ๐Ÿ”ง Document Server ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • === + +1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋น„๋ฐ€๋ฒˆํ˜ธ + ๊ธฐ๋ณธ๊ฐ’: AbC123XyZ (์ž๋™์ƒ์„ฑ) + ์ž…๋ ฅ: [์—”ํ„ฐ = ๊ธฐ๋ณธ๊ฐ’ ์‚ฌ์šฉ] + +2. JWT ์‹œํฌ๋ฆฟ ํ‚ค (๋ณด์•ˆ์šฉ) + ๊ธฐ๋ณธ๊ฐ’: kL9mN2pQ... (์ž๋™์ƒ์„ฑ) + ์ž…๋ ฅ: [์—”ํ„ฐ = ๊ธฐ๋ณธ๊ฐ’ ์‚ฌ์šฉ] + +3. ๊ด€๋ฆฌ์ž ์ด๋ฉ”์ผ + ๊ธฐ๋ณธ๊ฐ’: admin@document-server.local + ์ž…๋ ฅ: admin@mydomain.com + +4. ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ + ๊ธฐ๋ณธ๊ฐ’: MyPass123 (์ž๋™์ƒ์„ฑ) + ์ž…๋ ฅ: [์—”ํ„ฐ = ๊ธฐ๋ณธ๊ฐ’ ์‚ฌ์šฉ] + +5. ๋„๋ฉ”์ธ ์ด๋ฆ„ (์™ธ๋ถ€ ์ ‘์†์šฉ) + ๊ธฐ๋ณธ๊ฐ’: localhost + ์ž…๋ ฅ: nas.mydomain.com +``` + +**๐Ÿ’ก ํŒ**: ๋Œ€๋ถ€๋ถ„ ์—”ํ„ฐ๋งŒ ๋ˆŒ๋Ÿฌ๋„ ์•ˆ์ „ํ•œ ๊ธฐ๋ณธ๊ฐ’์ด ์ž๋™ ์„ค์ •๋ฉ๋‹ˆ๋‹ค! + +## ๐ŸŽ‰ ๋ฐฐํฌ ์™„๋ฃŒ ํ›„ + +### ์ ‘์† ํ™•์ธ +``` +๐ŸŒ ์›น ์ธํ„ฐํŽ˜์ด์Šค: http://your-nas-ip:24100 +๐Ÿ“ง ๊ด€๋ฆฌ์ž ์ด๋ฉ”์ผ: admin@document-server.local +๐Ÿ”‘ ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ: (์„ค์ • ์‹œ ํ‘œ์‹œ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ) +``` + +### ์ฃผ์š” ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ +1. **ํ• ์ผ๊ด€๋ฆฌ**: `http://your-nas-ip:24100/todos.html` +2. **๋ฉ”๋ชจ ํŠธ๋ฆฌ**: `http://your-nas-ip:24100/memo-tree.html` +3. **๋…ธํŠธ๋ถ**: `http://your-nas-ip:24100/notebooks.html` +4. **๋ฌธ์„œ ์—…๋กœ๋“œ**: ๋ฉ”์ธ ํŽ˜์ด์ง€์—์„œ HTML ํŒŒ์ผ ๋“œ๋ž˜๊ทธ&๋“œ๋กญ + +## ๐Ÿ”„ ์—…๋ฐ์ดํŠธ ๋ฐฉ๋ฒ• + +### Git ์‚ฌ์šฉ (๊ถŒ์žฅ) +```bash +# NAS์— SSH ์ ‘์† +ssh admin@your-nas-ip +cd /volume1/docker/document-server + +# ์ž๋™ ์—…๋ฐ์ดํŠธ (๋ฐฑ์—… + ์—…๋ฐ์ดํŠธ + ํ—ฌ์Šค์ฒดํฌ) +./scripts/update-synology.sh +``` + +### ์ˆ˜๋™ ์—…๋ฐ์ดํŠธ +```bash +# 1. ์ฝ”๋“œ ์—…๋ฐ์ดํŠธ +git pull origin main + +# 2. ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘ +docker-compose -f docker-compose.synology-optimized.yml restart +``` + +## ๐Ÿ“Š ๋ชจ๋‹ˆํ„ฐ๋ง + +```bash +# ์‹œ์Šคํ…œ ์ƒํƒœ ํ™•์ธ +./scripts/monitor-synology.sh + +# ์‹ค์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋ง (5์ดˆ ๊ฐ„๊ฒฉ) +watch -n 5 './scripts/monitor-synology.sh' + +# ๋กœ๊ทธ ํ™•์ธ +docker-compose -f docker-compose.synology-optimized.yml logs -f +``` + +## ๐Ÿšจ ๋ฌธ์ œ ํ•ด๊ฒฐ + +### ํฌํŠธ ์ถฉ๋Œ +```bash +# ํฌํŠธ ์‚ฌ์šฉ ํ™•์ธ +netstat -tuln | grep -E "(24100|24101|24102|24103)" + +# ๋‹ค๋ฅธ ํฌํŠธ ์‚ฌ์šฉ ์‹œ .env.synology ํŒŒ์ผ ์ˆ˜์ • +nano .env.synology +# EXTERNAL_PORT=24200 (์˜ˆ์‹œ) +``` + +### ๊ถŒํ•œ ๋ฌธ์ œ +```bash +# ๋””๋ ‰ํ† ๋ฆฌ ๊ถŒํ•œ ์ˆ˜์ • +sudo chown -R 1000:1000 /volume1/docker/document-server/ +sudo chown -R 1000:1000 /volume2/document-storage/ +``` + +### ์„œ๋น„์Šค ์žฌ์‹œ์ž‘ +```bash +# ์ „์ฒด ์žฌ์‹œ์ž‘ +docker-compose -f docker-compose.synology-optimized.yml restart + +# ํŠน์ • ์„œ๋น„์Šค๋งŒ ์žฌ์‹œ์ž‘ +docker-compose -f docker-compose.synology-optimized.yml restart backend +``` + +### ๋กค๋ฐฑ (์—…๋ฐ์ดํŠธ ์‹คํŒจ ์‹œ) +```bash +# ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋กค๋ฐฑ +./scripts/update-synology.sh rollback +``` + +## ๐Ÿ’พ ๋ฐฑ์—… + +### ์ž๋™ ๋ฐฑ์—… ์„ค์ • +```bash +# Synology ์ž‘์—… ์Šค์ผ€์ค„๋Ÿฌ์—์„œ ์„ค์ • +# ์ œ์–ดํŒ > ์ž‘์—… ์Šค์ผ€์ค„๋Ÿฌ > ์ƒ์„ฑ > ์‚ฌ์šฉ์ž ์ •์˜ ์Šคํฌ๋ฆฝํŠธ + +# ๋งค์ผ ์ƒˆ๋ฒฝ 2์‹œ ๋ฐฑ์—… +0 2 * * * /volume1/docker/document-server/backup.sh +``` + +### ์ˆ˜๋™ ๋ฐฑ์—… +```bash +# ์ฆ‰์‹œ ๋ฐฑ์—… ์‹คํ–‰ +/volume1/docker/document-server/backup.sh + +# ๋ฐฑ์—… ํŒŒ์ผ ํ™•์ธ +ls -la /volume2/document-storage/backups/ +``` + +## ๐Ÿ”’ ๋ณด์•ˆ ์„ค์ • + +### ๋ฐฉํ™”๋ฒฝ (๊ถŒ์žฅ) +```bash +# Synology ์ œ์–ดํŒ > ๋ณด์•ˆ > ๋ฐฉํ™”๋ฒฝ +# ๊ทœ์น™ ์ถ”๊ฐ€: ํฌํŠธ 24100 ํ—ˆ์šฉ +``` + +### SSL ์ธ์ฆ์„œ (์™ธ๋ถ€ ์ ‘์† ์‹œ) +```bash +# Let's Encrypt ์ธ์ฆ์„œ ๋ฐœ๊ธ‰ +certbot certonly --webroot -w /volume2/document-storage/documents -d your-domain.com +``` + +## ๐Ÿ“ž ๋„์›€๋ง + +### ๋กœ๊ทธ ์ˆ˜์ง‘ (๋ฌธ์ œ ๋ณด๊ณ  ์‹œ) +```bash +# ์‹œ์Šคํ…œ ๋ฆฌํฌํŠธ ์ƒ์„ฑ +./scripts/monitor-synology.sh > system-report.txt + +# ๋กœ๊ทธ ํŒŒ์ผ ์œ„์น˜ +/volume1/docker/document-server/logs/ +``` + +### ์œ ์šฉํ•œ ๋ช…๋ น์–ด +```bash +# Docker ์ƒํƒœ ํ™•์ธ +docker ps +docker stats + +# ๋””์Šคํฌ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ +df -h /volume1 /volume2 + +# ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ +free -h +``` + +--- + +## ๐ŸŽฏ ์š”์•ฝ + +1. **๋ฐฐํฌ**: `./scripts/deploy-synology.sh` (ํ•œ ๋ฒˆ๋งŒ) +2. **์—…๋ฐ์ดํŠธ**: `./scripts/update-synology.sh` (ํ•„์š”์‹œ) +3. **๋ชจ๋‹ˆํ„ฐ๋ง**: `./scripts/monitor-synology.sh` (์ƒํƒœ ํ™•์ธ) +4. **์ ‘์†**: `http://your-nas-ip:24100` + +**๐ŸŽ‰ ์ด์ œ Document Server๋ฅผ ์‚ฌ์šฉํ•  ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!** diff --git a/docker-compose.synology-optimized.yml b/docker-compose.synology-optimized.yml index 9498234..0fb928c 100644 --- a/docker-compose.synology-optimized.yml +++ b/docker-compose.synology-optimized.yml @@ -13,8 +13,8 @@ services: POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C" volumes: # SSD: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (์„ฑ๋Šฅ ์ตœ์šฐ์„ ) - - /volume1/docker/document-server/database:/var/lib/postgresql/data - - /volume1/docker/document-server/config/postgresql.synology.conf:/etc/postgresql/postgresql.conf:ro + - /volume3/docker/document-server/database:/var/lib/postgresql/data + - /volume3/docker/document-server/config/postgresql.synology.conf:/etc/postgresql/postgresql.conf:ro - ./database/init:/docker-entrypoint-initdb.d:ro ports: - "24101:5432" @@ -53,7 +53,7 @@ services: restart: unless-stopped volumes: # SSD: Redis ๋ฐ์ดํ„ฐ (๋น ๋ฅธ ์บ์‹œ) - - /volume1/docker/document-server/redis:/data + - /volume3/docker/document-server/redis:/data ports: - "24103:6379" command: > @@ -100,15 +100,15 @@ services: - MAX_FILE_SIZE=500000000 volumes: # SSD: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ ๋ฐ ์„ค์ • (๋น ๋ฅธ ์•ก์„ธ์Šค) - - /volume1/docker/document-server/logs:/app/logs - - /volume1/docker/document-server/config:/app/config - - /volume1/docker/document-server/cache:/app/cache + - /volume3/docker/document-server/logs:/app/logs + - /volume3/docker/document-server/config:/app/config + - /volume3/docker/document-server/cache:/app/cache # HDD: ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ ์ €์žฅ์†Œ (๋น„์šฉ ํšจ์œจ์ ) - - /volume2/document-storage/uploads:/app/uploads - - /volume2/document-storage/documents:/app/documents - - /volume2/document-storage/thumbnails:/app/thumbnails - - /volume2/document-storage/backups:/app/backups + - /volume1/document-storage/uploads:/app/uploads + - /volume1/document-storage/documents:/app/documents + - /volume1/document-storage/thumbnails:/app/thumbnails + - /volume1/document-storage/backups:/app/backups ports: - "24102:8000" depends_on: @@ -139,16 +139,16 @@ services: restart: unless-stopped volumes: # SSD: Nginx ์„ค์ •, ๋กœ๊ทธ, ์บ์‹œ (์„ฑ๋Šฅ ์ตœ์ ํ™”) - - /volume1/docker/document-server/nginx/conf.d:/etc/nginx/conf.d - - /volume1/docker/document-server/nginx/cache:/var/cache/nginx - - /volume1/docker/document-server/logs/nginx:/var/log/nginx + - /volume3/docker/document-server/nginx/conf.d:/etc/nginx/conf.d + - /volume3/docker/document-server/nginx/cache:/var/cache/nginx + - /volume3/docker/document-server/logs/nginx:/var/log/nginx # SSD: ํ”„๋ก ํŠธ์—”๋“œ ์ •์  ํŒŒ์ผ (๋น ๋ฅธ ์„œ๋น™) - ./frontend:/usr/share/nginx/html:ro # HDD: ๋Œ€์šฉ๋Ÿ‰ ๋ฌธ์„œ ํŒŒ์ผ (์ฝ๊ธฐ ์ „์šฉ) - - /volume2/document-storage/uploads:/usr/share/nginx/html/uploads:ro - - /volume2/document-storage/documents:/usr/share/nginx/html/documents:ro + - /volume1/document-storage/uploads:/usr/share/nginx/html/uploads:ro + - /volume1/document-storage/documents:/usr/share/nginx/html/documents:ro ports: - "24100:80" depends_on: diff --git a/scripts/deploy-synology.sh b/scripts/deploy-synology.sh index baf9427..2427620 100755 --- a/scripts/deploy-synology.sh +++ b/scripts/deploy-synology.sh @@ -41,12 +41,24 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(dirname "$SCRIPT_DIR")" COMPOSE_FILE="docker-compose.synology-optimized.yml" -# ๊ธฐ๋ณธ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ -export DB_PASSWORD="${DB_PASSWORD:-$(openssl rand -base64 32)}" -export SECRET_KEY="${SECRET_KEY:-$(openssl rand -base64 64)}" -export ADMIN_EMAIL="${ADMIN_EMAIL:-admin@document-server.local}" -export ADMIN_PASSWORD="${ADMIN_PASSWORD:-$(openssl rand -base64 16)}" -export DOMAIN_NAME="${DOMAIN_NAME:-localhost}" +# ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • ํ™•์ธ +ENV_FILE="$PROJECT_DIR/.env.synology" + +if [ ! -f "$ENV_FILE" ]; then + log_info "ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ์ด ์—†์Šต๋‹ˆ๋‹ค. ์„ค์ •์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค..." + "$SCRIPT_DIR/setup-env.sh" +fi + +# ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋กœ๋“œ +if [ -f "$ENV_FILE" ]; then + log_info "ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค: $ENV_FILE" + set -a # ์ž๋™์œผ๋กœ export + source "$ENV_FILE" + set +a +else + log_error "ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค" + exit 1 +fi log_info "๐Ÿš€ Synology DS1525+ ์ตœ์ ํ™” ๋ฐฐํฌ ์‹œ์ž‘" log_info "๐Ÿ“ ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ: $PROJECT_DIR" @@ -76,25 +88,25 @@ log_success "์‹œ์Šคํ…œ ์š”๊ตฌ์‚ฌํ•ญ ํ™•์ธ ์™„๋ฃŒ" # 2. ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ ์ƒ์„ฑ log_info "๐Ÿ“‚ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ ์ƒ์„ฑ ์ค‘..." -# SSD ๋””๋ ‰ํ† ๋ฆฌ (์„ฑ๋Šฅ ์ตœ์šฐ์„ ) +# SSD ๋””๋ ‰ํ† ๋ฆฌ (์„ฑ๋Šฅ ์ตœ์šฐ์„ ) - Volume3 SSD_DIRS=( - "/volume1/docker/document-server/database" - "/volume1/docker/document-server/redis" - "/volume1/docker/document-server/logs" - "/volume1/docker/document-server/logs/nginx" - "/volume1/docker/document-server/config" - "/volume1/docker/document-server/nginx/conf.d" - "/volume1/docker/document-server/nginx/cache" - "/volume1/docker/document-server/cache" + "/volume3/docker/document-server/database" + "/volume3/docker/document-server/redis" + "/volume3/docker/document-server/logs" + "/volume3/docker/document-server/logs/nginx" + "/volume3/docker/document-server/config" + "/volume3/docker/document-server/nginx/conf.d" + "/volume3/docker/document-server/nginx/cache" + "/volume3/docker/document-server/cache" ) -# HDD ๋””๋ ‰ํ† ๋ฆฌ (๋Œ€์šฉ๋Ÿ‰ ์ €์žฅ) +# HDD ๋””๋ ‰ํ† ๋ฆฌ (๋Œ€์šฉ๋Ÿ‰ ์ €์žฅ) - Volume1 HDD_DIRS=( - "/volume2/document-storage/uploads" - "/volume2/document-storage/documents" - "/volume2/document-storage/thumbnails" - "/volume2/document-storage/backups" - "/volume2/document-storage/archives" + "/volume1/document-storage/uploads" + "/volume1/document-storage/documents" + "/volume1/document-storage/thumbnails" + "/volume1/document-storage/backups" + "/volume1/document-storage/archives" ) # SSD ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ @@ -114,8 +126,8 @@ for dir in "${HDD_DIRS[@]}"; do done # ๊ถŒํ•œ ์„ค์ • -sudo chown -R 1000:1000 /volume1/docker/document-server/ -sudo chown -R 1000:1000 /volume2/document-storage/ +sudo chown -R 1000:1000 /volume3/docker/document-server/ +sudo chown -R 1000:1000 /volume1/document-storage/ log_success "๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ ์ƒ์„ฑ ์™„๋ฃŒ" @@ -123,7 +135,7 @@ log_success "๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ ์ƒ์„ฑ ์™„๋ฃŒ" log_info "โš™๏ธ ์„ค์ • ํŒŒ์ผ ์ƒ์„ฑ ์ค‘..." # PostgreSQL ์„ค์ • (32GB RAM ์ตœ์ ํ™”) -cat > /volume1/docker/document-server/config/postgresql.synology.conf << 'EOF' +cat > /volume3/docker/document-server/config/postgresql.synology.conf << 'EOF' # PostgreSQL ์„ค์ • - Synology DS1525+ 32GB RAM ์ตœ์ ํ™” # ๋ฉ”๋ชจ๋ฆฌ ์„ค์ • (32GB RAM ๊ธฐ์ค€) @@ -168,7 +180,7 @@ autovacuum_naptime = 30s EOF # Nginx ์„ค์ • (SSD ์บ์‹œ ์ตœ์ ํ™”) -cat > /volume1/docker/document-server/nginx/conf.d/default.conf << 'EOF' +cat > /volume3/docker/document-server/nginx/conf.d/default.conf << 'EOF' # Nginx ์„ค์ • - SSD ์บ์‹œ ์ตœ์ ํ™” # ์—…์ŠคํŠธ๋ฆผ ๋ฐฑ์—”๋“œ diff --git a/scripts/setup-env.sh b/scripts/setup-env.sh new file mode 100755 index 0000000..3a68976 --- /dev/null +++ b/scripts/setup-env.sh @@ -0,0 +1,257 @@ +#!/bin/bash + +# ============================================================================= +# Document Server - ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • ์Šคํฌ๋ฆฝํŠธ +# ๋Œ€ํ™”ํ˜•์œผ๋กœ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๊ณ  .env ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค +# ============================================================================= + +set -e + +# ์ƒ‰์ƒ ์ •์˜ +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' + +# ๋กœ๊ทธ ํ•จ์ˆ˜ +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +log_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +# ๋ณด์•ˆ ํ‚ค ์ƒ์„ฑ ํ•จ์ˆ˜ +generate_secure_key() { + openssl rand -base64 32 | tr -d "=+/" | cut -c1-32 +} + +generate_jwt_key() { + openssl rand -base64 64 | tr -d "=+/" | cut -c1-64 +} + +generate_password() { + openssl rand -base64 16 | tr -d "=+/" | cut -c1-12 +} + +# ํ™˜๊ฒฝ ์„ค์ • +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +ENV_FILE="$PROJECT_DIR/.env.synology" + +cd "$PROJECT_DIR" + +echo "=== ๐Ÿ”ง Document Server ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • ===" +echo "" + +# ๊ธฐ์กด .env ํŒŒ์ผ ํ™•์ธ +if [ -f "$ENV_FILE" ]; then + log_warning "๊ธฐ์กด ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค: $ENV_FILE" + echo "" + read -p "๊ธฐ์กด ์„ค์ •์„ ๋ฎ์–ด์“ฐ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? (y/N): " -n 1 -r + echo "" + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + log_info "๊ธฐ์กด ์„ค์ •์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค" + exit 0 + fi + + # ๊ธฐ์กด ํŒŒ์ผ ๋ฐฑ์—… + cp "$ENV_FILE" "$ENV_FILE.backup.$(date +%Y%m%d_%H%M%S)" + log_info "๊ธฐ์กด ํŒŒ์ผ์„ ๋ฐฑ์—…ํ–ˆ์Šต๋‹ˆ๋‹ค" +fi + +echo "" +log_info "ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์—”ํ„ฐ๋ฅผ ๋ˆ„๋ฅด๋ฉด ๊ธฐ๋ณธ๊ฐ’/์ž๋™์ƒ์„ฑ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค." +echo "" + +# 1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋น„๋ฐ€๋ฒˆํ˜ธ +echo -e "${CYAN}1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋น„๋ฐ€๋ฒˆํ˜ธ${NC}" +DEFAULT_DB_PASSWORD=$(generate_password) +echo " ๊ธฐ๋ณธ๊ฐ’: $DEFAULT_DB_PASSWORD (์ž๋™์ƒ์„ฑ)" +read -p " ์ž…๋ ฅ: " DB_PASSWORD +DB_PASSWORD=${DB_PASSWORD:-$DEFAULT_DB_PASSWORD} + +# 2. JWT ์‹œํฌ๋ฆฟ ํ‚ค +echo "" +echo -e "${CYAN}2. JWT ์‹œํฌ๋ฆฟ ํ‚ค (๋ณด์•ˆ์šฉ)${NC}" +DEFAULT_SECRET_KEY=$(generate_jwt_key) +echo " ๊ธฐ๋ณธ๊ฐ’: ${DEFAULT_SECRET_KEY:0:20}... (์ž๋™์ƒ์„ฑ)" +read -p " ์ž…๋ ฅ: " SECRET_KEY +SECRET_KEY=${SECRET_KEY:-$DEFAULT_SECRET_KEY} + +# 3. ๊ด€๋ฆฌ์ž ์ด๋ฉ”์ผ +echo "" +echo -e "${CYAN}3. ๊ด€๋ฆฌ์ž ์ด๋ฉ”์ผ${NC}" +DEFAULT_ADMIN_EMAIL="admin@document-server.local" +echo " ๊ธฐ๋ณธ๊ฐ’: $DEFAULT_ADMIN_EMAIL" +read -p " ์ž…๋ ฅ: " ADMIN_EMAIL +ADMIN_EMAIL=${ADMIN_EMAIL:-$DEFAULT_ADMIN_EMAIL} + +# 4. ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ +echo "" +echo -e "${CYAN}4. ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ${NC}" +DEFAULT_ADMIN_PASSWORD=$(generate_password) +echo " ๊ธฐ๋ณธ๊ฐ’: $DEFAULT_ADMIN_PASSWORD (์ž๋™์ƒ์„ฑ)" +read -p " ์ž…๋ ฅ: " ADMIN_PASSWORD +ADMIN_PASSWORD=${ADMIN_PASSWORD:-$DEFAULT_ADMIN_PASSWORD} + +# 5. ๋„๋ฉ”์ธ ์ด๋ฆ„ +echo "" +echo -e "${CYAN}5. ๋„๋ฉ”์ธ ์ด๋ฆ„ (์™ธ๋ถ€ ์ ‘์†์šฉ)${NC}" +DEFAULT_DOMAIN="localhost" +echo " ๊ธฐ๋ณธ๊ฐ’: $DEFAULT_DOMAIN" +echo " ์˜ˆ์‹œ: mydomain.com, nas.mydomain.com" +read -p " ์ž…๋ ฅ: " DOMAIN_NAME +DOMAIN_NAME=${DOMAIN_NAME:-$DEFAULT_DOMAIN} + +# 6. ์™ธ๋ถ€ ํฌํŠธ (์„ ํƒ์‚ฌํ•ญ) +echo "" +echo -e "${CYAN}6. ์™ธ๋ถ€ ํฌํŠธ (๊ธฐ๋ณธ: 24100)${NC}" +DEFAULT_PORT="24100" +echo " ๊ธฐ๋ณธ๊ฐ’: $DEFAULT_PORT" +read -p " ์ž…๋ ฅ: " EXTERNAL_PORT +EXTERNAL_PORT=${EXTERNAL_PORT:-$DEFAULT_PORT} + +# .env ํŒŒ์ผ ์ƒ์„ฑ +echo "" +log_info "ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ ์ƒ์„ฑ ์ค‘..." + +cat > "$ENV_FILE" << EOF +# ============================================================================= +# Document Server - Synology DS1525+ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ +# ์ƒ์„ฑ์ผ: $(date '+%Y-%m-%d %H:%M:%S') +# ============================================================================= + +# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ • +DB_PASSWORD=$DB_PASSWORD +POSTGRES_PASSWORD=$DB_PASSWORD + +# ๋ณด์•ˆ ์„ค์ • +SECRET_KEY=$SECRET_KEY +JWT_SECRET_KEY=$SECRET_KEY + +# ๊ด€๋ฆฌ์ž ๊ณ„์ • +ADMIN_EMAIL=$ADMIN_EMAIL +ADMIN_PASSWORD=$ADMIN_PASSWORD + +# ๋„คํŠธ์›Œํฌ ์„ค์ • +DOMAIN_NAME=$DOMAIN_NAME +EXTERNAL_PORT=$EXTERNAL_PORT + +# CORS ์„ค์ • (๋„๋ฉ”์ธ์— ๋”ฐ๋ผ ์ž๋™ ์„ค์ •) +ALLOWED_ORIGINS=http://localhost:$EXTERNAL_PORT,http://$DOMAIN_NAME:$EXTERNAL_PORT + +# ์„ฑ๋Šฅ ์ตœ์ ํ™” ์„ค์ • (DS1525+ 32GB RAM) +POSTGRES_SHARED_BUFFERS=8GB +POSTGRES_EFFECTIVE_CACHE_SIZE=24GB +POSTGRES_WORK_MEM=512MB +POSTGRES_MAINTENANCE_WORK_MEM=4GB + +# Redis ์„ค์ • +REDIS_MAXMEMORY=8gb +REDIS_MAXMEMORY_POLICY=allkeys-lru + +# ๋กœ๊ทธ ๋ ˆ๋ฒจ +LOG_LEVEL=INFO +DEBUG=false + +# ํŒŒ์ผ ์—…๋กœ๋“œ ์„ค์ • +MAX_FILE_SIZE=500000000 +UPLOAD_DIR=/app/uploads + +# ๋ฐฑ์—… ์„ค์ • +BACKUP_RETENTION_DAYS=30 +AUTO_BACKUP_ENABLED=true + +# ๋ชจ๋‹ˆํ„ฐ๋ง ์„ค์ • +HEALTH_CHECK_INTERVAL=30s +HEALTH_CHECK_TIMEOUT=10s +HEALTH_CHECK_RETRIES=3 + +# ์Šคํ† ๋ฆฌ์ง€ ๊ฒฝ๋กœ (Synology ์ตœ์ ํ™”) +SSD_PATH=/volume3/docker/document-server +HDD_PATH=/volume1/document-storage + +# ํƒ€์ž„์กด ์„ค์ • +TZ=Asia/Seoul +EOF + +# ํŒŒ์ผ ๊ถŒํ•œ ์„ค์ • (๋ณด์•ˆ) +chmod 600 "$ENV_FILE" + +log_success "ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค: $ENV_FILE" + +# ์„ค์ • ์š”์•ฝ ์ถœ๋ ฅ +echo "" +echo "=== ๐Ÿ“‹ ์„ค์ • ์š”์•ฝ ===" +echo -e "๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋น„๋ฐ€๋ฒˆํ˜ธ: ${CYAN}$DB_PASSWORD${NC}" +echo -e "๊ด€๋ฆฌ์ž ์ด๋ฉ”์ผ: ${CYAN}$ADMIN_EMAIL${NC}" +echo -e "๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ: ${CYAN}$ADMIN_PASSWORD${NC}" +echo -e "๋„๋ฉ”์ธ: ${CYAN}$DOMAIN_NAME${NC}" +echo -e "ํฌํŠธ: ${CYAN}$EXTERNAL_PORT${NC}" +echo "" + +# ๋ณด์•ˆ ์ •๋ณด ์ €์žฅ +SECURITY_INFO_FILE="/volume1/document-storage/backups/security-info-$(date +%Y%m%d_%H%M%S).txt" +mkdir -p "$(dirname "$SECURITY_INFO_FILE")" 2>/dev/null || true + +cat > "$SECURITY_INFO_FILE" << EOF +Document Server ๋ณด์•ˆ ์ •๋ณด +์ƒ์„ฑ์ผ: $(date '+%Y-%m-%d %H:%M:%S') + +=== ๊ด€๋ฆฌ์ž ๊ณ„์ • === +์ด๋ฉ”์ผ: $ADMIN_EMAIL +๋น„๋ฐ€๋ฒˆํ˜ธ: $ADMIN_PASSWORD + +=== ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค === +์‚ฌ์šฉ์ž: docuser +๋น„๋ฐ€๋ฒˆํ˜ธ: $DB_PASSWORD + +=== ์ ‘์† ์ •๋ณด === +์›น ์ธํ„ฐํŽ˜์ด์Šค: http://$DOMAIN_NAME:$EXTERNAL_PORT +API ๋ฌธ์„œ: http://$DOMAIN_NAME:$((EXTERNAL_PORT + 2))/docs + +=== ์ค‘์š” ์•ˆ๋‚ด === +- ์ด ํŒŒ์ผ์€ ์•ˆ์ „ํ•œ ๊ณณ์— ๋ณด๊ด€ํ•˜์„ธ์š” +- ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์ •๊ธฐ์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์„ธ์š” +- ์™ธ๋ถ€ ์ ‘์† ์‹œ HTTPS ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค +EOF + +chmod 600 "$SECURITY_INFO_FILE" 2>/dev/null || true + +log_success "๋ณด์•ˆ ์ •๋ณด๊ฐ€ ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค: $SECURITY_INFO_FILE" + +# ๋‹ค์Œ ๋‹จ๊ณ„ ์•ˆ๋‚ด +echo "" +echo "=== ๐Ÿš€ ๋‹ค์Œ ๋‹จ๊ณ„ ===" +echo "1. ๋ฐฐํฌ ์‹คํ–‰:" +echo " ${CYAN}./scripts/deploy-synology.sh${NC}" +echo "" +echo "2. ์ƒํƒœ ํ™•์ธ:" +echo " ${CYAN}./scripts/monitor-synology.sh${NC}" +echo "" +echo "3. ์›น ์ ‘์†:" +echo " ${CYAN}http://$DOMAIN_NAME:$EXTERNAL_PORT${NC}" +echo "" + +# SSL ์„ค์ • ๊ถŒ์žฅ์‚ฌํ•ญ +if [ "$DOMAIN_NAME" != "localhost" ]; then + echo "=== ๐Ÿ”’ ๋ณด์•ˆ ๊ถŒ์žฅ์‚ฌํ•ญ ===" + echo "์™ธ๋ถ€ ๋„๋ฉ”์ธ์„ ์‚ฌ์šฉํ•˜์‹œ๋Š” ๊ฒฝ์šฐ SSL ์ธ์ฆ์„œ ์„ค์ •์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค:" + echo "" + echo "1. Let's Encrypt ์ธ์ฆ์„œ ๋ฐœ๊ธ‰:" + echo " ${CYAN}certbot certonly --webroot -w /volume2/document-storage/documents -d $DOMAIN_NAME${NC}" + echo "" + echo "2. Nginx SSL ์„ค์ • ์ถ”๊ฐ€" + echo "3. ๋ฐฉํ™”๋ฒฝ์—์„œ HTTPS(443) ํฌํŠธ ๊ฐœ๋ฐฉ" + echo "" +fi + +log_success "ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!" diff --git a/scripts/update-synology.sh b/scripts/update-synology.sh new file mode 100755 index 0000000..1accacb --- /dev/null +++ b/scripts/update-synology.sh @@ -0,0 +1,303 @@ +#!/bin/bash + +# ============================================================================= +# Document Server - Synology ์—…๋ฐ์ดํŠธ ์Šคํฌ๋ฆฝํŠธ +# Git์„ ํ†ตํ•œ ๋ฌด์ค‘๋‹จ ์—…๋ฐ์ดํŠธ ๋ฐ ๋กค๋ฐฑ ์ง€์› +# ============================================================================= + +set -e + +# ์ƒ‰์ƒ ์ •์˜ +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +# ๋กœ๊ทธ ํ•จ์ˆ˜ +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +log_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# ํ™˜๊ฒฝ ์„ค์ • +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +COMPOSE_FILE="docker-compose.synology-optimized.yml" +BACKUP_DIR="/volume2/document-storage/backups" +UPDATE_LOG="/volume1/docker/document-server/logs/update.log" + +# ์—…๋ฐ์ดํŠธ ๋ชจ๋“œ ์„ค์ • +UPDATE_MODE="${1:-safe}" # safe, force, rollback + +log_info "๐Ÿ”„ Document Server ์—…๋ฐ์ดํŠธ ์‹œ์ž‘ (๋ชจ๋“œ: $UPDATE_MODE)" +echo "$(date '+%Y-%m-%d %H:%M:%S') - ์—…๋ฐ์ดํŠธ ์‹œ์ž‘: $UPDATE_MODE" >> "$UPDATE_LOG" + +cd "$PROJECT_DIR" + +# ํ˜„์žฌ ์ƒํƒœ ํ™•์ธ +log_info "๐Ÿ“Š ํ˜„์žฌ ์ƒํƒœ ํ™•์ธ ์ค‘..." + +# Git ์ƒํƒœ ํ™•์ธ +if [ ! -d ".git" ]; then + log_error "Git ์ €์žฅ์†Œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. Git ํด๋ก ์œผ๋กœ ์„ค์น˜ํ•ด์ฃผ์„ธ์š”." + exit 1 +fi + +# ํ˜„์žฌ ์ปค๋ฐ‹ ํ•ด์‹œ ์ €์žฅ (๋กค๋ฐฑ์šฉ) +CURRENT_COMMIT=$(git rev-parse HEAD) +CURRENT_BRANCH=$(git branch --show-current) +echo "์ด์ „ ์ปค๋ฐ‹: $CURRENT_COMMIT" >> "$UPDATE_LOG" + +log_info "ํ˜„์žฌ ๋ธŒ๋žœ์น˜: $CURRENT_BRANCH" +log_info "ํ˜„์žฌ ์ปค๋ฐ‹: ${CURRENT_COMMIT:0:8}" + +# ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ ํ™•์ธ +if docker-compose -f "$COMPOSE_FILE" ps -q | grep -q .; then + CONTAINERS_RUNNING=true + log_info "์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค" +else + CONTAINERS_RUNNING=false + log_warning "์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰ ์ค‘์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค" +fi + +# ๋กค๋ฐฑ ๋ชจ๋“œ +if [ "$UPDATE_MODE" = "rollback" ]; then + log_warning "๐Ÿ”™ ๋กค๋ฐฑ ๋ชจ๋“œ ์‹คํ–‰" + + # ๋งˆ์ง€๋ง‰ ์„ฑ๊ณตํ•œ ์ปค๋ฐ‹์œผ๋กœ ๋กค๋ฐฑ + LAST_SUCCESS=$(tail -n 20 "$UPDATE_LOG" | grep "์—…๋ฐ์ดํŠธ ์„ฑ๊ณต" | tail -n 1 | awk '{print $6}') + + if [ -z "$LAST_SUCCESS" ]; then + log_error "๋กค๋ฐฑํ•  ์ปค๋ฐ‹์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค" + exit 1 + fi + + log_info "๋กค๋ฐฑ ๋Œ€์ƒ ์ปค๋ฐ‹: $LAST_SUCCESS" + + # ๋กค๋ฐฑ ์‹คํ–‰ + git reset --hard "$LAST_SUCCESS" + + # ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘ + if [ "$CONTAINERS_RUNNING" = true ]; then + log_info "์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘ ์ค‘..." + docker-compose -f "$COMPOSE_FILE" down + docker-compose -f "$COMPOSE_FILE" up -d --build + fi + + log_success "๋กค๋ฐฑ ์™„๋ฃŒ: $LAST_SUCCESS" + echo "$(date '+%Y-%m-%d %H:%M:%S') - ๋กค๋ฐฑ ์™„๋ฃŒ: $LAST_SUCCESS" >> "$UPDATE_LOG" + exit 0 +fi + +# ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ +log_info "๐Ÿ” ์—…๋ฐ์ดํŠธ ํ™•์ธ ์ค‘..." + +# ์›๊ฒฉ ์ €์žฅ์†Œ์—์„œ ์ตœ์‹  ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ +git fetch origin + +# ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅํ•œ ์ปค๋ฐ‹ ์ˆ˜ ํ™•์ธ +COMMITS_BEHIND=$(git rev-list --count HEAD..origin/$CURRENT_BRANCH) + +if [ "$COMMITS_BEHIND" -eq 0 ]; then + log_success "์ด๋ฏธ ์ตœ์‹  ๋ฒ„์ „์ž…๋‹ˆ๋‹ค" + exit 0 +fi + +log_info "์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅํ•œ ์ปค๋ฐ‹: $COMMITS_BEHIND๊ฐœ" + +# ๋ณ€๊ฒฝ์‚ฌํ•ญ ๋ฏธ๋ฆฌ๋ณด๊ธฐ +log_info "๐Ÿ“ ๋ณ€๊ฒฝ์‚ฌํ•ญ ๋ฏธ๋ฆฌ๋ณด๊ธฐ:" +git log --oneline HEAD..origin/$CURRENT_BRANCH | head -10 + +# Safe ๋ชจ๋“œ์—์„œ ์‚ฌ์šฉ์ž ํ™•์ธ +if [ "$UPDATE_MODE" = "safe" ]; then + echo "" + read -p "์—…๋ฐ์ดํŠธ๋ฅผ ์ง„ํ–‰ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? (y/N): " -n 1 -r + echo "" + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + log_info "์—…๋ฐ์ดํŠธ๊ฐ€ ์ทจ์†Œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค" + exit 0 + fi +fi + +# ๋ฐฑ์—… ์ƒ์„ฑ +log_info "๐Ÿ’พ ๋ฐฑ์—… ์ƒ์„ฑ ์ค‘..." + +BACKUP_TIMESTAMP=$(date +%Y%m%d_%H%M%S) +BACKUP_NAME="pre_update_${BACKUP_TIMESTAMP}" + +# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐฑ์—… +if [ "$CONTAINERS_RUNNING" = true ]; then + docker-compose -f "$COMPOSE_FILE" exec -T database pg_dump -U docuser document_db > "$BACKUP_DIR/db_${BACKUP_NAME}.sql" + log_success "๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐฑ์—… ์™„๋ฃŒ" +fi + +# ์„ค์ • ํŒŒ์ผ ๋ฐฑ์—… +tar -czf "$BACKUP_DIR/config_${BACKUP_NAME}.tar.gz" \ + /volume1/docker/document-server/config/ \ + .env.synology 2>/dev/null || true + +log_success "์„ค์ • ํŒŒ์ผ ๋ฐฑ์—… ์™„๋ฃŒ" + +# Git ์—…๋ฐ์ดํŠธ ์‹คํ–‰ +log_info "๐Ÿ“ฅ ์ฝ”๋“œ ์—…๋ฐ์ดํŠธ ์ค‘..." + +# ๋กœ์ปฌ ๋ณ€๊ฒฝ์‚ฌํ•ญ ์ž„์‹œ ์ €์žฅ (์žˆ๋Š” ๊ฒฝ์šฐ) +if ! git diff --quiet; then + log_warning "๋กœ์ปฌ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ž„์‹œ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค" + git stash push -m "Auto-stash before update $BACKUP_TIMESTAMP" +fi + +# ์—…๋ฐ์ดํŠธ ์‹คํ–‰ +git pull origin "$CURRENT_BRANCH" + +NEW_COMMIT=$(git rev-parse HEAD) +log_success "์ฝ”๋“œ ์—…๋ฐ์ดํŠธ ์™„๋ฃŒ: ${NEW_COMMIT:0:8}" + +# Docker ์ด๋ฏธ์ง€ ์—…๋ฐ์ดํŠธ ํ™•์ธ +log_info "๐Ÿณ Docker ์ด๋ฏธ์ง€ ์—…๋ฐ์ดํŠธ ํ™•์ธ ์ค‘..." + +# Dockerfile์ด๋‚˜ requirements.txt ๋ณ€๊ฒฝ ํ™•์ธ +NEED_REBUILD=false + +if git diff --name-only "$CURRENT_COMMIT" "$NEW_COMMIT" | grep -E "(Dockerfile|requirements.txt|pyproject.toml|package.json)" > /dev/null; then + NEED_REBUILD=true + log_info "์˜์กด์„ฑ ๋ณ€๊ฒฝ ๊ฐ์ง€ - ์ด๋ฏธ์ง€ ์žฌ๋นŒ๋“œ ํ•„์š”" +fi + +# ์ปจํ…Œ์ด๋„ˆ ์—…๋ฐ์ดํŠธ +if [ "$CONTAINERS_RUNNING" = true ]; then + log_info "๐Ÿ”„ ์„œ๋น„์Šค ์—…๋ฐ์ดํŠธ ์ค‘..." + + if [ "$NEED_REBUILD" = true ]; then + log_info "์ด๋ฏธ์ง€ ์žฌ๋นŒ๋“œ ์ค‘..." + + # ๋ฌด์ค‘๋‹จ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ๋‹จ๊ณ„๋ณ„ ์žฌ์‹œ์ž‘ + docker-compose -f "$COMPOSE_FILE" build --no-cache backend + docker-compose -f "$COMPOSE_FILE" up -d --no-deps backend + + # ํ—ฌ์Šค์ฒดํฌ ๋Œ€๊ธฐ + log_info "๋ฐฑ์—”๋“œ ํ—ฌ์Šค์ฒดํฌ ๋Œ€๊ธฐ ์ค‘..." + sleep 30 + + # Nginx ์—…๋ฐ์ดํŠธ (ํ•„์š”์‹œ) + if git diff --name-only "$CURRENT_COMMIT" "$NEW_COMMIT" | grep -E "(nginx|frontend)" > /dev/null; then + docker-compose -f "$COMPOSE_FILE" build --no-cache nginx + docker-compose -f "$COMPOSE_FILE" up -d --no-deps nginx + fi + else + log_info "์„ค์ • ํŒŒ์ผ๋งŒ ์—…๋ฐ์ดํŠธ - ์žฌ์‹œ์ž‘ ์ค‘..." + docker-compose -f "$COMPOSE_FILE" restart backend nginx + fi + + # ์„œ๋น„์Šค ์ƒํƒœ ํ™•์ธ + sleep 10 + + # ํ—ฌ์Šค์ฒดํฌ + HEALTH_CHECK_FAILED=false + + # ๋ฐฑ์—”๋“œ ํ—ฌ์Šค์ฒดํฌ + if ! curl -f http://localhost:24102/health > /dev/null 2>&1; then + log_error "๋ฐฑ์—”๋“œ ํ—ฌ์Šค์ฒดํฌ ์‹คํŒจ" + HEALTH_CHECK_FAILED=true + fi + + # ํ”„๋ก ํŠธ์—”๋“œ ํ—ฌ์Šค์ฒดํฌ + if ! curl -f http://localhost:24100/ > /dev/null 2>&1; then + log_error "ํ”„๋ก ํŠธ์—”๋“œ ํ—ฌ์Šค์ฒดํฌ ์‹คํŒจ" + HEALTH_CHECK_FAILED=true + fi + + # ํ—ฌ์Šค์ฒดํฌ ์‹คํŒจ ์‹œ ๋กค๋ฐฑ + if [ "$HEALTH_CHECK_FAILED" = true ]; then + log_error "ํ—ฌ์Šค์ฒดํฌ ์‹คํŒจ - ์ž๋™ ๋กค๋ฐฑ ์‹คํ–‰" + + # ์ด์ „ ์ปค๋ฐ‹์œผ๋กœ ๋กค๋ฐฑ + git reset --hard "$CURRENT_COMMIT" + + # ์ปจํ…Œ์ด๋„ˆ ๋กค๋ฐฑ + docker-compose -f "$COMPOSE_FILE" down + docker-compose -f "$COMPOSE_FILE" up -d --build + + log_error "์—…๋ฐ์ดํŠธ ์‹คํŒจ - ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋กค๋ฐฑ๋จ" + echo "$(date '+%Y-%m-%d %H:%M:%S') - ์—…๋ฐ์ดํŠธ ์‹คํŒจ (๋กค๋ฐฑ): $NEW_COMMIT -> $CURRENT_COMMIT" >> "$UPDATE_LOG" + exit 1 + fi + + log_success "์„œ๋น„์Šค ์—…๋ฐ์ดํŠธ ์™„๋ฃŒ" +else + log_info "์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰ ์ค‘์ด์ง€ ์•Š์•„ ์„œ๋น„์Šค ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค" +fi + +# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ™•์ธ +log_info "๐Ÿ—„๏ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ™•์ธ ์ค‘..." + +if git diff --name-only "$CURRENT_COMMIT" "$NEW_COMMIT" | grep -E "(migrations|models)" > /dev/null; then + log_warning "๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ ๊ฐ์ง€" + + if [ "$CONTAINERS_RUNNING" = true ]; then + log_info "๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹คํ–‰ ์ค‘..." + docker-compose -f "$COMPOSE_FILE" exec -T backend python -m alembic upgrade head || true + log_success "๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์™„๋ฃŒ" + else + log_warning "์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰ ์ค‘์ด์ง€ ์•Š์•„ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค" + fi +fi + +# ์—…๋ฐ์ดํŠธ ์™„๋ฃŒ +log_success "๐ŸŽ‰ ์—…๋ฐ์ดํŠธ ์™„๋ฃŒ!" + +echo "" +echo "=== ์—…๋ฐ์ดํŠธ ์ •๋ณด ===" +echo "์ด์ „ ์ปค๋ฐ‹: ${CURRENT_COMMIT:0:8}" +echo "์ƒˆ ์ปค๋ฐ‹: ${NEW_COMMIT:0:8}" +echo "์—…๋ฐ์ดํŠธ๋œ ์ปค๋ฐ‹ ์ˆ˜: $COMMITS_BEHIND" +echo "๋ฐฑ์—… ์œ„์น˜: $BACKUP_DIR/*_${BACKUP_NAME}.*" +echo "" + +# ๋ณ€๊ฒฝ์‚ฌํ•ญ ์š”์•ฝ +echo "=== ์ฃผ์š” ๋ณ€๊ฒฝ์‚ฌํ•ญ ===" +git log --oneline "$CURRENT_COMMIT".."$NEW_COMMIT" | head -5 + +echo "" +echo "=== ์„œ๋น„์Šค ์ƒํƒœ ===" +if [ "$CONTAINERS_RUNNING" = true ]; then + docker-compose -f "$COMPOSE_FILE" ps + echo "" + echo "๐ŸŒ ์›น ์ธํ„ฐํŽ˜์ด์Šค: http://localhost:24100" + echo "๐Ÿ”ง API ๋ฌธ์„œ: http://localhost:24102/docs" +fi + +# ์„ฑ๊ณต ๋กœ๊ทธ ๊ธฐ๋ก +echo "$(date '+%Y-%m-%d %H:%M:%S') - ์—…๋ฐ์ดํŠธ ์„ฑ๊ณต: $CURRENT_COMMIT -> $NEW_COMMIT" >> "$UPDATE_LOG" + +# ์ •๋ฆฌ ์ž‘์—… +log_info "๐Ÿงน ์ •๋ฆฌ ์ž‘์—… ์ค‘..." + +# ์˜ค๋ž˜๋œ ๋ฐฑ์—… ํŒŒ์ผ ์ •๋ฆฌ (30์ผ ์ด์ƒ) +find "$BACKUP_DIR" -name "pre_update_*" -mtime +30 -delete 2>/dev/null || true + +# Docker ์ด๋ฏธ์ง€ ์ •๋ฆฌ +docker system prune -f > /dev/null 2>&1 || true + +log_success "์—…๋ฐ์ดํŠธ ํ”„๋กœ์„ธ์Šค ์™„๋ฃŒ" + +# ๋ชจ๋‹ˆํ„ฐ๋ง ์‹คํ–‰ ์ œ์•ˆ +echo "" +echo "๐Ÿ’ก ์—…๋ฐ์ดํŠธ ํ›„ ์‹œ์Šคํ…œ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด:" +echo " ./scripts/monitor-synology.sh" +echo "" +echo "๐Ÿ”™ ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋ฉด ๋กค๋ฐฑํ•˜๋ ค๋ฉด:" +echo " ./scripts/update-synology.sh rollback"