- Flask Blueprint 아키텍처로 전환 (dashboard, upload, backup, status) - app.py 681줄 95줄로 축소 (86% 감소) - HTML 템플릿 모듈화 (base.html + 기능별 templates) - CSS/JS 파일 분리 (common + 기능별 파일) - 대시보드 기능 추가 (통계, 주간 예보, 방문객 추이) - 파일 업로드 웹 인터페이스 구현 - 백업/복구 관리 UI 구현 - Docker 배포 환경 개선 - .gitignore 업데이트 (uploads, backups, cache 등)
130 lines
3.9 KiB
Docker
130 lines
3.9 KiB
Docker
# Dockerfile - First Garden Static Analysis Service
|
|
# Python 3.11 기반의 가벼운 이미지 사용
|
|
|
|
FROM python:3.11-slim-bullseye
|
|
|
|
# 메타데이터 설정
|
|
LABEL maintainer="First Garden Team"
|
|
LABEL description="First Garden Static Analysis - Data Collection & Visitor Forecasting Service"
|
|
|
|
# 작업 디렉토리 설정
|
|
WORKDIR /app
|
|
|
|
# 타임존 설정
|
|
ENV TZ=Asia/Seoul
|
|
ENV PYTHONUNBUFFERED=1
|
|
ENV PYTHONDONTWRITEBYTECODE=1
|
|
|
|
# 시스템 패키지 업데이트 및 필수 도구 설치
|
|
# mysqldump 및 mysql 클라이언트 추가 (DB 백업/복구 용)
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
gcc \
|
|
g++ \
|
|
build-essential \
|
|
libmysqlclient-dev \
|
|
libssl-dev \
|
|
libffi-dev \
|
|
curl \
|
|
wget \
|
|
git \
|
|
cron \
|
|
mariadb-client \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& apt-get clean
|
|
|
|
# Python 의존성 설치
|
|
COPY requirements.txt ./
|
|
RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \
|
|
pip install --no-cache-dir -r requirements.txt
|
|
|
|
# 앱 코드 복사
|
|
COPY . .
|
|
|
|
# 로그 디렉토리 생성
|
|
RUN mkdir -p /app/logs /app/data /app/output /app/uploads /app/dbbackup && \
|
|
chmod 755 /app/logs /app/data /app/output /app/uploads /app/dbbackup
|
|
|
|
# 크론 작업 설정: 매일 11시 UTC (서울 시간 20시)에 daily_run.py 실행
|
|
RUN echo "0 11 * * * cd /app && python daily_run.py >> /app/logs/daily_run.log 2>&1" > /etc/cron.d/daily-forecast && \
|
|
chmod 0644 /etc/cron.d/daily-forecast && \
|
|
crontab /etc/cron.d/daily-forecast
|
|
|
|
# 헬스체크 스크립트 생성
|
|
RUN cat > /app/healthcheck.sh << 'EOF'
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
# DB 연결 확인
|
|
python -c "
|
|
import sys
|
|
sys.path.insert(0, '/app')
|
|
from conf import db
|
|
try:
|
|
session = db.get_session()
|
|
session.execute('SELECT 1')
|
|
session.close()
|
|
print('DB Connection OK')
|
|
except Exception as e:
|
|
print(f'DB Connection Failed: {e}')
|
|
sys.exit(1)
|
|
" && exit 0 || exit 1
|
|
EOF
|
|
chmod +x /app/healthcheck.sh
|
|
|
|
# 컨테이너 시작 스크립트 생성
|
|
# Flask 웹 서버(포트 8889) + 크론 + 파일 감시 서비스 병렬 실행
|
|
RUN cat > /app/docker-entrypoint.sh << 'EOF'
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ========================================="
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting First Garden Static Service"
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ========================================="
|
|
|
|
# 크론 데몬 시작 (백그라운드)
|
|
# 일정 시간에 daily_run.py 자동 실행
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting cron daemon..."
|
|
cron -f > /app/logs/cron.log 2>&1 &
|
|
CRON_PID=$!
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Cron daemon started (PID: $CRON_PID)"
|
|
|
|
# file_watch.py 실행 (백그라운드)
|
|
# 로컬 파일 시스템 감시 및 자동 처리
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting file watch service..."
|
|
cd /app
|
|
python lib/file_watch.py > /app/logs/file_watch.log 2>&1 &
|
|
WATCH_PID=$!
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] File watch service started (PID: $WATCH_PID)"
|
|
|
|
# Flask 웹 서버 시작 (포트 8889)
|
|
# 파일 업로드, DB 백업/복구 API 제공
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Flask file upload server (port 8889)..."
|
|
cd /app
|
|
python -c "from app.app import run_app; run_app()" > /app/logs/flask_app.log 2>&1 &
|
|
FLASK_PID=$!
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Flask server started (PID: $FLASK_PID)"
|
|
|
|
# 신호 처리: 컨테이너 종료 시 모든 하위 프로세스 정리
|
|
trap "
|
|
echo '[$(date +\"%Y-%m-%d %H:%M:%S\")] Shutting down services...'
|
|
kill $CRON_PID $WATCH_PID $FLASK_PID 2>/dev/null || true
|
|
exit 0
|
|
" SIGTERM SIGINT
|
|
|
|
# 프로세스 모니터링
|
|
# 하위 프로세스 상태 확인
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Service monitoring started"
|
|
while true; do
|
|
wait
|
|
done
|
|
EOF
|
|
chmod +x /app/docker-entrypoint.sh
|
|
|
|
# 포트 노출 선언
|
|
# 8889: Flask 파일 업로드 서버
|
|
# 5000: 기타 서비스 포트
|
|
EXPOSE 8889 5000
|
|
|
|
# 엔트리포인트 설정
|
|
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|