From 016682269a380c0ed85aeaad9340d0f3779e70d1 Mon Sep 17 00:00:00 2001 From: hyungi Date: Sun, 14 Sep 2025 12:58:55 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9=20Consolidate=20documentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - โœ… Created unified DEVELOPMENT_DEPLOYMENT_GUIDE.md - ๐Ÿ—‘๏ธ Removed individual setup guides: - TECH_STACK.md - HOMEBREW_SETUP.md - SYNOLOGY_SETUP.md - DS1525_OPTIMIZED_SETUP.md - DEV_DEPLOY_PIPELINE.md - DOCKER_DEV_GUIDE.md All content consolidated into single development-deployment guide focused on Mac โ†’ DS1525+ (32GB RAM) workflow --- DEVELOPMENT_DEPLOYMENT_GUIDE.md | 864 ++++++++++++++++++++++++++++++++ DS1525_OPTIMIZED_SETUP.md | 607 ---------------------- HOMEBREW_SETUP.md | 592 ---------------------- SYNOLOGY_SETUP.md | 721 -------------------------- TECH_STACK.md | 285 ----------- 5 files changed, 864 insertions(+), 2205 deletions(-) create mode 100644 DEVELOPMENT_DEPLOYMENT_GUIDE.md delete mode 100644 DS1525_OPTIMIZED_SETUP.md delete mode 100644 HOMEBREW_SETUP.md delete mode 100644 SYNOLOGY_SETUP.md delete mode 100644 TECH_STACK.md diff --git a/DEVELOPMENT_DEPLOYMENT_GUIDE.md b/DEVELOPMENT_DEPLOYMENT_GUIDE.md new file mode 100644 index 0000000..7349b06 --- /dev/null +++ b/DEVELOPMENT_DEPLOYMENT_GUIDE.md @@ -0,0 +1,864 @@ +# ๐Ÿš€ ๊ฐœ๋ฐœ-๋ฐฐํฌ ํ†ตํ•ฉ ๊ฐ€์ด๋“œ (Mac โ†’ DS1525+ 32GB) + +## ๐Ÿ“‹ ๊ฐœ์š” + +Mac์—์„œ ๊ฐœ๋ฐœํ•˜๊ณ  Synology DS1525+ (32GB RAM, 480GB SSD)์— ๋ฐฐํฌํ•˜๋Š” ์™„์ „ํ•œ ๊ฐœ๋ฐœ-๋ฐฐํฌ ํŒŒ์ดํ”„๋ผ์ธ ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค. + +--- + +## ๐Ÿ”ง ํ•˜๋“œ์›จ์–ด ์‚ฌ์–‘ + +### ๊ฐœ๋ฐœ ํ™˜๊ฒฝ: Mac +- **MacBook Pro/Mac Mini** (M1/M2 ๋˜๋Š” Intel) +- **๋ฉ”๋ชจ๋ฆฌ**: 16GB ์ด์ƒ ๊ถŒ์žฅ +- **์ €์žฅ๊ณต๊ฐ„**: 100GB ์ด์ƒ ์—ฌ์œ  ๊ณต๊ฐ„ + +### ๋ฐฐํฌ ํ™˜๊ฒฝ: Synology DS1525+ +- **CPU**: AMD Ryzen R1600 (4์ฝ”์–ด 2.6GHz) +- **๋ฉ”๋ชจ๋ฆฌ**: 32GB RAM (๋Œ€์šฉ๋Ÿ‰!) +- **์ €์žฅ์žฅ์น˜**: ์‹œ๋†€๋กœ์ง€ ์ •ํ’ˆ 2.5" SSD 480GB +- **๋„คํŠธ์›Œํฌ**: ๊ธฐ๊ฐ€๋น„ํŠธ ์ด๋”๋„ท x4 +- **OS**: DSM 7.0+ + +--- + +## ๐Ÿณ Docker ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœ-๋ฐฐํฌ ์ „๋žต + +### ์•„ํ‚คํ…์ฒ˜ ํ˜ธํ™˜์„ฑ ํ•ด๊ฒฐ +``` +Mac (๊ฐœ๋ฐœ) DS1525+ (๋ฐฐํฌ) +โ”œโ”€โ”€ M1/M2: arm64 โ†’ โ”œโ”€โ”€ AMD Ryzen: amd64 +โ”œโ”€โ”€ Intel: amd64 โ†’ โ””โ”€โ”€ Linux ์ปจํ…Œ์ด๋„ˆ +โ””โ”€โ”€ Docker Desktop โ””โ”€โ”€ Container Manager +``` + +**ํ•ต์‹ฌ ํ•ด๊ฒฐ์ฑ…: ๋ฉ€ํ‹ฐ ์•„ํ‚คํ…์ฒ˜ ๋นŒ๋“œ** +- Mac์—์„œ ๊ฐœ๋ฐœ: `arm64` ๋˜๋Š” `amd64` +- DS1525+์—์„œ ์‹คํ–‰: `amd64` ๋ณด์žฅ +- ํฌ๋กœ์Šค ํ”Œ๋žซํผ ๋นŒ๋“œ๋กœ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ ์™„์ „ ํ•ด๊ฒฐ + +--- + +## ๐Ÿ› ๏ธ 1๋‹จ๊ณ„: Mac ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ • + +### Docker Desktop ์„ค์น˜ ๋ฐ ์ตœ์ ํ™” +```bash +# Homebrew๋กœ Docker Desktop ์„ค์น˜ +brew install --cask docker + +# Docker Desktop ๋ฆฌ์†Œ์Šค ์„ค์ • (GUI) +# Memory: 8GB (16GB Mac ๊ธฐ์ค€) +# CPUs: 4 cores +# Swap: 2GB +# Disk: 100GB +``` + +### Docker Buildx ์„ค์ • (๋ฉ€ํ‹ฐ ์•„ํ‚คํ…์ฒ˜ ๋นŒ๋“œ์šฉ) +```bash +# ๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ ๋นŒ๋” ์ƒ์„ฑ +docker buildx create --name multiarch --driver docker-container --use +docker buildx inspect --bootstrap + +# ์ง€์› ํ”Œ๋žซํผ ํ™•์ธ +docker buildx ls +``` + +### ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ์„ค์ • +``` +project/ +โ”œโ”€โ”€ docker/ +โ”‚ โ”œโ”€โ”€ Dockerfile.dev # Mac ๊ฐœ๋ฐœ์šฉ +โ”‚ โ”œโ”€โ”€ Dockerfile.prod # DS1525+ ๋ฐฐํฌ์šฉ +โ”‚ โ”œโ”€โ”€ docker-compose.dev.yml # ๋กœ์ปฌ ๊ฐœ๋ฐœ +โ”‚ โ””โ”€โ”€ docker-compose.prod.yml# DS1525+ ๋ฐฐํฌ +โ”œโ”€โ”€ scripts/ +โ”‚ โ”œโ”€โ”€ dev-start.sh # ๊ฐœ๋ฐœ ์‹œ์ž‘ +โ”‚ โ”œโ”€โ”€ build-deploy.sh # ๋นŒ๋“œ & ๋ฐฐํฌ +โ”‚ โ””โ”€โ”€ rollback.sh # ๋กค๋ฐฑ +โ”œโ”€โ”€ src/ +โ”‚ โ”œโ”€โ”€ backend/ +โ”‚ โ””โ”€โ”€ frontend/ +โ”œโ”€โ”€ config/ +โ”‚ โ”œโ”€โ”€ nginx/ +โ”‚ โ”œโ”€โ”€ postgres/ +โ”‚ โ””โ”€โ”€ monitoring/ +โ””โ”€โ”€ environments/ + โ”œโ”€โ”€ .env.development + โ””โ”€โ”€ .env.production +``` + +--- + +## ๐Ÿ—๏ธ 2๋‹จ๊ณ„: ๊ฐœ๋ฐœ์šฉ Docker ์„ค์ • + +### ๊ฐœ๋ฐœ์šฉ Dockerfile +```dockerfile +# docker/Dockerfile.dev +FROM --platform=linux/amd64 python:3.11-slim + +# ๊ฐœ๋ฐœ ๋„๊ตฌ ์„ค์น˜ +RUN apt-get update && apt-get install -y \ + gcc g++ curl vim git \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +# Python ๊ฐœ๋ฐœ ์˜์กด์„ฑ +COPY requirements.dev.txt . +RUN pip install --no-cache-dir -r requirements.dev.txt + +# ํ™˜๊ฒฝ ์„ค์ • +ENV PYTHONPATH=/app +ENV PYTHONUNBUFFERED=1 +ENV RELOAD=true + +EXPOSE 8000 5678 + +# Hot Reload ๊ฐœ๋ฐœ ์„œ๋ฒ„ +CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] +``` + +### ๊ฐœ๋ฐœ์šฉ Docker Compose +```yaml +# docker/docker-compose.dev.yml +version: '3.8' + +services: + app: + build: + context: .. + dockerfile: docker/Dockerfile.dev + platform: linux/amd64 # DS1525+ ํ˜ธํ™˜์„ฑ ๋ณด์žฅ + container_name: app-dev + environment: + - DEBUG=true + - DATABASE_URL=postgresql://dev_user:dev_pass@postgres:5432/app_dev + - REDIS_URL=redis://redis:6379/0 + volumes: + - ../src:/app/src:cached # Mac ์„ฑ๋Šฅ ์ตœ์ ํ™” + - ../config:/app/config:cached + ports: + - "8000:8000" + - "5678:5678" # ๋””๋ฒ„๊น… ํฌํŠธ + depends_on: + - postgres + - redis + networks: + - dev-network + + postgres: + image: postgres:15-alpine + platform: linux/amd64 + container_name: postgres-dev + environment: + POSTGRES_DB: app_dev + POSTGRES_USER: dev_user + POSTGRES_PASSWORD: dev_pass + volumes: + - postgres_data:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - dev-network + + redis: + image: redis:7-alpine + platform: linux/amd64 + container_name: redis-dev + volumes: + - redis_data:/data + ports: + - "6379:6379" + networks: + - dev-network + +networks: + dev-network: + driver: bridge + +volumes: + postgres_data: + redis_data: +``` + +### ๊ฐœ๋ฐœ ์‹œ์ž‘ ์Šคํฌ๋ฆฝํŠธ +```bash +#!/bin/bash +# scripts/dev-start.sh + +echo "๐Ÿš€ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์‹œ์ž‘" + +# ๊ฐœ๋ฐœ ์ปจํ…Œ์ด๋„ˆ ์‹œ์ž‘ +docker-compose -f docker/docker-compose.dev.yml up -d + +# ์„œ๋น„์Šค ์ค€๋น„ ๋Œ€๊ธฐ +echo "โณ ์„œ๋น„์Šค ์‹œ์ž‘ ๋Œ€๊ธฐ..." +sleep 15 + +# ํ—ฌ์Šค์ฒดํฌ +if curl -f http://localhost:8000/health > /dev/null 2>&1; then + echo "โœ… ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์ค€๋น„ ์™„๋ฃŒ!" + echo "๐ŸŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜: http://localhost:8000" + echo "๐Ÿ—„๏ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค: localhost:5432" + echo "๐Ÿ”ด Redis: localhost:6379" +else + echo "โŒ ์„œ๋น„์Šค ์‹œ์ž‘ ์‹คํŒจ" + docker-compose -f docker/docker-compose.dev.yml logs +fi +``` + +--- + +## ๐Ÿญ 3๋‹จ๊ณ„: DS1525+ ๋ฐฐํฌ ํ™˜๊ฒฝ ์„ค์ • + +### DS1525+ 32GB ์ตœ์ ํ™” ๊ตฌ์„ฑ +``` +์ด ๋ฉ”๋ชจ๋ฆฌ: 32GB ํ• ๋‹น ๊ณ„ํš +โ”œโ”€โ”€ DSM ์‹œ์Šคํ…œ: 2GB +โ”œโ”€โ”€ PostgreSQL: 4GB (๊ณ ์„ฑ๋Šฅ DB) +โ”œโ”€โ”€ Elasticsearch: 8GB (๋Œ€์šฉ๋Ÿ‰ ๊ฒ€์ƒ‰) +โ”œโ”€โ”€ Redis: 2GB (๋Œ€์šฉ๋Ÿ‰ ์บ์‹œ) +โ”œโ”€โ”€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜: 4GB (๋ฉ€ํ‹ฐ ์›Œ์ปค) +โ”œโ”€โ”€ ๋ชจ๋‹ˆํ„ฐ๋ง: 2GB (Prometheus + Grafana) +โ”œโ”€โ”€ ์‹œ์Šคํ…œ ์บ์‹œ: 8GB +โ””โ”€โ”€ ์—ฌ์œ  ๊ณต๊ฐ„: 2GB +``` + +### ๋ฐฐํฌ์šฉ Dockerfile (์ตœ์ ํ™”) +```dockerfile +# docker/Dockerfile.prod +FROM --platform=$BUILDPLATFORM python:3.11-slim AS builder + +ARG TARGETPLATFORM +ARG BUILDPLATFORM + +WORKDIR /app + +# ์‹œ์Šคํ…œ ํŒจํ‚ค์ง€ ์„ค์น˜ +RUN apt-get update && apt-get install -y \ + gcc g++ curl \ + && rm -rf /var/lib/apt/lists/* + +# Python ์˜์กด์„ฑ ์„ค์น˜ +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# ํ”„๋กœ๋•์…˜ ์ด๋ฏธ์ง€ +FROM python:3.11-slim AS production + +WORKDIR /app + +# ๋นŒ๋“œ๋œ ํŒจํ‚ค์ง€ ๋ณต์‚ฌ +COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages +COPY --from=builder /usr/local/bin /usr/local/bin + +# ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ ๋ณต์‚ฌ +COPY src/ ./src/ +COPY config/ ./config/ + +# ํ—ฌ์Šค์ฒดํฌ ์ถ”๊ฐ€ +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8000/health || exit 1 + +EXPOSE 8000 + +CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"] +``` + +### DS1525+ ๋ฐฐํฌ์šฉ Docker Compose +```yaml +# docker/docker-compose.prod.yml +version: '3.8' + +services: + app: + build: + context: .. + dockerfile: docker/Dockerfile.prod + platforms: + - linux/amd64 + container_name: app-prod + environment: + - DATABASE_URL=postgresql://app_user:${DB_PASSWORD}@postgres:5432/app_prod + - REDIS_URL=redis://redis:6379/0 + - WORKERS=4 + volumes: + - /volume1/docker/app/logs:/app/logs + ports: + - "8000:8000" + networks: + - prod-network + depends_on: + - postgres + - redis + restart: unless-stopped + deploy: + resources: + limits: + memory: 4G + cpus: '2.0' + + postgres: + image: postgres:15-alpine + platform: linux/amd64 + container_name: postgres-prod + environment: + POSTGRES_DB: app_prod + POSTGRES_USER: app_user + POSTGRES_PASSWORD: ${DB_PASSWORD} + volumes: + - /volume1/docker/app/data/postgres:/var/lib/postgresql/data + - ../config/postgresql.conf:/etc/postgresql/postgresql.conf + ports: + - "5432:5432" + networks: + - prod-network + restart: unless-stopped + deploy: + resources: + limits: + memory: 4G + cpus: '2.0' + command: postgres -c config_file=/etc/postgresql/postgresql.conf + + redis: + image: redis:7-alpine + platform: linux/amd64 + container_name: redis-prod + command: redis-server --maxmemory 2gb --maxmemory-policy allkeys-lru + volumes: + - /volume1/docker/app/data/redis:/data + ports: + - "6379:6379" + networks: + - prod-network + restart: unless-stopped + deploy: + resources: + limits: + memory: 2G + cpus: '1.0' + + elasticsearch: + image: elasticsearch:8.11.0 + platform: linux/amd64 + container_name: elasticsearch-prod + environment: + - discovery.type=single-node + - "ES_JAVA_OPTS=-Xms4g -Xmx8g" + - xpack.security.enabled=false + volumes: + - /volume1/docker/app/data/elasticsearch:/usr/share/elasticsearch/data + ports: + - "9200:9200" + networks: + - prod-network + restart: unless-stopped + deploy: + resources: + limits: + memory: 10G + cpus: '2.0' + + nginx: + image: nginx:alpine + platform: linux/amd64 + container_name: nginx-prod + volumes: + - ../config/nginx/nginx.conf:/etc/nginx/nginx.conf + - /volume1/docker/app/logs:/var/log/nginx + ports: + - "80:80" + - "443:443" + networks: + - prod-network + depends_on: + - app + restart: unless-stopped + + # ๋ชจ๋‹ˆํ„ฐ๋ง + prometheus: + image: prom/prometheus:latest + platform: linux/amd64 + container_name: prometheus + volumes: + - ../config/prometheus.yml:/etc/prometheus/prometheus.yml + - /volume1/docker/app/data/prometheus:/prometheus + ports: + - "9090:9090" + networks: + - prod-network + restart: unless-stopped + deploy: + resources: + limits: + memory: 1G + + grafana: + image: grafana/grafana:latest + platform: linux/amd64 + container_name: grafana + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin123 + volumes: + - /volume1/docker/app/data/grafana:/var/lib/grafana + ports: + - "3000:3000" + networks: + - prod-network + restart: unless-stopped + deploy: + resources: + limits: + memory: 1G + +networks: + prod-network: + driver: bridge + +volumes: + postgres_data: + redis_data: + elasticsearch_data: +``` + +--- + +## ๐Ÿš€ 4๋‹จ๊ณ„: ์ž๋™ํ™” ๋นŒ๋“œ & ๋ฐฐํฌ + +### ํ†ตํ•ฉ ๋นŒ๋“œ-๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ +```bash +#!/bin/bash +# scripts/build-deploy.sh + +set -e + +# ์„ค์ • +PROJECT_NAME="app" +NAS_HOST="192.168.1.100" +NAS_USER="admin" +VERSION=$(git describe --tags --always --dirty) + +echo "๐Ÿš€ ๋นŒ๋“œ & ๋ฐฐํฌ ์‹œ์ž‘: $PROJECT_NAME v$VERSION" + +# 1. ๋กœ์ปฌ ํ…Œ์ŠคํŠธ +echo "๐Ÿงช ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ์‹คํ–‰..." +docker-compose -f docker/docker-compose.dev.yml up -d +sleep 30 + +if curl -f http://localhost:8000/health > /dev/null 2>&1; then + echo "โœ… ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ" + docker-compose -f docker/docker-compose.dev.yml down +else + echo "โŒ ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ์‹คํŒจ" + docker-compose -f docker/docker-compose.dev.yml logs + exit 1 +fi + +# 2. ๋ฉ€ํ‹ฐ ์•„ํ‚คํ…์ฒ˜ ๋นŒ๋“œ (DS1525+ ํ˜ธํ™˜) +echo "๐Ÿ”จ DS1525+ ํ˜ธํ™˜ ์ด๋ฏธ์ง€ ๋นŒ๋“œ..." +docker buildx build \ + --platform linux/amd64 \ + --tag $PROJECT_NAME:$VERSION \ + --tag $PROJECT_NAME:latest \ + --file docker/Dockerfile.prod \ + --load \ + . + +# 3. DS1525+๋กœ ์ด๋ฏธ์ง€ ์ „์†ก +echo "๐Ÿ“ค DS1525+๋กœ ์ด๋ฏธ์ง€ ์ „์†ก..." +docker save $PROJECT_NAME:latest | ssh $NAS_USER@$NAS_HOST "docker load" + +# 4. ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋™๊ธฐํ™” +echo "โš™๏ธ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋™๊ธฐํ™”..." +scp environments/.env.production $NAS_USER@$NAS_HOST:/volume1/docker/$PROJECT_NAME/.env + +# 5. DS1525+์—์„œ ๋ฐฐํฌ ์‹คํ–‰ +echo "๐Ÿšข DS1525+ ๋ฐฐํฌ ์‹คํ–‰..." +ssh $NAS_USER@$NAS_HOST << EOF + cd /volume1/docker/$PROJECT_NAME + + # ๊ธฐ์กด ์ปจํ…Œ์ด๋„ˆ ๋ฐฑ์—… (๋กค๋ฐฑ์šฉ) + if docker-compose -f docker-compose.prod.yml ps | grep -q "Up"; then + echo "๐Ÿ“ฆ ๋กค๋ฐฑ์šฉ ๋ฐฑ์—… ์ƒ์„ฑ..." + docker-compose -f docker-compose.prod.yml config > docker-compose.backup.yml + docker images --format "{{.Repository}}:{{.Tag}}" | grep $PROJECT_NAME | head -1 > last_image.txt + fi + + # ์ƒˆ ๋ฒ„์ „ ๋ฐฐํฌ + docker-compose -f docker-compose.prod.yml down + docker-compose -f docker-compose.prod.yml up -d + + # ์ด๋ฏธ์ง€ ์ •๋ฆฌ + docker image prune -f +EOF + +# 6. ๋ฐฐํฌ ํ›„ ํ—ฌ์Šค์ฒดํฌ +echo "๐Ÿฅ ๋ฐฐํฌ ํ›„ ํ—ฌ์Šค์ฒดํฌ..." +sleep 60 + +for i in {1..10}; do + if curl -f http://$NAS_HOST:8000/health > /dev/null 2>&1; then + echo "โœ… ๋ฐฐํฌ ์„ฑ๊ณต ๋ฐ ํ—ฌ์Šค์ฒดํฌ ํ†ต๊ณผ" + break + fi + + if [ $i -eq 10 ]; then + echo "โŒ ํ—ฌ์Šค์ฒดํฌ ์‹คํŒจ - ๋กค๋ฐฑ ํ•„์š”" + exit 1 + fi + + echo "โณ ํ—ฌ์Šค์ฒดํฌ ์žฌ์‹œ๋„ ($i/10)..." + sleep 10 +done + +# 7. ๋ฐฐํฌ ์™„๋ฃŒ ์ •๋ณด +echo "" +echo "๐ŸŽ‰ ๋ฐฐํฌ ์™„๋ฃŒ!" +echo "๐Ÿ“Š ๋ฐฐํฌ ์ •๋ณด:" +echo " - ํ”„๋กœ์ ํŠธ: $PROJECT_NAME" +echo " - ๋ฒ„์ „: $VERSION" +echo " - ๋Œ€์ƒ: DS1525+ (32GB RAM, 480GB SSD)" +echo " - ๋ฐฐํฌ ์‹œ๊ฐ„: $(date)" +echo "" +echo "๐Ÿ”— ์ ‘์† ๋งํฌ:" +echo " - ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜: http://$NAS_HOST" +echo " - ๋ชจ๋‹ˆํ„ฐ๋ง: http://$NAS_HOST:3000 (admin/admin123)" +echo " - Prometheus: http://$NAS_HOST:9090" +``` + +### ๋กค๋ฐฑ ์Šคํฌ๋ฆฝํŠธ +```bash +#!/bin/bash +# scripts/rollback.sh + +set -e + +NAS_HOST="192.168.1.100" +NAS_USER="admin" +PROJECT_NAME="app" + +echo "๐Ÿ”„ ๋กค๋ฐฑ ์‹œ์ž‘..." + +ssh $NAS_USER@$NAS_HOST << EOF + cd /volume1/docker/$PROJECT_NAME + + # ๋ฐฑ์—… ํŒŒ์ผ ํ™•์ธ + if [[ ! -f "docker-compose.backup.yml" ]] || [[ ! -f "last_image.txt" ]]; then + echo "โŒ ๋ฐฑ์—… ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค" + exit 1 + fi + + # ํ˜„์žฌ ์ปจํ…Œ์ด๋„ˆ ์ค‘์ง€ + docker-compose -f docker-compose.prod.yml down + + # ์ด์ „ ์„ค์ •์œผ๋กœ ๋ณต์› + cp docker-compose.backup.yml docker-compose.prod.yml + + # ์ปจํ…Œ์ด๋„ˆ ์‹œ์ž‘ + docker-compose -f docker-compose.prod.yml up -d + + echo "โœ… ๋กค๋ฐฑ ์™„๋ฃŒ" +EOF + +# ํ—ฌ์Šค์ฒดํฌ +sleep 30 +if curl -f http://$NAS_HOST:8000/health > /dev/null 2>&1; then + echo "โœ… ๋กค๋ฐฑ ์„ฑ๊ณต ๋ฐ ํ—ฌ์Šค์ฒดํฌ ํ†ต๊ณผ" +else + echo "โŒ ๋กค๋ฐฑ ํ›„ ํ—ฌ์Šค์ฒดํฌ ์‹คํŒจ" + exit 1 +fi +``` + +--- + +## ๐Ÿ“Š 5๋‹จ๊ณ„: DS1525+ ์„ฑ๋Šฅ ์ตœ์ ํ™” + +### PostgreSQL ์ตœ์ ํ™” (32GB ํ™œ์šฉ) +```ini +# config/postgresql.conf +# DS1525+ 32GB RAM ์ตœ์ ํ™” + +# ๋ฉ”๋ชจ๋ฆฌ ์„ค์ • +shared_buffers = 2GB # 32GB์˜ 6.25% +effective_cache_size = 16GB # 32GB์˜ 50% +maintenance_work_mem = 512MB +work_mem = 64MB + +# AMD Ryzen 4์ฝ”์–ด ํ™œ์šฉ +max_worker_processes = 4 +max_parallel_workers = 4 +max_parallel_workers_per_gather = 2 + +# SSD ์ตœ์ ํ™” +random_page_cost = 1.1 +effective_io_concurrency = 200 + +# ์—ฐ๊ฒฐ ๋ฐ ์ฒดํฌํฌ์ธํŠธ +max_connections = 200 +checkpoint_completion_target = 0.9 +checkpoint_timeout = 15min +max_wal_size = 4GB +``` + +### Nginx ์„ค์ • (๊ณ ์„ฑ๋Šฅ) +```nginx +# config/nginx/nginx.conf +worker_processes 4; # AMD Ryzen 4์ฝ”์–ด + +events { + worker_connections 2048; + use epoll; + multi_accept on; +} + +http { + upstream app { + server app:8000; + keepalive 32; + } + + server { + listen 80; + server_name _; + + client_max_body_size 100M; + + # ์ •์  ํŒŒ์ผ ์บ์‹ฑ + location /static/ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # API ํ”„๋ก์‹œ + location / { + proxy_pass http://app; + 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_http_version 1.1; + proxy_set_header Connection ""; + } + } +} +``` + +--- + +## ๐Ÿ”ง 6๋‹จ๊ณ„: ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์šฐ + +### ์ผ์ผ ๊ฐœ๋ฐœ ๋ฃจํ‹ด +```bash +# ๊ฐœ๋ฐœ ์‹œ์ž‘ +./scripts/dev-start.sh + +# ์ฝ”๋“œ ๋ณ€๊ฒฝ ํ›„ ํ…Œ์ŠคํŠธ +docker-compose -f docker/docker-compose.dev.yml logs -f app + +# ๊ฐœ๋ฐœ ์™„๋ฃŒ ํ›„ ๋ฐฐํฌ +git add . +git commit -m "feat: ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€" +git push origin main + +# ๋ฐฐํฌ ์‹คํ–‰ +./scripts/build-deploy.sh + +# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์ •๋ฆฌ +docker-compose -f docker/docker-compose.dev.yml down +``` + +### ๋ธŒ๋žœ์น˜๋ณ„ ๋ฐฐํฌ ์ „๋žต +```bash +# develop ๋ธŒ๋žœ์น˜ โ†’ ์Šคํ…Œ์ด์ง• ์ž๋™ ๋ฐฐํฌ +git checkout develop +git merge feature/new-feature +git push origin develop + +# main ๋ธŒ๋žœ์น˜ โ†’ ํ”„๋กœ๋•์…˜ ๋ฐฐํฌ +git checkout main +git merge develop +git tag v1.2.0 +git push origin main --tags +./scripts/build-deploy.sh +``` + +--- + +## ๐Ÿ“ˆ 7๋‹จ๊ณ„: ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ์œ ์ง€๋ณด์ˆ˜ + +### ๋ฆฌ์†Œ์Šค ๋ชจ๋‹ˆํ„ฐ๋ง +```bash +# DS1525+ ๋ฆฌ์†Œ์Šค ํ™•์ธ +ssh admin@nas.local << 'EOF' + echo "๐Ÿ’พ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰:" + free -h + + echo "๐Ÿณ Docker ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ:" + docker stats --no-stream + + echo "๐Ÿ’ฟ ๋””์Šคํฌ ์‚ฌ์šฉ๋Ÿ‰:" + df -h /volume1 + + echo "๐Ÿ”ฅ CPU ์‚ฌ์šฉ๋ฅ :" + top -bn1 | grep "Cpu(s)" +EOF +``` + +### ์ž๋™ ๋ฐฑ์—… (480GB SSD ์ตœ์ ํ™”) +```bash +#!/bin/bash +# scripts/backup.sh + +BACKUP_DIR="/volume1/backup/app" +DATE=$(date +%Y%m%d_%H%M%S) + +# ๋ฐฑ์—… ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ +mkdir -p $BACKUP_DIR/{database,volumes,configs} + +echo "๐Ÿ’พ ๋ฐฑ์—… ์‹œ์ž‘: $DATE" + +# 1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐฑ์—… (์••์ถ•) +docker exec postgres-prod pg_dump -U app_user app_prod | gzip > $BACKUP_DIR/database/postgres_$DATE.sql.gz + +# 2. ์ค‘์š” ๋ณผ๋ฅจ๋งŒ ๋ฐฑ์—… (์šฉ๋Ÿ‰ ๊ณ ๋ ค) +docker run --rm \ + -v app_postgres_data:/source:ro \ + -v $BACKUP_DIR/volumes:/backup \ + alpine tar czf /backup/postgres_$DATE.tar.gz -C /source . + +# 3. ์„ค์ • ํŒŒ์ผ ๋ฐฑ์—… +tar czf $BACKUP_DIR/configs/configs_$DATE.tar.gz \ + /volume1/docker/app/docker-compose.prod.yml \ + /volume1/docker/app/.env \ + /volume1/docker/app/config/ + +# 4. ์˜ค๋ž˜๋œ ๋ฐฑ์—… ์ •๋ฆฌ (SSD ์ˆ˜๋ช… ๊ณ ๋ ค) +find $BACKUP_DIR -name "*.gz" -mtime +7 -delete +find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete + +echo "โœ… ๋ฐฑ์—… ์™„๋ฃŒ: $DATE" +``` + +--- + +## ๐ŸŽฏ ์„ฑ๋Šฅ ๋ฒค์น˜๋งˆํฌ (DS1525+ 32GB) + +### ์˜ˆ์ƒ ์„ฑ๋Šฅ ์ง€ํ‘œ +``` +๐Ÿš€ DS1525+ 32GB ์„ฑ๋Šฅ (์ตœ์ ํ™” ํ›„) +โ”œโ”€โ”€ ๋™์‹œ ์‚ฌ์šฉ์ž: 200๋ช… +โ”œโ”€โ”€ ์‘๋‹ต ์‹œ๊ฐ„: 50-100ms +โ”œโ”€โ”€ ์ฒ˜๋ฆฌ๋Ÿ‰: 2,000 req/sec +โ”œโ”€โ”€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋ฅ : 70-80% +โ”œโ”€โ”€ CPU ์‚ฌ์šฉ๋ฅ : 30-50% +โ””โ”€โ”€ ๋””์Šคํฌ I/O: SSD ์ตœ์ ํ™” +``` + +### ๋ฆฌ์†Œ์Šค ํ• ๋‹น ํ˜„ํ™ฉ +``` +์ด 32GB ๋ฉ”๋ชจ๋ฆฌ ํ™œ์šฉ: +โ”œโ”€โ”€ PostgreSQL: 4GB (12.5%) +โ”œโ”€โ”€ Elasticsearch: 8GB (25%) +โ”œโ”€โ”€ Redis: 2GB (6.25%) +โ”œโ”€โ”€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜: 4GB (12.5%) +โ”œโ”€โ”€ ๋ชจ๋‹ˆํ„ฐ๋ง: 2GB (6.25%) +โ”œโ”€โ”€ ์‹œ์Šคํ…œ ์บ์‹œ: 8GB (25%) +โ”œโ”€โ”€ DSM: 2GB (6.25%) +โ””โ”€โ”€ ์—ฌ์œ : 2GB (6.25%) +``` + +--- + +## ๐Ÿšจ ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ฐ€์ด๋“œ + +### ์ผ๋ฐ˜์ ์ธ ๋ฌธ์ œ๋“ค + +#### 1. ์•„ํ‚คํ…์ฒ˜ ํ˜ธํ™˜์„ฑ ์˜ค๋ฅ˜ +```bash +# ์˜ค๋ฅ˜: exec format error +# ํ•ด๊ฒฐ: ํ”Œ๋žซํผ ๋ช…์‹œ์  ์ง€์ • +docker run --platform linux/amd64 your-image + +# ๋˜๋Š” Dockerfile์—์„œ +FROM --platform=linux/amd64 python:3.11-slim +``` + +#### 2. ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ (32GB์—์„œ๋Š” ๋“œ๋ฌผ์ง€๋งŒ) +```bash +# ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ +docker stats + +# Elasticsearch ๋ฉ”๋ชจ๋ฆฌ ์ค„์ด๊ธฐ (ํ•„์š”์‹œ) +ES_JAVA_OPTS="-Xms2g -Xmx4g" +``` + +#### 3. ๋””์Šคํฌ ๊ณต๊ฐ„ ๋ถ€์กฑ (480GB SSD) +```bash +# Docker ์ •๋ฆฌ +docker system prune -a + +# ๋กœ๊ทธ ์ •๋ฆฌ +find /volume1/docker/app/logs -name "*.log" -mtime +3 -delete + +# ๋ฐฑ์—… ์ •๋ฆฌ +find /volume1/backup -mtime +30 -delete +``` + +--- + +## ๐Ÿ“‹ ๋ฐฐํฌ ์ฒดํฌ๋ฆฌ์ŠคํŠธ + +### ๋ฐฐํฌ ์ „ ํ™•์ธ์‚ฌํ•ญ +```bash +โœ… ์ฒดํฌ๋ฆฌ์ŠคํŠธ +- [ ] ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ +- [ ] ๋ฉ€ํ‹ฐ ์•„ํ‚คํ…์ฒ˜ ๋นŒ๋“œ ์„ฑ๊ณต +- [ ] ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ • ์™„๋ฃŒ +- [ ] ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ค€๋น„ +- [ ] ํ—ฌ์Šค์ฒดํฌ ์—”๋“œํฌ์ธํŠธ ๊ตฌํ˜„ +- [ ] ๋ฐฑ์—… ๊ณ„ํš ์ˆ˜๋ฆฝ +- [ ] ๋กค๋ฐฑ ๊ณ„ํš ์ค€๋น„ +- [ ] ๋ชจ๋‹ˆํ„ฐ๋ง ์„ค์ • ํ™•์ธ +``` + +### ๋ฐฐํฌ ํ›„ ํ™•์ธ์‚ฌํ•ญ +```bash +โœ… ๋ฐฐํฌ ํ›„ ์ฒดํฌ +- [ ] ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ •์ƒ ๋™์ž‘ +- [ ] ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ™•์ธ +- [ ] ์บ์‹œ ๋™์ž‘ ํ™•์ธ +- [ ] ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ํ™•์ธ +- [ ] ๋ชจ๋‹ˆํ„ฐ๋ง ๋Œ€์‹œ๋ณด๋“œ ํ™•์ธ +- [ ] ๋กœ๊ทธ ์ˆ˜์ง‘ ํ™•์ธ +- [ ] ๋ฐฑ์—… ์ž๋™ํ™” ํ™•์ธ +``` + +--- + +## ๐ŸŽ‰ ๊ฒฐ๋ก  + +### DS1525+ 32GB์˜ ์••๋„์  ์žฅ์  +- โœ… **์ถฉ๋ถ„ํ•œ ์„ฑ๋Šฅ**: 32GB RAM์œผ๋กœ ๋ชจ๋“  ์„œ๋น„์Šค ์—ฌ์œ ๋กญ๊ฒŒ ์šด์˜ +- โœ… **24์‹œ๊ฐ„ ์•ˆ์ •์„ฑ**: ์ „๋ ฅ ํšจ์œจ์ , ์ €์†Œ์Œ ์šด์˜ +- โœ… **์™„์ „ ์ž๋™ํ™”**: ๊ฐœ๋ฐœ๋ถ€ํ„ฐ ๋ฐฐํฌ๊นŒ์ง€ ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋ฐ˜ +- โœ… **ํ™•์žฅ ๊ฐ€๋Šฅ**: ํ–ฅํ›„ ์„œ๋น„์Šค ํ™•์žฅ ์‹œ์—๋„ ์—ฌ์œ ๋กœ์›€ +- โœ… **๋น„์šฉ ํšจ์œจ**: ํด๋ผ์šฐ๋“œ ๋Œ€๋น„ ์›”๋“ฑํ•œ ๋น„์šฉ ์ ˆ์•ฝ + +### ๊ฐœ๋ฐœ-๋ฐฐํฌ ํŒŒ์ดํ”„๋ผ์ธ ์™„์„ฑ +``` +Mac ๊ฐœ๋ฐœ (Hot Reload) + โ†“ +๋ฉ€ํ‹ฐ ์•„ํ‚คํ…์ฒ˜ ๋นŒ๋“œ + โ†“ +DS1525+ ์ž๋™ ๋ฐฐํฌ + โ†“ +์‹ค์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋ง + โ†“ +์ž๋™ ๋ฐฑ์—… +``` + +**์ด์ œ ๊ฐœ๋ฐœ์—๋งŒ ์ง‘์ค‘ํ•˜๊ณ  ๋ฐฐํฌ๋Š” ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์•Œ์•„์„œ!** ๐Ÿš€ diff --git a/DS1525_OPTIMIZED_SETUP.md b/DS1525_OPTIMIZED_SETUP.md deleted file mode 100644 index 7a8e50c..0000000 --- a/DS1525_OPTIMIZED_SETUP.md +++ /dev/null @@ -1,607 +0,0 @@ -# ๐Ÿ  DS1525+ ์ตœ์ ํ™” ์„ค์น˜ ๊ฐ€์ด๋“œ - -## ๐Ÿ“‹ ํ•˜๋“œ์›จ์–ด ์‚ฌ์–‘ - -### ๋Œ€์ƒ ๊ธฐ๊ธฐ: Synology DS1525+ -- **CPU**: AMD Ryzen R1600 (4์ฝ”์–ด 2.6GHz) -- **๋ฉ”๋ชจ๋ฆฌ**: 32GB RAM (๋Œ€ํญ ์—…๊ทธ๋ ˆ์ด๋“œ๋จ!) -- **์ €์žฅ์žฅ์น˜**: ์‹œ๋†€๋กœ์ง€ ์ •ํ’ˆ 2.5" SSD 480GB -- **๋„คํŠธ์›Œํฌ**: ๊ธฐ๊ฐ€๋น„ํŠธ ์ด๋”๋„ท x4 -- **DSM**: 7.0 ์ด์ƒ - -### ์„ฑ๋Šฅ ํŠน์ง• -- **๊ณ ์„ฑ๋Šฅ CPU**: AMD Ryzen์œผ๋กœ NLP ์ฒ˜๋ฆฌ ์šฐ์ˆ˜ -- **๋Œ€์šฉ๋Ÿ‰ ๋ฉ”๋ชจ๋ฆฌ**: 32GB๋กœ ๋ชจ๋“  ์„œ๋น„์Šค ์—ฌ์œ ๋กญ๊ฒŒ ์šด์˜ -- **SSD ์Šคํ† ๋ฆฌ์ง€**: ๋น ๋ฅธ I/O, ๋‚ฎ์€ ์ง€์—ฐ์‹œ๊ฐ„ -- **๋ฉ€ํ‹ฐ ๊ธฐ๊ฐ€๋น„ํŠธ**: ๋„คํŠธ์›Œํฌ ๋ณ‘๋ชฉ ์—†์Œ - ---- - -## ๐Ÿš€ DS1525+ 32GB ์ตœ์ ํ™” ๊ตฌ์„ฑ - -### ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๊ณ„ํš (32GB ํ™œ์šฉ) -``` -์ด ๋ฉ”๋ชจ๋ฆฌ: 32GB -โ”œโ”€โ”€ DSM ์‹œ์Šคํ…œ: 2GB -โ”œโ”€โ”€ PostgreSQL: 4GB (๋Œ€ํญ ์ฆ๋Ÿ‰) -โ”œโ”€โ”€ Elasticsearch: 8GB (๊ณ ์„ฑ๋Šฅ ๊ฒ€์ƒ‰) -โ”œโ”€โ”€ Redis: 2GB (๋Œ€์šฉ๋Ÿ‰ ์บ์‹œ) -โ”œโ”€โ”€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜: 4GB (๋ฉ€ํ‹ฐ ์›Œ์ปค) -โ”œโ”€โ”€ NLP ์ฒ˜๋ฆฌ: 4GB (๋™์‹œ ์ฒ˜๋ฆฌ) -โ”œโ”€โ”€ ์‹œ์Šคํ…œ ์บ์‹œ: 6GB (ํŒŒ์ผ ์‹œ์Šคํ…œ ์บ์‹œ) -โ””โ”€โ”€ ์—ฌ์œ  ๊ณต๊ฐ„: 2GB -``` - -### Docker Compose ์ตœ์ ํ™” (DS1525+ ์ „์šฉ) -```yaml -# /volume1/docker/industrial-info/docker-compose.yml -version: '3.8' - -networks: - industrial-net: - driver: bridge - ipam: - config: - - subnet: 172.20.0.0/16 - -services: - postgres: - image: postgres:15-alpine - container_name: industrial-postgres - environment: - POSTGRES_DB: industrial_info - POSTGRES_USER: industrial_user - POSTGRES_PASSWORD: secure_password_here - POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C" - volumes: - - /volume1/docker/industrial-info/data/postgres:/var/lib/postgresql/data - - /volume1/docker/industrial-info/config/postgresql.conf:/etc/postgresql/postgresql.conf - ports: - - "5432:5432" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 4G # 32GB ํ™œ์šฉ - cpus: '2.0' # Ryzen 4์ฝ”์–ด ํ™œ์šฉ - reservations: - memory: 2G - cpus: '1.0' - command: postgres -c config_file=/etc/postgresql/postgresql.conf - - elasticsearch: - image: elasticsearch:8.11.0 - container_name: industrial-elasticsearch - environment: - - discovery.type=single-node - - "ES_JAVA_OPTS=-Xms4g -Xmx8g" # ๋Œ€ํญ ์ฆ๋Ÿ‰! - - xpack.security.enabled=false - - xpack.security.enrollment.enabled=false - - bootstrap.memory_lock=true - volumes: - - /volume1/docker/industrial-info/data/elasticsearch:/usr/share/elasticsearch/data - - /volume1/docker/industrial-info/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml - ports: - - "9200:9200" - - "9300:9300" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 10G # 8GB JVM + 2GB ์‹œ์Šคํ…œ - cpus: '2.0' - reservations: - memory: 6G - cpus: '1.0' - ulimits: - memlock: - soft: -1 - hard: -1 - nofile: - soft: 65536 - hard: 65536 - - redis: - image: redis:7-alpine - container_name: industrial-redis - command: redis-server /etc/redis/redis.conf - volumes: - - /volume1/docker/industrial-info/data/redis:/data - - /volume1/docker/industrial-info/config/redis.conf:/etc/redis/redis.conf - ports: - - "6379:6379" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 2G # ๋Œ€์šฉ๋Ÿ‰ ์บ์‹œ - cpus: '1.0' - reservations: - memory: 1G - cpus: '0.5' - - app: - build: ./app - container_name: industrial-app - environment: - - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info - - REDIS_URL=redis://redis:6379/0 - - ELASTICSEARCH_URL=http://elasticsearch:9200 - - PYTHONPATH=/app - - WORKERS=4 # ๋ฉ€ํ‹ฐ ์›Œ์ปค - volumes: - - /volume1/docker/industrial-info/app:/app - - /volume1/docker/industrial-info/data/logs:/app/logs - ports: - - "8000:8000" - networks: - - industrial-net - depends_on: - - postgres - - redis - - elasticsearch - restart: unless-stopped - deploy: - resources: - limits: - memory: 4G # ๋ฉ€ํ‹ฐ ์›Œ์ปค ์ง€์› - cpus: '2.0' - reservations: - memory: 2G - cpus: '1.0' - - # NLP ์ „์šฉ ์›Œ์ปค (๊ณ ์„ฑ๋Šฅ) - nlp-worker: - build: ./app - container_name: industrial-nlp-worker - command: celery -A main.celery worker --loglevel=info --concurrency=4 -Q nlp - environment: - - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info - - REDIS_URL=redis://redis:6379/0 - - ELASTICSEARCH_URL=http://elasticsearch:9200 - - SPACY_MODEL_PATH=/app/models - volumes: - - /volume1/docker/industrial-info/app:/app - - /volume1/docker/industrial-info/data/logs:/app/logs - - /volume1/docker/industrial-info/data/models:/app/models - networks: - - industrial-net - depends_on: - - postgres - - redis - - elasticsearch - restart: unless-stopped - deploy: - resources: - limits: - memory: 4G # NLP ๋ชจ๋ธ ๋กœ๋”ฉ์šฉ - cpus: '2.0' - reservations: - memory: 2G - cpus: '1.0' - - # ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ์›Œ์ปค - collector-worker: - build: ./app - container_name: industrial-collector - command: celery -A main.celery worker --loglevel=info --concurrency=2 -Q collector - environment: - - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info - - REDIS_URL=redis://redis:6379/0 - - ELASTICSEARCH_URL=http://elasticsearch:9200 - volumes: - - /volume1/docker/industrial-info/app:/app - - /volume1/docker/industrial-info/data/logs:/app/logs - networks: - - industrial-net - depends_on: - - postgres - - redis - - elasticsearch - restart: unless-stopped - deploy: - resources: - limits: - memory: 2G - cpus: '1.0' - reservations: - memory: 1G - cpus: '0.5' - - # ์Šค์ผ€์ค„๋Ÿฌ - scheduler: - build: ./app - container_name: industrial-scheduler - command: celery -A main.celery beat --loglevel=info - environment: - - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info - - REDIS_URL=redis://redis:6379/0 - - ELASTICSEARCH_URL=http://elasticsearch:9200 - volumes: - - /volume1/docker/industrial-info/app:/app - - /volume1/docker/industrial-info/data/logs:/app/logs - networks: - - industrial-net - depends_on: - - postgres - - redis - - elasticsearch - restart: unless-stopped - deploy: - resources: - limits: - memory: 512M - cpus: '0.5' - - # ๋ชจ๋‹ˆํ„ฐ๋ง (Prometheus) - prometheus: - image: prom/prometheus:latest - container_name: industrial-prometheus - volumes: - - /volume1/docker/industrial-info/config/prometheus.yml:/etc/prometheus/prometheus.yml - - /volume1/docker/industrial-info/data/prometheus:/prometheus - ports: - - "9090:9090" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 1G - cpus: '0.5' - - # ๋ชจ๋‹ˆํ„ฐ๋ง ๋Œ€์‹œ๋ณด๋“œ (Grafana) - grafana: - image: grafana/grafana:latest - container_name: industrial-grafana - environment: - - GF_SECURITY_ADMIN_PASSWORD=admin123 - volumes: - - /volume1/docker/industrial-info/data/grafana:/var/lib/grafana - ports: - - "3000:3000" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 1G - cpus: '0.5' - - nginx: - image: nginx:alpine - container_name: industrial-nginx - volumes: - - /volume1/docker/industrial-info/config/nginx.conf:/etc/nginx/nginx.conf - - /volume1/docker/industrial-info/data/logs:/var/log/nginx - ports: - - "80:80" - - "443:443" - networks: - - industrial-net - depends_on: - - app - restart: unless-stopped - deploy: - resources: - limits: - memory: 512M - cpus: '0.5' -``` - ---- - -## โš™๏ธ ๊ณ ์„ฑ๋Šฅ ์„ค์ • ํŒŒ์ผ๋“ค - -### PostgreSQL ์ตœ์ ํ™” (32GB ํ™œ์šฉ) -```ini -# /volume1/docker/industrial-info/config/postgresql.conf -# DS1525+ 32GB RAM ์ตœ์ ํ™” ์„ค์ • - -# ๋ฉ”๋ชจ๋ฆฌ ์„ค์ • -shared_buffers = 2GB # 32GB์˜ 6.25% -effective_cache_size = 16GB # 32GB์˜ 50% -maintenance_work_mem = 512MB # ๋Œ€์šฉ๋Ÿ‰ ์ธ๋ฑ์Šค ์ž‘์—… -work_mem = 64MB # ์ •๋ ฌ/ํ•ด์‹œ ์ž‘์—…์šฉ - -# ์ฒดํฌํฌ์ธํŠธ ์„ค์ • -checkpoint_completion_target = 0.9 -checkpoint_timeout = 15min -max_wal_size = 4GB -min_wal_size = 1GB - -# ์—ฐ๊ฒฐ ์„ค์ • -max_connections = 200 -shared_preload_libraries = 'pg_stat_statements' - -# ๋กœ๊ทธ ์„ค์ • -log_destination = 'stderr' -logging_collector = on -log_directory = '/var/lib/postgresql/data/log' -log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' -log_rotation_age = 1d -log_rotation_size = 100MB -log_min_duration_statement = 1000 # 1์ดˆ ์ด์ƒ ์ฟผ๋ฆฌ ๋กœ๊น… - -# ์„ฑ๋Šฅ ์ตœ์ ํ™” -random_page_cost = 1.1 # SSD ์ตœ์ ํ™” -effective_io_concurrency = 200 # SSD ๋™์‹œ I/O -max_worker_processes = 4 # Ryzen 4์ฝ”์–ด ํ™œ์šฉ -max_parallel_workers = 4 -max_parallel_workers_per_gather = 2 - -# ์ž๋™ VACUUM ์ตœ์ ํ™” -autovacuum = on -autovacuum_max_workers = 2 -autovacuum_naptime = 30s -``` - -### Elasticsearch ์ตœ์ ํ™” (8GB JVM) -```yaml -# /volume1/docker/industrial-info/config/elasticsearch.yml -cluster.name: "industrial-cluster" -node.name: "industrial-node-1" -path.data: /usr/share/elasticsearch/data -path.logs: /usr/share/elasticsearch/logs - -# ๋„คํŠธ์›Œํฌ ์„ค์ • -network.host: 0.0.0.0 -http.port: 9200 -transport.port: 9300 - -# ๋ฉ”๋ชจ๋ฆฌ ์„ค์ • (32GB ํ™˜๊ฒฝ) -bootstrap.memory_lock: true -indices.memory.index_buffer_size: 2GB -indices.fielddata.cache.size: 2GB - -# ์„ฑ๋Šฅ ์ตœ์ ํ™” -thread_pool.write.queue_size: 1000 -thread_pool.search.queue_size: 1000 -indices.queries.cache.size: 1GB - -# SSD ์ตœ์ ํ™” -index.store.type: niofs -index.merge.scheduler.max_thread_count: 2 - -# ํ•œ๊ตญ์–ด ๋ถ„์„ ์„ค์ • -index.analysis.analyzer.nori.type: custom -index.analysis.analyzer.nori.tokenizer: nori_tokenizer -index.analysis.analyzer.nori.filter: [nori_part_of_speech, lowercase] -``` - -### Redis ์ตœ์ ํ™” (2GB) -```ini -# /volume1/docker/industrial-info/config/redis.conf -# DS1525+ 32GB RAM ์ตœ์ ํ™” - -# ๋ฉ”๋ชจ๋ฆฌ ์„ค์ • -maxmemory 2gb -maxmemory-policy allkeys-lru - -# ์˜์†์„ฑ ์„ค์ • (SSD ์ตœ์ ํ™”) -save 900 1 -save 300 10 -save 60 10000 - -# AOF ์„ค์ • -appendonly yes -appendfsync everysec -auto-aof-rewrite-percentage 100 -auto-aof-rewrite-min-size 64mb - -# ๋„คํŠธ์›Œํฌ ์ตœ์ ํ™” -tcp-keepalive 300 -timeout 0 - -# ์„ฑ๋Šฅ ์ตœ์ ํ™” -hash-max-ziplist-entries 512 -hash-max-ziplist-value 64 -list-max-ziplist-size -2 -set-max-intset-entries 512 -zset-max-ziplist-entries 128 -zset-max-ziplist-value 64 - -# ๋กœ๊ทธ ์„ค์ • -loglevel notice -logfile "" -``` - ---- - -## ๐Ÿ“Š ์„ฑ๋Šฅ ๋ฒค์น˜๋งˆํฌ (DS1525+ 32GB) - -### ์˜ˆ์ƒ ์„ฑ๋Šฅ ์ง€ํ‘œ -``` -๋™์‹œ ์‚ฌ์šฉ์ž: 100๋ช… (์—ฌ์œ ๋กญ๊ฒŒ) -๊ฒ€์ƒ‰ ์‘๋‹ต์‹œ๊ฐ„: 50-100ms (๋งค์šฐ ๋น ๋ฆ„) -RSS ์ˆ˜์ง‘: 500๊ฐœ ํ”ผ๋“œ/๋ถ„ (๋Œ€์šฉ๋Ÿ‰ ์ฒ˜๋ฆฌ) -NLP ์ฒ˜๋ฆฌ: 10,000๊ฑด/์‹œ๊ฐ„ (๊ณ ์† ์ฒ˜๋ฆฌ) -๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค: 1,000 TPS (๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰) -``` - -### ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋ฅ  ๋ชฉํ‘œ -``` -CPU ์‚ฌ์šฉ๋ฅ : ํ‰๊ท  30-40% (์—ฌ์œ ) -๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋ฅ : ํ‰๊ท  70-80% (ํšจ์œจ์ ) -๋””์Šคํฌ I/O: SSD ์„ฑ๋Šฅ ์ตœ๋Œ€ ํ™œ์šฉ -๋„คํŠธ์›Œํฌ: ๊ธฐ๊ฐ€๋น„ํŠธ ๋Œ€์—ญํญ ํ™œ์šฉ -``` - ---- - -## ๐Ÿ’พ SSD 480GB ์ตœ์ ํ™” - -### ๋””์Šคํฌ ๊ณต๊ฐ„ ํ• ๋‹น -``` -์ด ์šฉ๋Ÿ‰: 480GB -โ”œโ”€โ”€ DSM ์‹œ์Šคํ…œ: 50GB -โ”œโ”€โ”€ Docker ์ด๋ฏธ์ง€: 20GB -โ”œโ”€โ”€ PostgreSQL ๋ฐ์ดํ„ฐ: 100GB -โ”œโ”€โ”€ Elasticsearch ์ธ๋ฑ์Šค: 150GB -โ”œโ”€โ”€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ: 30GB -โ”œโ”€โ”€ ๋ฐฑ์—… ๊ณต๊ฐ„: 80GB -โ””โ”€โ”€ ์—ฌ์œ  ๊ณต๊ฐ„: 50GB (10% ์—ฌ์œ ) -``` - -### SSD ์ˆ˜๋ช… ์—ฐ์žฅ ์„ค์ • -```bash -# SSD ์ตœ์ ํ™” ์Šคํฌ๋ฆฝํŠธ -#!/bin/bash - -# TRIM ํ™œ์„ฑํ™” -echo 'deadline' > /sys/block/sda/queue/scheduler - -# ๋กœ๊ทธ ๋กœํ…Œ์ด์…˜ ์ตœ์ ํ™” -cat > /etc/logrotate.d/docker << EOF -/volume1/docker/industrial-info/data/logs/*.log { - daily - rotate 7 - compress - delaycompress - missingok - notifempty - create 644 root root -} -EOF - -# ์Šค์™‘ ์‚ฌ์šฉ ์ตœ์†Œํ™” -echo 'vm.swappiness=1' >> /etc/sysctl.conf -echo 'vm.vfs_cache_pressure=50' >> /etc/sysctl.conf -``` - -### ์ž๋™ ์ •๋ฆฌ ์Šคํฌ๋ฆฝํŠธ -```bash -# /volume1/docker/industrial-info/scripts/cleanup.sh -#!/bin/bash - -# Docker ์ด๋ฏธ์ง€ ์ •๋ฆฌ (์ฃผ๊ฐ„) -docker system prune -f - -# ๋กœ๊ทธ ํŒŒ์ผ ์••์ถ• (์ผ์ผ) -find /volume1/docker/industrial-info/data/logs -name "*.log" -mtime +1 -exec gzip {} \; - -# ์˜ค๋ž˜๋œ ๋ฐฑ์—… ์‚ญ์ œ (์›”๊ฐ„) -find /volume1/docker/industrial-info/backup -name "*.gz" -mtime +30 -delete - -# Elasticsearch ์ธ๋ฑ์Šค ์ตœ์ ํ™” (์ฃผ๊ฐ„) -curl -X POST "localhost:9200/_forcemerge?max_num_segments=1" - -echo "Cleanup completed: $(date)" -``` - ---- - -## ๐Ÿ”ง ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ์•Œ๋ฆผ - -### Prometheus ์„ค์ • -```yaml -# /volume1/docker/industrial-info/config/prometheus.yml -global: - scrape_interval: 15s - -scrape_configs: - - job_name: 'industrial-app' - static_configs: - - targets: ['app:8000'] - - - job_name: 'postgres' - static_configs: - - targets: ['postgres:5432'] - - - job_name: 'elasticsearch' - static_configs: - - targets: ['elasticsearch:9200'] - - - job_name: 'redis' - static_configs: - - targets: ['redis:6379'] - - - job_name: 'node-exporter' - static_configs: - - targets: ['localhost:9100'] -``` - -### ์•Œ๋ฆผ ๊ทœ์น™ -```yaml -# ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋ฅ  80% ์ดˆ๊ณผ ์‹œ ์•Œ๋ฆผ -- alert: HighMemoryUsage - expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 80 - for: 5m - labels: - severity: warning - annotations: - summary: "High memory usage detected" - -# ๋””์Šคํฌ ์‚ฌ์šฉ๋ฅ  85% ์ดˆ๊ณผ ์‹œ ์•Œ๋ฆผ -- alert: HighDiskUsage - expr: (1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100 > 85 - for: 5m - labels: - severity: critical - annotations: - summary: "High disk usage detected" -``` - ---- - -## ๐Ÿš€ ๋ฐฐํฌ ๋ฐ ์‹คํ–‰ - -### ์›ํด๋ฆญ ์„ค์น˜ ์Šคํฌ๋ฆฝํŠธ -```bash -#!/bin/bash -# /volume1/docker/industrial-info/install.sh - -echo "๐Ÿš€ DS1525+ ์‚ฐ์—…์ •๋ณด์‹œ์Šคํ…œ ์„ค์น˜ ์‹œ์ž‘..." - -# ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ -mkdir -p /volume1/docker/industrial-info/{app,data/{postgres,elasticsearch,redis,logs,grafana,prometheus},config,backup,scripts} - -# ๊ถŒํ•œ ์„ค์ • -chown -R 1000:1000 /volume1/docker/industrial-info - -# Docker ๋„คํŠธ์›Œํฌ ์ƒ์„ฑ -docker network create industrial-net 2>/dev/null || true - -# ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ ์ƒ์„ฑ -cat > /volume1/docker/industrial-info/.env << EOF -POSTGRES_PASSWORD=$(openssl rand -base64 32) -SECRET_KEY=$(openssl rand -base64 64) -ELASTICSEARCH_PASSWORD=$(openssl rand -base64 32) -EOF - -# ์ปจํ…Œ์ด๋„ˆ ์‹œ์ž‘ -cd /volume1/docker/industrial-info -docker-compose up --build -d - -echo "โœ… ์„ค์น˜ ์™„๋ฃŒ! ์ ‘์† URL:" -echo " ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜: http://$(hostname -I | awk '{print $1}'):80" -echo " ๋ชจ๋‹ˆํ„ฐ๋ง: http://$(hostname -I | awk '{print $1}'):3000" -echo " Elasticsearch: http://$(hostname -I | awk '{print $1}'):9200" -``` - ---- - -## ๐Ÿ“ˆ ์„ฑ๋Šฅ ๋น„๊ต ์š”์•ฝ - -### DS1525+ vs ์ผ๋ฐ˜ NAS vs Mac -| ํ•ญ๋ชฉ | DS1525+ 32GB | ์ผ๋ฐ˜ NAS 8GB | Mac Mini M2 | -|------|--------------|--------------|-------------| -| ๋™์‹œ ์‚ฌ์šฉ์ž | 100๋ช… | 20๋ช… | 50๋ช… | -| ๊ฒ€์ƒ‰ ์†๋„ | 50ms | 200ms | 30ms | -| NLP ์ฒ˜๋ฆฌ | 10K๊ฑด/์‹œ๊ฐ„ | 1K๊ฑด/์‹œ๊ฐ„ | 15K๊ฑด/์‹œ๊ฐ„ | -| ์ „๋ ฅ ์†Œ๋ชจ | 60W | 40W | 150W | -| 24์‹œ๊ฐ„ ์šด์˜ | โœ… ์ตœ์  | โœ… ๊ฐ€๋Šฅ | โŒ ๋น„ํšจ์œจ | -| ํ™•์žฅ์„ฑ | โœ… ์šฐ์ˆ˜ | โš ๏ธ ์ œํ•œ์  | โŒ ์ œํ•œ์  | -| ๋น„์šฉ ํšจ์œจ | โœ… ์ตœ๊ณ  | โœ… ์ข‹์Œ | โŒ ๋†’์Œ | - -**๊ฒฐ๋ก **: DS1525+ 32GB๋Š” ์ด ํ”„๋กœ์ ํŠธ์— **๊ณผ๋ถ„ํ•  ์ •๋„๋กœ ์ข‹์€ ์„ฑ๋Šฅ**์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค! ๐Ÿš€ - -480GB SSD๋„ ์ถฉ๋ถ„ํ•˜๊ณ , 32GB RAM์œผ๋กœ ๋ชจ๋“  ์„œ๋น„์Šค๋ฅผ ์—ฌ์œ ๋กญ๊ฒŒ ๋Œ๋ฆด ์ˆ˜ ์žˆ์–ด์š”. ์™„๋ฒฝํ•œ ์„ ํƒ์ž…๋‹ˆ๋‹ค! ๐Ÿ‘ diff --git a/HOMEBREW_SETUP.md b/HOMEBREW_SETUP.md deleted file mode 100644 index 0b105ab..0000000 --- a/HOMEBREW_SETUP.md +++ /dev/null @@ -1,592 +0,0 @@ -# ๐Ÿบ Homebrew ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœํ™˜๊ฒฝ ์„ค์ • ๊ฐ€์ด๋“œ - -## ๐Ÿ“‹ ๊ฐœ์š” - -macOS์—์„œ Homebrew๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฐ์—… ์ „๋ฌธ ์ •๋ณด ์ˆ˜์ง‘ ์‹œ์Šคํ…œ์˜ ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๋Š” ๋‹จ๊ณ„๋ณ„ ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค. - ---- - -## ๐Ÿ”ง ์‚ฌ์ „ ์š”๊ตฌ์‚ฌํ•ญ - -### ์‹œ์Šคํ…œ ์š”๊ตฌ์‚ฌํ•ญ -- **macOS**: 12.0+ (Monterey ์ด์ƒ ๊ถŒ์žฅ) -- **๋ฉ”๋ชจ๋ฆฌ**: 8GB ์ด์ƒ (16GB ๊ถŒ์žฅ) -- **์ €์žฅ๊ณต๊ฐ„**: 20GB ์ด์ƒ ์—ฌ์œ  ๊ณต๊ฐ„ -- **๋„คํŠธ์›Œํฌ**: ์ธํ„ฐ๋„ท ์—ฐ๊ฒฐ (ํŒจํ‚ค์ง€ ๋‹ค์šด๋กœ๋“œ์šฉ) - -### ๊ฐœ๋ฐœ์ž ๋„๊ตฌ -```bash -# Xcode Command Line Tools ์„ค์น˜ (Homebrew ์„ค์น˜ ์ „ ํ•„์ˆ˜) -xcode-select --install -``` - ---- - -## ๐Ÿบ 1๋‹จ๊ณ„: Homebrew ์„ค์น˜ - -### Homebrew ์„ค์น˜ -```bash -# Homebrew ์„ค์น˜ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - -# ์„ค์น˜ ํ™•์ธ -brew --version - -# PATH ์„ค์ • (M1/M2 Mac์˜ ๊ฒฝ์šฐ) -echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc -source ~/.zshrc -``` - -### Homebrew ์—…๋ฐ์ดํŠธ -```bash -# Homebrew ์ž์ฒด ์—…๋ฐ์ดํŠธ -brew update - -# ์„ค์น˜๋œ ํŒจํ‚ค์ง€ ์—…๊ทธ๋ ˆ์ด๋“œ -brew upgrade -``` - ---- - -## ๐Ÿ 2๋‹จ๊ณ„: Python ํ™˜๊ฒฝ ์„ค์ • - -### Python ์„ค์น˜ -```bash -# Python 3.11 ์„ค์น˜ (์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „) -brew install python@3.11 - -# ์„ค์น˜ ํ™•์ธ -python3 --version -pip3 --version - -# ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ์„ค์ • (์„ ํƒ์‚ฌํ•ญ) -brew link python@3.11 -``` - -### ๊ฐ€์ƒํ™˜๊ฒฝ ๋„๊ตฌ ์„ค์น˜ -```bash -# virtualenv ์„ค์น˜ -pip3 install virtualenv - -# ๋˜๋Š” pyenv ์‚ฌ์šฉ (Python ๋ฒ„์ „ ๊ด€๋ฆฌ) -brew install pyenv -echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc -echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc -echo 'eval "$(pyenv init -)"' >> ~/.zshrc -source ~/.zshrc -``` - -### ํ”„๋กœ์ ํŠธ ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ -```bash -# ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™ -cd /Users/hyungi/news-project - -# ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ -python3 -m venv venv - -# ๊ฐ€์ƒํ™˜๊ฒฝ ํ™œ์„ฑํ™” -source venv/bin/activate - -# ๊ฐ€์ƒํ™˜๊ฒฝ ํ™œ์„ฑํ™” ํ™•์ธ (ํ”„๋กฌํ”„ํŠธ์— (venv) ํ‘œ์‹œ๋จ) -which python -``` - ---- - -## ๐ŸŸข 3๋‹จ๊ณ„: Node.js ํ™˜๊ฒฝ ์„ค์ • - -### Node.js ์„ค์น˜ -```bash -# Node.js 18 LTS ์„ค์น˜ -brew install node@18 - -# ์„ค์น˜ ํ™•์ธ -node --version -npm --version - -# ๊ธ€๋กœ๋ฒŒ ํŒจํ‚ค์ง€ ์—…๋ฐ์ดํŠธ -npm install -g npm@latest -``` - -### ์„ ํƒ์ : Node ๋ฒ„์ „ ๊ด€๋ฆฌ์ž ์„ค์น˜ -```bash -# nvm ์„ค์น˜ (Node Version Manager) -brew install nvm - -# nvm ์„ค์ • -mkdir ~/.nvm -echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.zshrc -echo '[ -s "/opt/homebrew/share/nvm/nvm.sh" ] && \. "/opt/homebrew/share/nvm/nvm.sh"' >> ~/.zshrc -echo '[ -s "/opt/homebrew/share/nvm/bash_completion" ] && \. "/opt/homebrew/share/nvm/bash_completion"' >> ~/.zshrc -source ~/.zshrc - -# Node.js 18 ์„ค์น˜ ๋ฐ ์‚ฌ์šฉ -nvm install 18 -nvm use 18 -nvm alias default 18 -``` - ---- - -## ๐Ÿ—„๏ธ 4๋‹จ๊ณ„: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์น˜ - -### PostgreSQL ์„ค์น˜ -```bash -# PostgreSQL ์„ค์น˜ -brew install postgresql@15 - -# ์„œ๋น„์Šค ์‹œ์ž‘ -brew services start postgresql@15 - -# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ƒ์„ฑ -createdb industrial_info - -# ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ -psql industrial_info -# \q ๋กœ ์ข…๋ฃŒ -``` - -### PostgreSQL ์„ค์ • -```bash -# ์‚ฌ์šฉ์ž ์ƒ์„ฑ (์„ ํƒ์‚ฌํ•ญ) -createuser --interactive --pwprompt industrial_user - -# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ถŒํ•œ ๋ถ€์—ฌ -psql -c "GRANT ALL PRIVILEGES ON DATABASE industrial_info TO industrial_user;" -``` - -### Redis ์„ค์น˜ -```bash -# Redis ์„ค์น˜ -brew install redis - -# ์„œ๋น„์Šค ์‹œ์ž‘ -brew services start redis - -# ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ -redis-cli ping -# PONG ์‘๋‹ต ํ™•์ธ -``` - ---- - -## ๐Ÿ” 5๋‹จ๊ณ„: Elasticsearch ์„ค์น˜ - -### Elasticsearch ์„ค์น˜ -```bash -# Elasticsearch ์„ค์น˜ -brew install elasticsearch - -# ์„ค์ • ํŒŒ์ผ ์œ„์น˜ ํ™•์ธ -brew --prefix elasticsearch - -# JVM ๋ฉ”๋ชจ๋ฆฌ ์„ค์ • (8GB Mac ๊ธฐ์ค€) -echo 'export ELASTICSEARCH_JAVA_OPTS="-Xms512m -Xmx1g"' >> ~/.zshrc -source ~/.zshrc - -# ์„œ๋น„์Šค ์‹œ์ž‘ -brew services start elasticsearch - -# ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ (์•ฝ 30์ดˆ ํ›„) -curl http://localhost:9200 -``` - -### Elasticsearch ํ•œ๊ตญ์–ด ๋ถ„์„๊ธฐ ์„ค์น˜ -```bash -# nori ๋ถ„์„๊ธฐ ์„ค์น˜ -/opt/homebrew/bin/elasticsearch-plugin install analysis-nori - -# ์„œ๋น„์Šค ์žฌ์‹œ์ž‘ -brew services restart elasticsearch -``` - ---- - -## ๐Ÿณ 6๋‹จ๊ณ„: Docker ์„ค์น˜ - -### Docker Desktop ์„ค์น˜ -```bash -# Docker Desktop ์„ค์น˜ -brew install --cask docker - -# Docker ์‹คํ–‰ ํ™•์ธ (GUI์—์„œ Docker Desktop ์‹คํ–‰ ํ•„์š”) -docker --version -docker-compose --version -``` - -### Docker ์„ค์ • ์ตœ์ ํ™” -```bash -# Docker Desktop ์„ค์ • ๊ถŒ์žฅ์‚ฌํ•ญ: -# - Memory: 4GB (8GB Mac ๊ธฐ์ค€) -# - Swap: 1GB -# - Disk image size: 64GB -``` - ---- - -## ๐Ÿ› ๏ธ 7๋‹จ๊ณ„: ๊ฐœ๋ฐœ ๋„๊ตฌ ์„ค์น˜ - -### ํ•„์ˆ˜ ๊ฐœ๋ฐœ ๋„๊ตฌ -```bash -# Git (์ด๋ฏธ ์„ค์น˜๋˜์–ด ์žˆ์„ ์ˆ˜ ์žˆ์Œ) -brew install git - -# ์‹œ์Šคํ…œ ๋ชจ๋‹ˆํ„ฐ๋ง ๋„๊ตฌ -brew install htop - -# ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ ๋„๊ตฌ -brew install jq # JSON ์ฒ˜๋ฆฌ -brew install ripgrep # ๋น ๋ฅธ ํ…์ŠคํŠธ ๊ฒ€์ƒ‰ - -# ๋„คํŠธ์›Œํฌ ๋„๊ตฌ -brew install curl -brew install wget -``` - -### IDE ๋ฐ ์—๋””ํ„ฐ -```bash -# Visual Studio Code -brew install --cask visual-studio-code - -# ๋˜๋Š” ๋‹ค๋ฅธ ์—๋””ํ„ฐ๋“ค -brew install --cask sublime-text -brew install --cask atom -brew install vim # ํ„ฐ๋ฏธ๋„ ์—๋””ํ„ฐ -``` - -### ์„ ํƒ์  ๋„๊ตฌ -```bash -# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค GUI ๋„๊ตฌ -brew install --cask dbeaver-community # ๋‹ค์ค‘ DB ํด๋ผ์ด์–ธํŠธ -brew install --cask tableplus # macOS ๋„ค์ดํ‹ฐ๋ธŒ DB ํด๋ผ์ด์–ธํŠธ - -# API ํ…Œ์ŠคํŠธ ๋„๊ตฌ -brew install --cask postman -brew install --cask insomnia - -# ํ„ฐ๋ฏธ๋„ ๊ฐœ์„  -brew install zsh-autosuggestions -brew install zsh-syntax-highlighting -``` - ---- - -## ๐Ÿš€ 8๋‹จ๊ณ„: ํ”„๋กœ์ ํŠธ ์„ค์ • - -### ํ”„๋กœ์ ํŠธ ํด๋ก  ๋ฐ ์„ค์ • -```bash -# ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™ -cd /Users/hyungi/news-project - -# ๊ฐ€์ƒํ™˜๊ฒฝ ํ™œ์„ฑํ™” -source venv/bin/activate - -# ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ ์ƒ์„ฑ -cp .env.example .env -``` - -### ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • (.env ํŒŒ์ผ) -```bash -# .env ํŒŒ์ผ ํŽธ์ง‘ -cat > .env << EOF -# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ • -DATABASE_URL=postgresql://industrial_user:password@localhost:5432/industrial_info -REDIS_URL=redis://localhost:6379/0 -ELASTICSEARCH_URL=http://localhost:9200 - -# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ • -DEBUG=True -SECRET_KEY=your-secret-key-here - -# API ํ‚ค (ํ•„์š”์‹œ) -PUBMED_API_KEY=your-pubmed-api-key -IEEE_API_KEY=your-ieee-api-key -EOF -``` - -### Python ์˜์กด์„ฑ ์„ค์น˜ -```bash -# requirements.txt๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ -pip install -r requirements.txt - -# ๋˜๋Š” ๊ธฐ๋ณธ ํŒจํ‚ค์ง€ ์„ค์น˜ -pip install fastapi uvicorn sqlalchemy psycopg2-binary redis elasticsearch celery spacy beautifulsoup4 requests pandas numpy -``` - -### Node.js ์˜์กด์„ฑ ์„ค์น˜ (ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ) -```bash -# frontend ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ -cd frontend -npm install -cd .. -``` - ---- - -## ๐Ÿ”ง 9๋‹จ๊ณ„: ์„œ๋น„์Šค ๊ด€๋ฆฌ - -### ์„œ๋น„์Šค ์‹œ์ž‘/์ค‘์ง€ ๋ช…๋ น์–ด -```bash -# ๋ชจ๋“  ์„œ๋น„์Šค ์‹œ์ž‘ -brew services start postgresql@15 -brew services start redis -brew services start elasticsearch - -# ์„œ๋น„์Šค ์ƒํƒœ ํ™•์ธ -brew services list - -# ํŠน์ • ์„œ๋น„์Šค ์ค‘์ง€ -brew services stop postgresql@15 -brew services stop redis -brew services stop elasticsearch - -# ์„œ๋น„์Šค ์žฌ์‹œ์ž‘ -brew services restart postgresql@15 -``` - -### ์ž๋™ ์‹œ์ž‘ ์„ค์ • -```bash -# ์‹œ์Šคํ…œ ๋ถ€ํŒ… ์‹œ ์ž๋™ ์‹œ์ž‘ (์ด๋ฏธ ์„ค์ •๋จ) -# brew services start ๋ช…๋ น์–ด๋กœ ์„ค์น˜ํ•œ ์„œ๋น„์Šค๋“ค์€ ์ž๋™์œผ๋กœ ๋ถ€ํŒ… ์‹œ ์‹œ์ž‘๋จ - -# ์ˆ˜๋™์œผ๋กœ ์ž๋™ ์‹œ์ž‘ ํ•ด์ œํ•˜๋ ค๋ฉด -brew services stop postgresql@15 -# ๊ทธ๋ฆฌ๊ณ  ์ˆ˜๋™์œผ๋กœ ์‹œ์ž‘ํ•˜๋ ค๋ฉด -pg_ctl -D /opt/homebrew/var/postgresql@15 start -``` - ---- - -## ๐Ÿ“Š 10๋‹จ๊ณ„: ์„ฑ๋Šฅ ์ตœ์ ํ™” - -### ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ตœ์ ํ™” (8GB Mac ๊ธฐ์ค€) -```bash -# ~/.zshrc์— ์ถ”๊ฐ€ -cat >> ~/.zshrc << EOF - -# ๊ฐœ๋ฐœํ™˜๊ฒฝ ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™” -export ELASTICSEARCH_JAVA_OPTS="-Xms512m -Xmx1g" -export REDIS_MAXMEMORY="256mb" -export PYTHONOPTIMIZE=1 - -# PostgreSQL ์„ค์ • ์ตœ์ ํ™” -export PGDATA="/opt/homebrew/var/postgresql@15" -EOF - -source ~/.zshrc -``` - -### PostgreSQL ์„ค์ • ์ตœ์ ํ™” -```bash -# postgresql.conf ํŽธ์ง‘ -vim /opt/homebrew/var/postgresql@15/postgresql.conf - -# ๋‹ค์Œ ์„ค์ • ์ถ”๊ฐ€/์ˆ˜์ •: -# shared_buffers = 256MB -# effective_cache_size = 1GB -# maintenance_work_mem = 64MB -# checkpoint_completion_target = 0.9 -# wal_buffers = 16MB -# default_statistics_target = 100 - -# ์„ค์ • ์ ์šฉ์„ ์œ„ํ•ด ์žฌ์‹œ์ž‘ -brew services restart postgresql@15 -``` - ---- - -## ๐Ÿ” 11๋‹จ๊ณ„: ๊ฐœ๋ฐœํ™˜๊ฒฝ ํ…Œ์ŠคํŠธ - -### ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ -```bash -# test_connections.py ์ƒ์„ฑ -cat > test_connections.py << EOF -#!/usr/bin/env python3 -import psycopg2 -import redis -import requests - -def test_postgresql(): - try: - conn = psycopg2.connect( - host="localhost", - database="industrial_info", - user="industrial_user", - password="password" - ) - print("โœ… PostgreSQL ์—ฐ๊ฒฐ ์„ฑ๊ณต") - conn.close() - except Exception as e: - print(f"โŒ PostgreSQL ์—ฐ๊ฒฐ ์‹คํŒจ: {e}") - -def test_redis(): - try: - r = redis.Redis(host='localhost', port=6379, db=0) - r.ping() - print("โœ… Redis ์—ฐ๊ฒฐ ์„ฑ๊ณต") - except Exception as e: - print(f"โŒ Redis ์—ฐ๊ฒฐ ์‹คํŒจ: {e}") - -def test_elasticsearch(): - try: - response = requests.get('http://localhost:9200') - if response.status_code == 200: - print("โœ… Elasticsearch ์—ฐ๊ฒฐ ์„ฑ๊ณต") - else: - print(f"โŒ Elasticsearch ์—ฐ๊ฒฐ ์‹คํŒจ: {response.status_code}") - except Exception as e: - print(f"โŒ Elasticsearch ์—ฐ๊ฒฐ ์‹คํŒจ: {e}") - -if __name__ == "__main__": - print("๐Ÿ” ๊ฐœ๋ฐœํ™˜๊ฒฝ ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ") - test_postgresql() - test_redis() - test_elasticsearch() -EOF - -# ํ…Œ์ŠคํŠธ ์‹คํ–‰ -python test_connections.py -``` - -### ์‹œ์Šคํ…œ ๋ฆฌ์†Œ์Šค ๋ชจ๋‹ˆํ„ฐ๋ง -```bash -# ์‹œ์Šคํ…œ ๋ฆฌ์†Œ์Šค ํ™•์ธ -htop - -# Docker ์ปจํ…Œ์ด๋„ˆ ๋ฆฌ์†Œ์Šค ํ™•์ธ (Docker ์‚ฌ์šฉ ์‹œ) -docker stats - -# ๋””์Šคํฌ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ -df -h - -# ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ -vm_stat -``` - ---- - -## ๐Ÿšจ ๋ฌธ์ œ ํ•ด๊ฒฐ - -### ์ผ๋ฐ˜์ ์ธ ๋ฌธ์ œ๋“ค - -#### 1. Homebrew ์„ค์น˜ ์‹คํŒจ -```bash -# ๊ถŒํ•œ ๋ฌธ์ œ ํ•ด๊ฒฐ -sudo chown -R $(whoami) /opt/homebrew - -# ๋˜๋Š” Rosetta 2 ์„ค์น˜ (M1/M2 Mac) -softwareupdate --install-rosetta -``` - -#### 2. PostgreSQL ์—ฐ๊ฒฐ ์‹คํŒจ -```bash -# ์„œ๋น„์Šค ์ƒํƒœ ํ™•์ธ -brew services list | grep postgresql - -# ๋กœ๊ทธ ํ™•์ธ -tail -f /opt/homebrew/var/log/postgresql@15.log - -# ํฌํŠธ ์ถฉ๋Œ ํ™•์ธ -lsof -i :5432 -``` - -#### 3. Elasticsearch ์‹œ์ž‘ ์‹คํŒจ -```bash -# Java ์„ค์น˜ ํ™•์ธ -java --version - -# ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์‹œ ์„ค์ • ์กฐ์ • -export ELASTICSEARCH_JAVA_OPTS="-Xms256m -Xmx512m" - -# ๋กœ๊ทธ ํ™•์ธ -tail -f /opt/homebrew/var/log/elasticsearch.log -``` - -#### 4. Redis ์—ฐ๊ฒฐ ๋ฌธ์ œ -```bash -# Redis ์„œ๋น„์Šค ํ™•์ธ -brew services list | grep redis - -# ์„ค์ • ํŒŒ์ผ ํ™•์ธ -cat /opt/homebrew/etc/redis.conf - -# ํฌํŠธ ํ™•์ธ -lsof -i :6379 -``` - -### ์„ฑ๋Šฅ ๋ฌธ์ œ ํ•ด๊ฒฐ - -#### ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์‹œ -```bash -# ๋ถˆํ•„์š”ํ•œ ์„œ๋น„์Šค ์ค‘์ง€ -brew services stop elasticsearch # ์ž„์‹œ๋กœ ์ค‘์ง€ - -# Swap ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ -sysctl vm.swapusage - -# ๋ฉ”๋ชจ๋ฆฌ ์ •๋ฆฌ -sudo purge -``` - -#### ๋””์Šคํฌ ๊ณต๊ฐ„ ๋ถ€์กฑ ์‹œ -```bash -# Homebrew ์บ์‹œ ์ •๋ฆฌ -brew cleanup - -# Docker ์ด๋ฏธ์ง€ ์ •๋ฆฌ -docker system prune -a - -# ๋กœ๊ทธ ํŒŒ์ผ ์ •๋ฆฌ -sudo rm -rf /opt/homebrew/var/log/*.log.* -``` - ---- - -## ๐Ÿ“š ์ถ”๊ฐ€ ๋ฆฌ์†Œ์Šค - -### ์œ ์šฉํ•œ ๋ช…๋ น์–ด ๋ชจ์Œ -```bash -# ๋ชจ๋“  Homebrew ์„œ๋น„์Šค ์ƒํƒœ ํ™•์ธ -brew services list - -# ์„ค์น˜๋œ ํŒจํ‚ค์ง€ ๋ชฉ๋ก -brew list - -# ํŒจํ‚ค์ง€ ์ •๋ณด ํ™•์ธ -brew info postgresql@15 - -# ์˜์กด์„ฑ ํ™•์ธ -brew deps --tree postgresql@15 - -# ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅํ•œ ํŒจํ‚ค์ง€ ํ™•์ธ -brew outdated -``` - -### ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์šฐ -```bash -# ์ผ์ผ ๊ฐœ๋ฐœ ์‹œ์ž‘ ๋ฃจํ‹ด -cd /Users/hyungi/news-project -source venv/bin/activate -brew services start postgresql@15 redis elasticsearch - -# ์ผ์ผ ๊ฐœ๋ฐœ ์ข…๋ฃŒ ๋ฃจํ‹ด -deactivate -brew services stop elasticsearch # ๋ฉ”๋ชจ๋ฆฌ ์ ˆ์•ฝ์„ ์œ„ํ•ด -``` - -### ๋ฐฑ์—… ๋ฐ ๋ณต์› -```bash -# PostgreSQL ๋ฐฑ์—… -pg_dump industrial_info > backup.sql - -# PostgreSQL ๋ณต์› -psql industrial_info < backup.sql - -# ์„ค์ • ํŒŒ์ผ ๋ฐฑ์—… -cp ~/.zshrc ~/.zshrc.backup -cp .env .env.backup -``` - ---- - -์ด ๊ฐ€์ด๋“œ๋ฅผ ๋”ฐ๋ผํ•˜๋ฉด macOS์—์„œ Homebrew๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์™„์ „ํ•œ ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ๋‹จ๊ณ„๋ณ„๋กœ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฌธ์ œ ํ•ด๊ฒฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์„ธ์š”. diff --git a/SYNOLOGY_SETUP.md b/SYNOLOGY_SETUP.md deleted file mode 100644 index ca5fada..0000000 --- a/SYNOLOGY_SETUP.md +++ /dev/null @@ -1,721 +0,0 @@ -# ๐Ÿ  ์‹œ๋†€๋กœ์ง€ NAS ์„ค์น˜ ๊ฐ€์ด๋“œ - -## ๐Ÿ“‹ ๊ฐœ์š” - -์‹œ๋†€๋กœ์ง€ NAS์—์„œ ์‚ฐ์—… ์ „๋ฌธ ์ •๋ณด ์ˆ˜์ง‘ ์‹œ์Šคํ…œ์„ Docker ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค์น˜ํ•˜๋Š” ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค. 24์‹œ๊ฐ„ ์•ˆ์ •์ ์ธ ์„œ๋น„์Šค ์šด์˜์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ, 480GB SSD ํ™˜๊ฒฝ์— ์ตœ์ ํ™”๋œ ์„ค์ •์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. - ---- - -## ๐Ÿ”ง ์‚ฌ์ „ ์š”๊ตฌ์‚ฌํ•ญ - -### ํ•˜๋“œ์›จ์–ด ์š”๊ตฌ์‚ฌํ•ญ -- **์‹œ๋†€๋กœ์ง€ NAS**: DS220+, DS720+, DS920+ ์ด์ƒ (Docker ์ง€์› ๋ชจ๋ธ) -- **๋ฉ”๋ชจ๋ฆฌ**: 4GB ์ด์ƒ (8GB ๊ถŒ์žฅ) -- **์ €์žฅ๊ณต๊ฐ„**: 480GB SSD (์ถฉ๋ถ„ํ•จ) -- **๋„คํŠธ์›Œํฌ**: ๊ธฐ๊ฐ€๋น„ํŠธ ์ด๋”๋„ท - -### ์†Œํ”„ํŠธ์›จ์–ด ์š”๊ตฌ์‚ฌํ•ญ -- **DSM**: 7.0 ์ด์ƒ -- **Docker**: Container Manager ํŒจํ‚ค์ง€ -- **Git Server**: Git ์ €์žฅ์†Œ ๊ด€๋ฆฌ์šฉ (์„ ํƒ์‚ฌํ•ญ) - ---- - -## ๐Ÿณ 1๋‹จ๊ณ„: Docker ํ™˜๊ฒฝ ์„ค์ • - -### Container Manager ์„ค์น˜ -``` -1. ํŒจํ‚ค์ง€ ์„ผํ„ฐ โ†’ Container Manager ๊ฒ€์ƒ‰ ๋ฐ ์„ค์น˜ -2. Container Manager ์‹คํ–‰ -3. ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ํƒญ์—์„œ ํ•„์š”ํ•œ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ์ค€๋น„ -``` - -### ํ•„์š”ํ•œ Docker ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ -```bash -# SSH๋กœ NAS ์ ‘์† ํ›„ ์‹คํ–‰ -docker pull python:3.11-slim -docker pull postgres:15-alpine -docker pull redis:7-alpine -docker pull elasticsearch:8.11.0 -docker pull nginx:alpine -``` - -### ๋ณผ๋ฅจ ๋ฐ ๋„คํŠธ์›Œํฌ ์„ค์ • -```bash -# ์ „์šฉ ๋„คํŠธ์›Œํฌ ์ƒ์„ฑ -docker network create industrial-net - -# ๋ฐ์ดํ„ฐ ๋ณผ๋ฅจ ์ƒ์„ฑ -docker volume create postgres-data -docker volume create elasticsearch-data -docker volume create redis-data -docker volume create app-logs -``` - ---- - -## ๐Ÿ“ 2๋‹จ๊ณ„: ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ ์„ค์ • - -### NAS ๋‚ด ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ -```bash -# SSH ์ ‘์† ํ›„ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ -mkdir -p /volume1/docker/industrial-info/{ - app, - data/{postgres,elasticsearch,redis,logs}, - config, - backup -} - -# ๊ถŒํ•œ ์„ค์ • -chown -R 1000:1000 /volume1/docker/industrial-info -``` - -### ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ -``` -/volume1/docker/industrial-info/ -โ”œโ”€โ”€ app/ # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ -โ”œโ”€โ”€ data/ # ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ -โ”‚ โ”œโ”€โ”€ postgres/ # PostgreSQL ๋ฐ์ดํ„ฐ -โ”‚ โ”œโ”€โ”€ elasticsearch/ # Elasticsearch ๋ฐ์ดํ„ฐ -โ”‚ โ”œโ”€โ”€ redis/ # Redis ๋ฐ์ดํ„ฐ -โ”‚ โ””โ”€โ”€ logs/ # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ -โ”œโ”€โ”€ config/ # ์„ค์ • ํŒŒ์ผ๋“ค -โ””โ”€โ”€ backup/ # ๋ฐฑ์—… ํŒŒ์ผ๋“ค -``` - ---- - -## ๐Ÿ˜ 3๋‹จ๊ณ„: PostgreSQL ์„ค์ • - -### PostgreSQL ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ -```yaml -# docker-compose.yml์˜ PostgreSQL ๋ถ€๋ถ„ -version: '3.8' -services: - postgres: - image: postgres:15-alpine - container_name: industrial-postgres - environment: - POSTGRES_DB: industrial_info - POSTGRES_USER: industrial_user - POSTGRES_PASSWORD: secure_password_here - POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C" - volumes: - - /volume1/docker/industrial-info/data/postgres:/var/lib/postgresql/data - - /volume1/docker/industrial-info/config/postgres.conf:/etc/postgresql/postgresql.conf - ports: - - "5432:5432" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 1G - reservations: - memory: 512M -``` - -### PostgreSQL ์ตœ์ ํ™” ์„ค์ • -```bash -# /volume1/docker/industrial-info/config/postgres.conf ์ƒ์„ฑ -cat > /volume1/docker/industrial-info/config/postgres.conf << EOF -# ์‹œ๋†€๋กœ์ง€ NAS ์ตœ์ ํ™” ์„ค์ • -shared_buffers = 256MB -effective_cache_size = 1GB -maintenance_work_mem = 64MB -checkpoint_completion_target = 0.9 -wal_buffers = 16MB -default_statistics_target = 100 -random_page_cost = 1.1 -effective_io_concurrency = 200 - -# ๋กœ๊ทธ ์„ค์ • -log_destination = 'stderr' -logging_collector = on -log_directory = '/var/log/postgresql' -log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' -log_rotation_age = 1d -log_rotation_size = 100MB -EOF -``` - ---- - -## ๐Ÿ” 4๋‹จ๊ณ„: Elasticsearch ์„ค์ • - -### Elasticsearch ์ปจํ…Œ์ด๋„ˆ (๊ฒฝ๋Ÿ‰ํ™” ๋ฒ„์ „) -```yaml -# docker-compose.yml์˜ Elasticsearch ๋ถ€๋ถ„ - elasticsearch: - image: elasticsearch:8.11.0 - container_name: industrial-elasticsearch - environment: - - discovery.type=single-node - - "ES_JAVA_OPTS=-Xms512m -Xmx1g" # NAS ๋ฉ”๋ชจ๋ฆฌ ๊ณ ๋ ค - - xpack.security.enabled=false - - xpack.security.enrollment.enabled=false - volumes: - - /volume1/docker/industrial-info/data/elasticsearch:/usr/share/elasticsearch/data - ports: - - "9200:9200" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 1.5G - reservations: - memory: 1G - ulimits: - memlock: - soft: -1 - hard: -1 -``` - -### Elasticsearch ํ•œ๊ตญ์–ด ๋ถ„์„๊ธฐ ์„ค์ • -```bash -# ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ ํ›„ nori ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜ -docker exec industrial-elasticsearch elasticsearch-plugin install analysis-nori -docker restart industrial-elasticsearch -``` - ---- - -## ๐Ÿ”ด 5๋‹จ๊ณ„: Redis ์„ค์ • - -### Redis ์ปจํ…Œ์ด๋„ˆ -```yaml -# docker-compose.yml์˜ Redis ๋ถ€๋ถ„ - redis: - image: redis:7-alpine - container_name: industrial-redis - command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru - volumes: - - /volume1/docker/industrial-info/data/redis:/data - ports: - - "6379:6379" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 512M - reservations: - memory: 256M -``` - ---- - -## ๐Ÿ 6๋‹จ๊ณ„: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค์ • - -### ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ Dockerfile -```dockerfile -# /volume1/docker/industrial-info/app/Dockerfile -FROM python:3.11-slim - -WORKDIR /app - -# ์‹œ์Šคํ…œ ํŒจํ‚ค์ง€ ์„ค์น˜ -RUN apt-get update && apt-get install -y \ - gcc \ - g++ \ - curl \ - && rm -rf /var/lib/apt/lists/* - -# Python ์˜์กด์„ฑ ์„ค์น˜ -COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt - -# ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ ๋ณต์‚ฌ -COPY . . - -# ํฌํŠธ ๋…ธ์ถœ -EXPOSE 8000 - -# ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ -CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] -``` - -### ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…Œ์ด๋„ˆ -```yaml -# docker-compose.yml์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€๋ถ„ - app: - build: ./app - container_name: industrial-app - environment: - - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info - - REDIS_URL=redis://redis:6379/0 - - ELASTICSEARCH_URL=http://elasticsearch:9200 - volumes: - - /volume1/docker/industrial-info/app:/app - - /volume1/docker/industrial-info/data/logs:/app/logs - ports: - - "8000:8000" - networks: - - industrial-net - depends_on: - - postgres - - redis - - elasticsearch - restart: unless-stopped - deploy: - resources: - limits: - memory: 1G - reservations: - memory: 512M -``` - ---- - -## ๐ŸŒ 7๋‹จ๊ณ„: Nginx ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ - -### Nginx ์„ค์ • -```yaml -# docker-compose.yml์˜ Nginx ๋ถ€๋ถ„ - nginx: - image: nginx:alpine - container_name: industrial-nginx - volumes: - - /volume1/docker/industrial-info/config/nginx.conf:/etc/nginx/nginx.conf - - /volume1/docker/industrial-info/data/logs:/var/log/nginx - ports: - - "80:80" - - "443:443" - networks: - - industrial-net - depends_on: - - app - restart: unless-stopped -``` - -### Nginx ์„ค์ • ํŒŒ์ผ -```nginx -# /volume1/docker/industrial-info/config/nginx.conf -events { - worker_connections 1024; -} - -http { - upstream app { - server app:8000; - } - - server { - listen 80; - server_name _; - - client_max_body_size 100M; - - location / { - proxy_pass http://app; - 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; - } - - location /api/ { - proxy_pass http://app; - 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; - } - } -} -``` - ---- - -## ๐Ÿ“ฆ 8๋‹จ๊ณ„: ํ†ตํ•ฉ Docker Compose - -### ์™„์ „ํ•œ docker-compose.yml -```yaml -# /volume1/docker/industrial-info/docker-compose.yml -version: '3.8' - -networks: - industrial-net: - driver: bridge - -services: - postgres: - image: postgres:15-alpine - container_name: industrial-postgres - environment: - POSTGRES_DB: industrial_info - POSTGRES_USER: industrial_user - POSTGRES_PASSWORD: secure_password_here - POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C" - volumes: - - /volume1/docker/industrial-info/data/postgres:/var/lib/postgresql/data - ports: - - "5432:5432" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 1G - - redis: - image: redis:7-alpine - container_name: industrial-redis - command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru - volumes: - - /volume1/docker/industrial-info/data/redis:/data - ports: - - "6379:6379" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 512M - - elasticsearch: - image: elasticsearch:8.11.0 - container_name: industrial-elasticsearch - environment: - - discovery.type=single-node - - "ES_JAVA_OPTS=-Xms512m -Xmx1g" - - xpack.security.enabled=false - - xpack.security.enrollment.enabled=false - volumes: - - /volume1/docker/industrial-info/data/elasticsearch:/usr/share/elasticsearch/data - ports: - - "9200:9200" - networks: - - industrial-net - restart: unless-stopped - deploy: - resources: - limits: - memory: 1.5G - ulimits: - memlock: - soft: -1 - hard: -1 - - app: - build: ./app - container_name: industrial-app - environment: - - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info - - REDIS_URL=redis://redis:6379/0 - - ELASTICSEARCH_URL=http://elasticsearch:9200 - - PYTHONPATH=/app - volumes: - - /volume1/docker/industrial-info/app:/app - - /volume1/docker/industrial-info/data/logs:/app/logs - ports: - - "8000:8000" - networks: - - industrial-net - depends_on: - - postgres - - redis - - elasticsearch - restart: unless-stopped - deploy: - resources: - limits: - memory: 1G - - nginx: - image: nginx:alpine - container_name: industrial-nginx - volumes: - - /volume1/docker/industrial-info/config/nginx.conf:/etc/nginx/nginx.conf - - /volume1/docker/industrial-info/data/logs:/var/log/nginx - ports: - - "80:80" - networks: - - industrial-net - depends_on: - - app - restart: unless-stopped - - # ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ์›Œ์ปค (Celery) - worker: - build: ./app - container_name: industrial-worker - command: celery -A main.celery worker --loglevel=info - environment: - - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info - - REDIS_URL=redis://redis:6379/0 - - ELASTICSEARCH_URL=http://elasticsearch:9200 - volumes: - - /volume1/docker/industrial-info/app:/app - - /volume1/docker/industrial-info/data/logs:/app/logs - networks: - - industrial-net - depends_on: - - postgres - - redis - - elasticsearch - restart: unless-stopped - deploy: - resources: - limits: - memory: 512M - - # ์Šค์ผ€์ค„๋Ÿฌ (Celery Beat) - scheduler: - build: ./app - container_name: industrial-scheduler - command: celery -A main.celery beat --loglevel=info - environment: - - DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info - - REDIS_URL=redis://redis:6379/0 - - ELASTICSEARCH_URL=http://elasticsearch:9200 - volumes: - - /volume1/docker/industrial-info/app:/app - - /volume1/docker/industrial-info/data/logs:/app/logs - networks: - - industrial-net - depends_on: - - postgres - - redis - - elasticsearch - restart: unless-stopped - deploy: - resources: - limits: - memory: 256M -``` - ---- - -## ๐Ÿš€ 9๋‹จ๊ณ„: ๋ฐฐํฌ ๋ฐ ์‹คํ–‰ - -### ์‹œ์Šคํ…œ ์‹คํ–‰ -```bash -# ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™ -cd /volume1/docker/industrial-info - -# ์ปจํ…Œ์ด๋„ˆ ๋นŒ๋“œ ๋ฐ ์‹คํ–‰ -docker-compose up --build -d - -# ๋กœ๊ทธ ํ™•์ธ -docker-compose logs -f - -# ์„œ๋น„์Šค ์ƒํƒœ ํ™•์ธ -docker-compose ps -``` - -### ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ดˆ๊ธฐํ™” -```bash -# ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹คํ–‰ -docker exec industrial-app python manage.py migrate - -# ์Šˆํผ์œ ์ € ์ƒ์„ฑ -docker exec -it industrial-app python manage.py createsuperuser -``` - ---- - -## ๐Ÿ“Š 10๋‹จ๊ณ„: ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ์ตœ์ ํ™” - -### ๋ฆฌ์†Œ์Šค ๋ชจ๋‹ˆํ„ฐ๋ง -```bash -# ์ปจํ…Œ์ด๋„ˆ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ -docker stats - -# ๋””์Šคํฌ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ -df -h /volume1 - -# ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ -free -h -``` - -### ๋กœ๊ทธ ๊ด€๋ฆฌ -```bash -# ๋กœ๊ทธ ๋กœํ…Œ์ด์…˜ ์„ค์ • (crontab) -# ๋งค์ผ ์ž์ •์— ๋กœ๊ทธ ์••์ถ• ๋ฐ ์ •๋ฆฌ -0 0 * * * find /volume1/docker/industrial-info/data/logs -name "*.log" -mtime +7 -exec gzip {} \; -0 0 * * * find /volume1/docker/industrial-info/data/logs -name "*.gz" -mtime +30 -delete -``` - -### ์„ฑ๋Šฅ ์ตœ์ ํ™” ์„ค์ • -```bash -# ์‹œ๋†€๋กœ์ง€ NAS ์ตœ์ ํ™” -echo 'vm.swappiness=10' >> /etc/sysctl.conf -echo 'vm.vfs_cache_pressure=50' >> /etc/sysctl.conf - -# Docker ๋กœ๊ทธ ํฌ๊ธฐ ์ œํ•œ -cat > /etc/docker/daemon.json << EOF -{ - "log-driver": "json-file", - "log-opts": { - "max-size": "10m", - "max-file": "3" - } -} -EOF -``` - ---- - -## ๐Ÿ”„ 11๋‹จ๊ณ„: ๋ฐฑ์—… ๋ฐ ๋ณต์› - -### ์ž๋™ ๋ฐฑ์—… ์Šคํฌ๋ฆฝํŠธ -```bash -# /volume1/docker/industrial-info/backup/backup.sh -#!/bin/bash - -BACKUP_DIR="/volume1/docker/industrial-info/backup" -DATE=$(date +%Y%m%d_%H%M%S) - -# PostgreSQL ๋ฐฑ์—… -docker exec industrial-postgres pg_dump -U industrial_user industrial_info > $BACKUP_DIR/postgres_$DATE.sql - -# Elasticsearch ๋ฐฑ์—… (์ธ๋ฑ์Šค ์„ค์ •๋งŒ) -curl -X GET "localhost:9200/_cat/indices?v" > $BACKUP_DIR/elasticsearch_indices_$DATE.txt - -# ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ ๋ฐฑ์—… -tar -czf $BACKUP_DIR/app_$DATE.tar.gz /volume1/docker/industrial-info/app - -# 7์ผ ์ด์ƒ ๋œ ๋ฐฑ์—… ํŒŒ์ผ ์‚ญ์ œ -find $BACKUP_DIR -name "*.sql" -mtime +7 -delete -find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete - -echo "Backup completed: $DATE" -``` - -### ๋ฐฑ์—… ์Šค์ผ€์ค„ ์„ค์ • -```bash -# crontab ์„ค์ • -# ๋งค์ผ ์ƒˆ๋ฒฝ 2์‹œ์— ๋ฐฑ์—… ์‹คํ–‰ -0 2 * * * /volume1/docker/industrial-info/backup/backup.sh >> /volume1/docker/industrial-info/data/logs/backup.log 2>&1 -``` - ---- - -## ๐ŸŒ 12๋‹จ๊ณ„: ์™ธ๋ถ€ ์ ‘๊ทผ ์„ค์ • - -### ์‹œ๋†€๋กœ์ง€ ๋ฐฉํ™”๋ฒฝ ์„ค์ • -``` -์ œ์–ดํŒ โ†’ ๋ณด์•ˆ โ†’ ๋ฐฉํ™”๋ฒฝ โ†’ ๊ทœ์น™ ํŽธ์ง‘ -- ํฌํŠธ 80 (HTTP) ํ—ˆ์šฉ -- ํฌํŠธ 443 (HTTPS) ํ—ˆ์šฉ (SSL ์ธ์ฆ์„œ ์„ค์ • ์‹œ) -- ํฌํŠธ 8000 (๊ฐœ๋ฐœ์šฉ, ์„ ํƒ์‚ฌํ•ญ) -``` - -### DDNS ์„ค์ • -``` -์ œ์–ดํŒ โ†’ ์™ธ๋ถ€ ์•ก์„ธ์Šค โ†’ DDNS -- Synology DDNS ์„œ๋น„์Šค ํ™œ์šฉ -- ๋˜๋Š” ์™ธ๋ถ€ DDNS ์„œ๋น„์Šค ์—ฐ๋™ -``` - -### SSL ์ธ์ฆ์„œ ์„ค์ • -``` -์ œ์–ดํŒ โ†’ ๋ณด์•ˆ โ†’ ์ธ์ฆ์„œ -- Let's Encrypt ๋ฌด๋ฃŒ ์ธ์ฆ์„œ ๋ฐœ๊ธ‰ -- ์ž๋™ ๊ฐฑ์‹  ์„ค์ • -``` - ---- - -## ๐Ÿšจ ๋ฌธ์ œ ํ•ด๊ฒฐ - -### ์ผ๋ฐ˜์ ์ธ ๋ฌธ์ œ๋“ค - -#### 1. ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ -```bash -# Elasticsearch ๋ฉ”๋ชจ๋ฆฌ ์ค„์ด๊ธฐ -# docker-compose.yml์—์„œ ES_JAVA_OPTS ์ˆ˜์ • -- "ES_JAVA_OPTS=-Xms256m -Xmx512m" - -# ๋ถˆํ•„์š”ํ•œ ์ปจํ…Œ์ด๋„ˆ ์ค‘์ง€ -docker-compose stop worker scheduler -``` - -#### 2. ๋””์Šคํฌ ๊ณต๊ฐ„ ๋ถ€์กฑ -```bash -# Docker ์ด๋ฏธ์ง€ ์ •๋ฆฌ -docker system prune -a - -# ๋กœ๊ทธ ํŒŒ์ผ ์ •๋ฆฌ -docker-compose exec app find /app/logs -name "*.log" -mtime +3 -delete - -# ๋ฐฑ์—… ํŒŒ์ผ ์ •๋ฆฌ -find /volume1/docker/industrial-info/backup -mtime +30 -delete -``` - -#### 3. ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ๋ฌธ์ œ -```bash -# ๋„คํŠธ์›Œํฌ ์žฌ์ƒ์„ฑ -docker network rm industrial-net -docker network create industrial-net - -# ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘ -docker-compose restart -``` - -### ์„ฑ๋Šฅ ํŠœ๋‹ - -#### SSD ์ตœ์ ํ™” -```bash -# SSD ์ˆ˜๋ช… ์—ฐ์žฅ์„ ์œ„ํ•œ ์„ค์ • -echo 'deadline' > /sys/block/sda/queue/scheduler -echo '1' > /sys/block/sda/queue/iosched/fifo_batch -``` - -#### ๋„คํŠธ์›Œํฌ ์ตœ์ ํ™” -```bash -# TCP ๋ฒ„ํผ ํฌ๊ธฐ ์กฐ์ • -echo 'net.core.rmem_max = 16777216' >> /etc/sysctl.conf -echo 'net.core.wmem_max = 16777216' >> /etc/sysctl.conf -``` - ---- - -## ๐Ÿ“ˆ ์‹œ๋†€๋กœ์ง€ vs Mac ๋น„๊ต - -### ์‹œ๋†€๋กœ์ง€ NAS ์žฅ์  -- โœ… **24์‹œ๊ฐ„ ์•ˆ์ • ์šด์˜**: ์ „๋ ฅ ํšจ์œจ์ , ์ €์†Œ์Œ -- โœ… **์ž๋™ ๋ฐฑ์—…**: RAID ๊ตฌ์„ฑ, ์Šค๋ƒ…์ƒท ๊ธฐ๋Šฅ -- โœ… **์›๊ฒฉ ์ ‘๊ทผ**: DDNS, VPN ์ง€์› -- โœ… **๋น„์šฉ ํšจ์œจ**: ์ „๋ ฅ๋น„ ์ ˆ์•ฝ, ๋ณ„๋„ ์„œ๋ฒ„ ๋ถˆํ•„์š” -- โœ… **ํ™•์žฅ์„ฑ**: ํŒจํ‚ค์ง€ ์„ผํ„ฐ, Docker ์ง€์› - -### Mac ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์žฅ์  -- โœ… **๊ฐœ๋ฐœ ํŽธ์˜์„ฑ**: ๋„ค์ดํ‹ฐ๋ธŒ ๋„๊ตฌ, IDE ์ง€์› -- โœ… **์„ฑ๋Šฅ**: ๋” ๋น ๋ฅธ CPU, ๋ฉ”๋ชจ๋ฆฌ -- โœ… **๋””๋ฒ„๊น…**: ์ง์ ‘์ ์ธ ๋กœ๊ทธ ์ ‘๊ทผ -- โœ… **์œ ์—ฐ์„ฑ**: ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ ์šฉ์ด - -### ๊ถŒ์žฅ ์‚ฌ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค -``` -๊ฐœ๋ฐœ ๋‹จ๊ณ„: Mac (HOMEBREW_SETUP.md) - โ†“ -ํ…Œ์ŠคํŠธ/์Šคํ…Œ์ด์ง•: ์‹œ๋†€๋กœ์ง€ NAS (ํ˜„์žฌ ๋ฌธ์„œ) - โ†“ -ํ”„๋กœ๋•์…˜: ํด๋ผ์šฐ๋“œ ๋˜๋Š” ์ „์šฉ ์„œ๋ฒ„ -``` - ---- - -## ๐ŸŽฏ ๊ฒฐ๋ก  - -์‹œ๋†€๋กœ์ง€ NAS๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ์ตœ์ ์ž…๋‹ˆ๋‹ค: - -1. **24์‹œ๊ฐ„ ์„œ๋น„์Šค ์šด์˜**์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ -2. **์ „๋ ฅ ํšจ์œจ์„ฑ**์„ ์ค‘์‹œํ•˜๋Š” ๊ฒฝ์šฐ -3. **์ž๋™ ๋ฐฑ์—… ๋ฐ ๋ฐ์ดํ„ฐ ๋ณดํ˜ธ**๊ฐ€ ์ค‘์š”ํ•œ ๊ฒฝ์šฐ -4. **์›๊ฒฉ ์ ‘๊ทผ**์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ -5. **๋น„์šฉ ์ ˆ์•ฝ**์„ ์›ํ•˜๋Š” ๊ฒฝ์šฐ - -480GB SSD๋Š” ์ด ํ”„๋กœ์ ํŠธ์— ์ถฉ๋ถ„ํ•˜๋ฉฐ, ์ ์ ˆํ•œ ๋กœ๊ทธ ๊ด€๋ฆฌ์™€ ๋ฐฑ์—… ์ •์ฑ…์œผ๋กœ ์žฅ๊ธฐ๊ฐ„ ์•ˆ์ •์ ์ธ ์šด์˜์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. - ---- - -**์‹œ๋†€๋กœ์ง€ NAS๋กœ ๋” ์•ˆ์ •์ ์ด๊ณ  ํšจ์œจ์ ์ธ ์‚ฐ์—… ์ •๋ณด ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•ด๋ณด์„ธ์š”!** ๐Ÿ ๐Ÿš€ diff --git a/TECH_STACK.md b/TECH_STACK.md deleted file mode 100644 index 2f02a65..0000000 --- a/TECH_STACK.md +++ /dev/null @@ -1,285 +0,0 @@ -# ๐Ÿ› ๏ธ ๊ธฐ์ˆ  ์Šคํƒ (Tech Stack) - -## ๐Ÿ“‹ ๊ฐœ์š” - -์‚ฐ์—… ์ „๋ฌธ ์ •๋ณด ์ˆ˜์ง‘ ์‹œ์Šคํ…œ์˜ ๊ธฐ์ˆ  ์Šคํƒ์„ ์ •๋ฆฌํ•œ ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค. ๊ฐ ๊ธฐ์ˆ ์˜ ์„ ํƒ ์ด์œ ์™€ ์—ญํ• ์„ ํฌํ•จํ•˜์—ฌ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. - ---- - -## ๐Ÿ–ฅ๏ธ Backend - -### ํ•ต์‹ฌ ํ”„๋ ˆ์ž„์›Œํฌ -- **Python 3.11+** - - ์„ ํƒ ์ด์œ : ํ’๋ถ€ํ•œ NLP ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ƒํƒœ๊ณ„, ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์ตœ์ ํ™” - - ์—ญํ• : ๋ฉ”์ธ ๋ฐฑ์—”๋“œ ์–ธ์–ด - -- **FastAPI** - - ์„ ํƒ ์ด์œ : ๊ณ ์„ฑ๋Šฅ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ, ์ž๋™ API ๋ฌธ์„œ ์ƒ์„ฑ, ํƒ€์ž… ํžŒํŒ… ์ง€์› - - ์—ญํ• : REST API ์„œ๋ฒ„, ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฑ์—”๋“œ - -### ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค & ๊ฒ€์ƒ‰ -- **PostgreSQL** - - ์„ ํƒ ์ด์œ : ๊ตฌ์กฐํ™”๋œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ €์žฅ, ACID ํŠธ๋žœ์žญ์…˜, JSON ์ง€์› - - ์—ญํ• : ๋ฉ”์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ์‚ฌ์šฉ์ž ์ •๋ณด, ๋ฌธ์„œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ - -- **Elasticsearch** - - ์„ ํƒ ์ด์œ : ์ „๋ฌธ ๊ฒ€์ƒ‰, ๋‹ค์ฐจ์› ํ•„ํ„ฐ๋ง, ์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰ ์„ฑ๋Šฅ - - ์—ญํ• : ๋ฌธ์„œ ๊ฒ€์ƒ‰ ์—”์ง„, ํƒœ๊ทธ ๊ธฐ๋ฐ˜ ํ•„ํ„ฐ๋ง, ์ „๋ฌธ ๊ฒ€์ƒ‰ - -- **Redis** - - ์„ ํƒ ์ด์œ : ๊ณ ์† ์บ์‹ฑ, ์„ธ์…˜ ๊ด€๋ฆฌ, ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ - - ์—ญํ• : ์บ์‹œ ๋ ˆ์ด์–ด, ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์บ์‹ฑ, ํŠธ๋ Œ๋”ฉ ๋ฐ์ดํ„ฐ - -### NLP & ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ -- **spaCy** - - ์„ ํƒ ์ด์œ : ์‚ฐ์—…์šฉ NLP, ์ปค์Šคํ…€ ๋ชจ๋ธ ์ง€์›, ํ•œ๊ตญ์–ด ์ง€์› - - ์—ญํ• : ๊ฐœ์ฒด๋ช… ์ธ์‹(NER), ๊ธฐ์ˆ  ์šฉ์–ด ์ถ”์ถœ - -- **Transformers (Hugging Face)** - - ์„ ํƒ ์ด์œ : ์ตœ์‹  ์–ธ์–ด ๋ชจ๋ธ, ์˜๋ฏธ ๊ธฐ๋ฐ˜ ๊ฒ€์ƒ‰ - - ์—ญํ• : ๋ฌธ์„œ ์ž„๋ฒ ๋”ฉ, ์˜๋ฏธ ์œ ์‚ฌ๋„ ๊ณ„์‚ฐ - -- **scikit-learn** - - ์„ ํƒ ์ด์œ : ๋จธ์‹ ๋Ÿฌ๋‹ ํŒŒ์ดํ”„๋ผ์ธ, ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ - - ์—ญํ• : ๋ฌธ์„œ ๋ถ„๋ฅ˜, ํƒœ๊ทธ ์˜ˆ์ธก, ํŠธ๋ Œ๋“œ ๋ถ„์„ - -### ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ & ์Šค์ผ€์ค„๋ง -- **Celery** - - ์„ ํƒ ์ด์œ : ๋ถ„์‚ฐ ํƒœ์Šคํฌ ํ, ์Šค์ผ€์ค„๋ง ์ง€์› - - ์—ญํ• : RSS ์ˆ˜์ง‘, ๋…ผ๋ฌธ ์ฒ˜๋ฆฌ, ๋ฐฐ์น˜ ์ž‘์—… - -- **Redis (Broker)** - - ์„ ํƒ ์ด์œ : Celery ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค, ๊ณ ์„ฑ๋Šฅ - - ์—ญํ• : ํƒœ์Šคํฌ ํ ๋ธŒ๋กœ์ปค - -### ๋ฌธ์„œ ์ฒ˜๋ฆฌ -- **PyPDF2 / pdfplumber** - - ์„ ํƒ ์ด์œ : PDF ํ…์ŠคํŠธ ์ถ”์ถœ, ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํŒŒ์‹ฑ - - ์—ญํ• : ๋…ผ๋ฌธ PDF ์ฒ˜๋ฆฌ, ๊ธฐ์ˆ  ๋ฌธ์„œ ๋ถ„์„ - -- **BeautifulSoup** - - ์„ ํƒ ์ด์œ : HTML ํŒŒ์‹ฑ, ์›น ์Šคํฌ๋ž˜ํ•‘ - - ์—ญํ• : RSS ํ”ผ๋“œ ์ฒ˜๋ฆฌ, ์›น์‚ฌ์ดํŠธ ํฌ๋กค๋ง - -- **Scrapy** - - ์„ ํƒ ์ด์œ : ๋Œ€๊ทœ๋ชจ ์›น ํฌ๋กค๋ง, ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ - - ์—ญํ• : ํ‘œ์ค€ ๊ธฐ๊ด€ ์›น์‚ฌ์ดํŠธ ๋ชจ๋‹ˆํ„ฐ๋ง - ---- - -## ๐ŸŽจ Frontend - -### ํ•ต์‹ฌ ํ”„๋ ˆ์ž„์›Œํฌ -- **React 18** - - ์„ ํƒ ์ด์œ : ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœ, ํ’๋ถ€ํ•œ ์ƒํƒœ๊ณ„ - - ์—ญํ• : ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์ถ• - -- **Next.js 13+** - - ์„ ํƒ ์ด์œ : SSR/SSG ์ง€์›, ์„ฑ๋Šฅ ์ตœ์ ํ™”, ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ… - - ์—ญํ• : React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ - -### UI & ์Šคํƒ€์ผ๋ง -- **Tailwind CSS** - - ์„ ํƒ ์ด์œ : ์œ ํ‹ธ๋ฆฌํ‹ฐ ์šฐ์„ , ๋น ๋ฅธ ๊ฐœ๋ฐœ, ์ผ๊ด€๋œ ๋””์ž์ธ - - ์—ญํ• : CSS ํ”„๋ ˆ์ž„์›Œํฌ, ๋ฐ˜์‘ํ˜• ๋””์ž์ธ - -- **Material-UI (MUI)** - - ์„ ํƒ ์ด์œ : ์ „๋ฌธ์ ์ธ UI ์ปดํฌ๋„ŒํŠธ, ์ ‘๊ทผ์„ฑ ์ง€์› - - ์—ญํ• : ๋ณต์žกํ•œ UI ์ปดํฌ๋„ŒํŠธ (ํ…Œ์ด๋ธ”, ํผ ๋“ฑ) - -### ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™” -- **D3.js** - - ์„ ํƒ ์ด์œ : ๊ณ ๋„๋กœ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ๊ฐ€๋Šฅํ•œ ์‹œ๊ฐํ™” - - ์—ญํ• : ๊ธฐ์ˆ  ๋„คํŠธ์›Œํฌ ๊ทธ๋ž˜ํ”„, ๋ณต์žกํ•œ ์ฐจํŠธ - -- **Chart.js** - - ์„ ํƒ ์ด์œ : ๊ฐ„๋‹จํ•œ ์ฐจํŠธ ์ƒ์„ฑ, React ํ†ตํ•ฉ - - ์—ญํ• : ํŠธ๋ Œ๋“œ ์ฐจํŠธ, ํ†ต๊ณ„ ๊ทธ๋ž˜ํ”„ - -### ๊ฒ€์ƒ‰ & ์ƒํ˜ธ์ž‘์šฉ -- **Algolia InstantSearch** - - ์„ ํƒ ์ด์œ : ์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰, ์ž๋™์™„์„ฑ, ํ•„ํ„ฐ๋ง - - ์—ญํ• : ๊ฒ€์ƒ‰ UI ์ปดํฌ๋„ŒํŠธ - ---- - -## ๐Ÿ”ง ์ „๋ฌธ ๋ถ„์•ผ ๋„๊ตฌ - -### ํ•™์ˆ  ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ -- **arXiv API** - - ์„ ํƒ ์ด์œ : ๋ฌผ๋ฆฌํ•™/๊ณตํ•™ ๋…ผ๋ฌธ ์ ‘๊ทผ - - ์—ญํ• : ์ตœ์‹  ์—ฐ๊ตฌ ๋…ผ๋ฌธ ์ˆ˜์ง‘ - -- **PubMed API** - - ์„ ํƒ ์ด์œ : ์˜ํ•™/๋ณด๊ฑด ๊ด€๋ จ ๋…ผ๋ฌธ - - ์—ญํ• : ์‚ฐ์—…์•ˆ์ „ ์˜ํ•™ ์—ฐ๊ตฌ ์ˆ˜์ง‘ - -- **IEEE Xplore API** - - ์„ ํƒ ์ด์œ : ์ „๊ธฐ/์ „์ž/์ปดํ“จํ„ฐ ๊ณตํ•™ ๋…ผ๋ฌธ - - ์—ญํ• : ๊ธฐ์ˆ  ํ‘œ์ค€ ๋ฐ ์—ฐ๊ตฌ ๋…ผ๋ฌธ ์ˆ˜์ง‘ - -### ํ‘œ์ค€ ๋ชจ๋‹ˆํ„ฐ๋ง -- **ASME ์›น์‚ฌ์ดํŠธ ํฌ๋กค๋Ÿฌ** - - ์„ ํƒ ์ด์œ : ์••๋ ฅ์šฉ๊ธฐ ํ‘œ์ค€ ์—…๋ฐ์ดํŠธ ์ถ”์  - - ์—ญํ• : BPVC ๋“ฑ ํ‘œ์ค€ ๋ณ€๊ฒฝ์‚ฌํ•ญ ๋ชจ๋‹ˆํ„ฐ๋ง - -- **KGS ์›น์‚ฌ์ดํŠธ ํฌ๋กค๋Ÿฌ** - - ์„ ํƒ ์ด์œ : ํ•œ๊ตญ ๊ฐ€์Šค์•ˆ์ „ ๊ธฐ์ค€ ์ถ”์  - - ์—ญํ• : ๊ตญ๋‚ด ์••๋ ฅ์šฉ๊ธฐ ๊ธฐ์ค€ ์—…๋ฐ์ดํŠธ - -- **API ์›น์‚ฌ์ดํŠธ ํฌ๋กค๋Ÿฌ** - - ์„ ํƒ ์ด์œ : ์„์œ /๊ฐ€์Šค ์‚ฐ์—… ํ‘œ์ค€ ์ถ”์  - - ์—ญํ• : API ํ‘œ์ค€ ์—…๋ฐ์ดํŠธ ๋ชจ๋‹ˆํ„ฐ๋ง - -### ์ „๋ฌธ ์šฉ์–ด ์ฒ˜๋ฆฌ -- **์••๋ ฅ์šฉ๊ธฐ ์ „๋ฌธ ์šฉ์–ด ์‚ฌ์ „** - - ์„ ํƒ ์ด์œ : ์ •ํ™•ํ•œ ๊ธฐ์ˆ  ์šฉ์–ด ์ธ์‹ - - ์—ญํ• : NER ๋ชจ๋ธ ํ•™์Šต ๋ฐ์ดํ„ฐ - -- **ํ”Œ๋žœํŠธ ์žฅ๋น„ ๋ถ„๋ฅ˜ ์ฒด๊ณ„** - - ์„ ํƒ ์ด์œ : ์ฒด๊ณ„์ ์ธ ์žฅ๋น„ ๋ถ„๋ฅ˜ - - ์—ญํ• : ํƒœ๊ทธ ์ •๊ทœํ™” ๋ฐ ๋ถ„๋ฅ˜ - -- **์‚ฐ์—…์•ˆ์ „ ์šฉ์–ด ์˜จํ†จ๋กœ์ง€** - - ์„ ํƒ ์ด์œ : ์•ˆ์ „ ๋ถ„์•ผ ์ „๋ฌธ ์šฉ์–ด ์ฒด๊ณ„ํ™” - - ์—ญํ• : ์•ˆ์ „ ๊ด€๋ จ ๋ฌธ์„œ ๋ถ„๋ฅ˜ - ---- - -## ๐Ÿ—๏ธ Infrastructure - -### ์ปจํ…Œ์ด๋„ˆํ™” -- **Docker** - - ์„ ํƒ ์ด์œ : ํ™˜๊ฒฝ ์ผ๊ด€์„ฑ, ๋ฐฐํฌ ๊ฐ„์†Œํ™” - - ์—ญํ• : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…Œ์ด๋„ˆํ™” - -- **Docker Compose** - - ์„ ํƒ ์ด์œ : ๋‹ค์ค‘ ์„œ๋น„์Šค ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ - - ์—ญํ• : ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๊ตฌ์„ฑ - -### ๋ชจ๋‹ˆํ„ฐ๋ง & ๋กœ๊น… -- **Prometheus** - - ์„ ํƒ ์ด์œ : ์‹œ๊ณ„์—ด ๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘, ์•Œ๋ฆผ ์‹œ์Šคํ…œ - - ์—ญํ• : ์‹œ์Šคํ…œ ๋ฉ”ํŠธ๋ฆญ ๋ชจ๋‹ˆํ„ฐ๋ง - -- **Grafana** - - ์„ ํƒ ์ด์œ : ๋ฉ”ํŠธ๋ฆญ ์‹œ๊ฐํ™”, ๋Œ€์‹œ๋ณด๋“œ - - ์—ญํ• : ๋ชจ๋‹ˆํ„ฐ๋ง ๋Œ€์‹œ๋ณด๋“œ - -- **ELK Stack (Elasticsearch, Logstash, Kibana)** - - ์„ ํƒ ์ด์œ : ์ค‘์•™ํ™”๋œ ๋กœ๊ทธ ๊ด€๋ฆฌ, ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅํ•œ ๋กœ๊ทธ - - ์—ญํ• : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ ์ˆ˜์ง‘ ๋ฐ ๋ถ„์„ - -### CI/CD -- **GitHub Actions** - - ์„ ํƒ ์ด์œ : GitHub ํ†ตํ•ฉ, ๋ฌด๋ฃŒ ์‚ฌ์šฉ๋Ÿ‰ - - ์—ญํ• : ์ž๋™ ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌ - -### ์Šคํ† ๋ฆฌ์ง€ -- **MinIO (S3 ํ˜ธํ™˜)** - - ์„ ํƒ ์ด์œ : ์˜คํ”ˆ์†Œ์Šค ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€, S3 ํ˜ธํ™˜์„ฑ - - ์—ญํ• : ๋…ผ๋ฌธ PDF, ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ €์žฅ - ---- - -## ๐Ÿบ macOS ๊ฐœ๋ฐœ ํ™˜๊ฒฝ (Homebrew ๊ธฐ๋ฐ˜) - -### ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € -- **Homebrew** - - ์„ ํƒ ์ด์œ : macOS ํ‘œ์ค€ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € - - ์—ญํ• : ๊ฐœ๋ฐœ ๋„๊ตฌ ์„ค์น˜ ๋ฐ ๊ด€๋ฆฌ - -### ํ•„์ˆ˜ ๊ฐœ๋ฐœ ๋„๊ตฌ -```bash -# ์–ธ์–ด ๋Ÿฐํƒ€์ž„ -brew install python@3.11 # Python ๋Ÿฐํƒ€์ž„ -brew install node@18 # Node.js ๋Ÿฐํƒ€์ž„ - -# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค -brew install postgresql # PostgreSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค -brew install redis # Redis ์บ์‹œ/๋ธŒ๋กœ์ปค - -# ๊ฒ€์ƒ‰ ์—”์ง„ -brew install elasticsearch # Elasticsearch ๊ฒ€์ƒ‰ ์—”์ง„ - -# ๊ฐœ๋ฐœ ๋„๊ตฌ -brew install git # ๋ฒ„์ „ ๊ด€๋ฆฌ -brew install htop # ์‹œ์Šคํ…œ ๋ชจ๋‹ˆํ„ฐ๋ง - -# GUI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ -brew install --cask docker # Docker Desktop -brew install --cask visual-studio-code # IDE -``` - -### ์„œ๋น„์Šค ๊ด€๋ฆฌ -```bash -# ์„œ๋น„์Šค ์‹œ์ž‘ -brew services start postgresql -brew services start redis -brew services start elasticsearch - -# ์„œ๋น„์Šค ์ƒํƒœ ํ™•์ธ -brew services list -``` - ---- - -## ๐Ÿ“Š ์„ฑ๋Šฅ ์ตœ์ ํ™” ์ „๋žต - -### ์บ์‹ฑ ๊ณ„์ธต -``` -L1: Redis (์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ, ํŠธ๋ Œ๋”ฉ ํƒœ๊ทธ) -L2: PostgreSQL (๊ตฌ์กฐํ™”๋œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ, ์‚ฌ์šฉ์ž ํ”„๋กœํ•„) -L3: Elasticsearch (์ „๋ฌธ ๊ฒ€์ƒ‰, ํƒœ๊ทธ ์ธ๋ฑ์Šค) -L4: MinIO/S3 (์›๋ณธ ๋ฌธ์„œ, ๋…ผ๋ฌธ PDF) -``` - -### ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™” (Mac mini 8GB ๊ธฐ์ค€) -```bash -# Elasticsearch JVM ์„ค์ • -export ELASTICSEARCH_JAVA_OPTS="-Xms512m -Xmx1g" - -# Redis ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ -export REDIS_MAXMEMORY="256mb" - -# Python ํ”„๋กœ์„ธ์Šค ์ตœ์ ํ™” -export PYTHONOPTIMIZE=1 -``` - -### ๊ฒ€์ƒ‰ ์„ฑ๋Šฅ ์ตœ์ ํ™” -- **์‚ฌ์ „ ๊ณ„์‚ฐ**: ์ž์ฃผ ๊ฒ€์ƒ‰๋˜๋Š” ์กฐํ•ฉ ์บ์‹ฑ -- **์ธ๋ฑ์Šค ์ตœ์ ํ™”**: ์ „๋ฌธ ์šฉ์–ด ๊ธฐ๋ฐ˜ ์—ญ์ƒ‰์ธ -- **๋ฒกํ„ฐ ๊ฒ€์ƒ‰**: BERT ๊ธฐ๋ฐ˜ ์˜๋ฏธ ๊ฒ€์ƒ‰ -- **์ง€์—ญ๋ณ„ ์ƒค๋”ฉ**: ๋ฐ์ดํ„ฐ ๋ถ„์‚ฐ ์ €์žฅ - ---- - -## ๐Ÿ”„ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ - -### ์ˆ˜์ง‘ โ†’ ์ฒ˜๋ฆฌ โ†’ ์ €์žฅ โ†’ ๊ฒ€์ƒ‰ -``` -RSS/API ์ˆ˜์ง‘ โ†’ NLP ํƒœ๊ทธ ์ถ”์ถœ โ†’ PostgreSQL ์ €์žฅ โ†’ Elasticsearch ์ธ๋ฑ์‹ฑ โ†’ Redis ์บ์‹ฑ -``` - -### ์‹ค์‹œ๊ฐ„ ์ฒ˜๋ฆฌ -- **RSS ๋ชจ๋‹ˆํ„ฐ๋ง**: 5๋ถ„๋งˆ๋‹ค ์ƒˆ ํ”ผ๋“œ ํ™•์ธ -- **๋…ผ๋ฌธ ๋™๊ธฐํ™”**: ์ผ์ผ 1ํšŒ ํ•™์ˆ  DB ์Šค์บ” -- **ํ‘œ์ค€ ์—…๋ฐ์ดํŠธ**: ์ฃผ๊ฐ„ ๊ณต์‹ ์‚ฌ์ดํŠธ ๋ชจ๋‹ˆํ„ฐ๋ง - ---- - -## ๐Ÿš€ ํ™•์žฅ์„ฑ ๊ณ ๋ ค์‚ฌํ•ญ - -### ์ˆ˜ํ‰ ํ™•์žฅ -- **๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค**: ๊ธฐ๋Šฅ๋ณ„ ์„œ๋น„์Šค ๋ถ„๋ฆฌ -- **๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ**: ๊ฒ€์ƒ‰ ์„œ๋น„์Šค ๋‹ค์ค‘ ์ธ์Šคํ„ด์Šค -- **๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ƒค๋”ฉ**: ์ง€์—ญ/๋ถ„์•ผ๋ณ„ ๋ฐ์ดํ„ฐ ๋ถ„์‚ฐ - -### ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง -- **๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘**: ์‘๋‹ต ์‹œ๊ฐ„, ์ฒ˜๋ฆฌ๋Ÿ‰, ์—๋Ÿฌ์œจ -- **์•Œ๋ฆผ ์‹œ์Šคํ…œ**: ์ž„๊ณ„๊ฐ’ ์ดˆ๊ณผ ์‹œ ์ž๋™ ์•Œ๋ฆผ -- **์šฉ๋Ÿ‰ ๊ณ„ํš**: ๋ฐ์ดํ„ฐ ์ฆ๊ฐ€์œจ ๊ธฐ๋ฐ˜ ๋ฆฌ์†Œ์Šค ๊ณ„ํš - ---- - -์ด ๊ธฐ์ˆ  ์Šคํƒ์€ ์‚ฐ์—… ์ „๋ฌธ ์ •๋ณด์˜ ํŠน์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ ์„ ํƒ๋˜์—ˆ์œผ๋ฉฐ, macOS ํ™˜๊ฒฝ์—์„œ์˜ ๊ฐœ๋ฐœ ํŽธ์˜์„ฑ๊ณผ ์šด์˜ ์•ˆ์ •์„ฑ์„ ๋ชจ๋‘ ๊ณ ๋ คํ•œ ๊ตฌ์„ฑ์ž…๋‹ˆ๋‹ค.