jameszokah commited on
Commit
bed415e
·
1 Parent(s): 275b1e7

Refactor Dockerfile and migration scripts: update Dockerfile to use Python slim image, streamline environment variable settings, and enhance permissions handling. Modify migrate.py to improve module path management and error handling, and update run.sh for better directory structure and debugging output.

Browse files
Files changed (3) hide show
  1. Dockerfile +14 -15
  2. scripts/migrate.py +28 -4
  3. scripts/run.sh +17 -56
Dockerfile CHANGED
@@ -1,14 +1,12 @@
1
- # Use Python 3.10 as the base image
2
  FROM python:3.10-slim
3
 
4
  # Set environment variables
5
  ENV PYTHONUNBUFFERED=1 \
6
  PYTHONDONTWRITEBYTECODE=1 \
7
- PIP_NO_CACHE_DIR=1 \
8
- PIP_DISABLE_PIP_VERSION_CHECK=1 \
9
- PYTHONPATH=/app:/app/app
10
 
11
- # Create and set working directory
12
  WORKDIR /app
13
 
14
  # Install system dependencies
@@ -18,28 +16,29 @@ RUN apt-get update && apt-get install -y \
18
  ffmpeg \
19
  && rm -rf /var/lib/apt/lists/*
20
 
21
- # Copy requirements file
22
- COPY requirements.txt .
 
23
 
24
- # Install Python dependencies
 
25
  RUN pip install --no-cache-dir -r requirements.txt
26
 
27
  # Copy application code
28
  COPY . .
29
 
30
- # Create necessary directories and set permissions
31
  RUN mkdir -p /app/storage/audio /app/storage/text /app/storage/temp && \
32
- # Make run script executable before changing ownership
33
- chmod +x /app/scripts/run.sh && \
34
- # Create app user and set ownership
35
- useradd -m -u 1000 app && \
36
- chown -R app:app /app
37
 
38
  # Switch to app user
39
  USER app
40
 
 
 
 
41
  # Expose port
42
  EXPOSE 7860
43
 
44
- # Set the entrypoint
45
  ENTRYPOINT ["/app/scripts/run.sh"]
 
1
+ # Use Python 3.10 slim image
2
  FROM python:3.10-slim
3
 
4
  # Set environment variables
5
  ENV PYTHONUNBUFFERED=1 \
6
  PYTHONDONTWRITEBYTECODE=1 \
7
+ PYTHONPATH="/app:/app/app"
 
 
8
 
9
+ # Set working directory
10
  WORKDIR /app
11
 
12
  # Install system dependencies
 
16
  ffmpeg \
17
  && rm -rf /var/lib/apt/lists/*
18
 
19
+ # Create app user
20
+ RUN useradd -m -u 1000 app && \
21
+ chown -R app:app /app
22
 
23
+ # Copy requirements first to leverage Docker cache
24
+ COPY requirements.txt .
25
  RUN pip install --no-cache-dir -r requirements.txt
26
 
27
  # Copy application code
28
  COPY . .
29
 
30
+ # Create storage directories
31
  RUN mkdir -p /app/storage/audio /app/storage/text /app/storage/temp && \
32
+ chown -R app:app /app/storage
 
 
 
 
33
 
34
  # Switch to app user
35
  USER app
36
 
37
+ # Make run script executable
38
+ RUN chmod +x /app/scripts/run.sh
39
+
40
  # Expose port
41
  EXPOSE 7860
42
 
43
+ # Set entrypoint
44
  ENTRYPOINT ["/app/scripts/run.sh"]
scripts/migrate.py CHANGED
@@ -5,11 +5,31 @@ import logging
5
  from alembic.config import Config
6
  from alembic import command
7
 
8
- # Add the project root to the Python path
9
- project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
10
- sys.path.insert(0, project_root)
 
 
 
 
11
 
12
- from app.models.database import Base
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  # Configure logging
15
  logging.basicConfig(
@@ -26,6 +46,10 @@ def run_migrations():
26
  # Get the project root directory (one level up)
27
  project_root = os.path.dirname(current_dir)
28
 
 
 
 
 
29
  # Create Alembic configuration
30
  alembic_cfg = Config(os.path.join(project_root, "alembic.ini"))
31
 
 
5
  from alembic.config import Config
6
  from alembic import command
7
 
8
+ # Add potential module paths to Python path
9
+ possible_paths = [
10
+ # Docker path
11
+ "/app",
12
+ # Local development path
13
+ os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
14
+ ]
15
 
16
+ # Add paths to Python path
17
+ for path in possible_paths:
18
+ if path not in sys.path and os.path.exists(path):
19
+ sys.path.insert(0, path)
20
+
21
+ try:
22
+ from app.models.database import Base
23
+ except ImportError as e:
24
+ print(f"Error importing Base: {e}")
25
+ print("Current sys.path:", sys.path)
26
+ print("Contents of /app directory:")
27
+ if os.path.exists("/app"):
28
+ print(os.listdir("/app"))
29
+ print("Contents of app directory:")
30
+ if os.path.exists("app"):
31
+ print(os.listdir("app"))
32
+ raise
33
 
34
  # Configure logging
35
  logging.basicConfig(
 
46
  # Get the project root directory (one level up)
47
  project_root = os.path.dirname(current_dir)
48
 
49
+ # In Docker, the project root is /app
50
+ if os.path.exists("/app/alembic.ini"):
51
+ project_root = "/app"
52
+
53
  # Create Alembic configuration
54
  alembic_cfg = Config(os.path.join(project_root, "alembic.ini"))
55
 
scripts/run.sh CHANGED
@@ -1,66 +1,27 @@
1
  #!/bin/bash
2
- set -e
3
 
4
- # Initialize environment variables with defaults if not set
5
- export PORT=${PORT:-7860}
6
- export HOST=${HOST:-"0.0.0.0"}
7
- export WORKERS=${WORKERS:-1}
8
- export LOG_LEVEL=${LOG_LEVEL:-"info"}
9
- export DATABASE_URL=${DATABASE_URL:-"sqlite:///app/storage/audiobooks.db"}
10
 
11
- # Set Python path to include both app directories
12
- export PYTHONPATH="/app:/app/app:${PYTHONPATH:-}:$(dirname $(dirname $(realpath $0)))"
 
13
 
14
- # Create storage directories if they don't exist
15
- mkdir -p /app/storage/audio
16
- mkdir -p /app/storage/text
17
- mkdir -p /app/storage/temp
18
 
19
- # Initialize database if using SQLite
20
- if [[ "$DATABASE_URL" == sqlite* ]]; then
21
- echo "Using SQLite database at: $DATABASE_URL"
22
- # Create the database directory if it doesn't exist
23
- DB_DIR=$(dirname "${DATABASE_URL#sqlite:///}")
24
- mkdir -p "$DB_DIR"
25
-
26
- # Initialize alembic if not already initialized
27
- if [ ! -d "migrations" ]; then
28
- echo "Initializing alembic..."
29
- alembic init migrations
30
- fi
31
-
32
- # Create initial migration if none exists
33
- if [ ! -d "migrations/versions" ] || [ -z "$(ls -A migrations/versions)" ]; then
34
- echo "Creating initial migration..."
35
- alembic revision --autogenerate -m "Initial migration"
36
- fi
37
- fi
38
 
39
- # Wait for database to be ready (if using external database)
40
- if [ ! -z "$DATABASE_URL" ] && [[ "$DATABASE_URL" != sqlite* ]]; then
41
- host=$(echo $DATABASE_URL | awk -F[@//] '{print $4}' | cut -d: -f1)
42
- port=$(echo $DATABASE_URL | awk -F[@//] '{print $4}' | cut -d: -f2 | cut -d/ -f1)
43
-
44
- echo "Waiting for database at $host:$port..."
45
- while ! nc -z $host $port; do
46
- sleep 1
47
- done
48
- echo "Database is ready!"
49
- fi
50
 
51
  # Run database migrations
52
  echo "Running database migrations..."
53
- python scripts/migrate.py
54
-
55
- echo "Starting CSM-1B TTS API server..."
56
- echo "Host: $HOST"
57
- echo "Port: $PORT"
58
- echo "Workers: $WORKERS"
59
- echo "Log Level: $LOG_LEVEL"
60
 
61
- # Start the FastAPI application using uvicorn
62
- exec uvicorn app.main:app \
63
- --host "$HOST" \
64
- --port "$PORT" \
65
- --workers "$WORKERS" \
66
- --log-level "$LOG_LEVEL"
 
1
  #!/bin/bash
 
2
 
3
+ # Exit on error
4
+ set -e
 
 
 
 
5
 
6
+ # Get the absolute path of the script directory
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
9
 
10
+ # Add project root and app directory to Python path
11
+ export PYTHONPATH="${PROJECT_ROOT}:${PROJECT_ROOT}/app:${PYTHONPATH:-}"
 
 
12
 
13
+ # Create storage directory if it doesn't exist
14
+ mkdir -p "${PROJECT_ROOT}/app/storage"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ # Print current working directory and Python path for debugging
17
+ echo "Current directory: $(pwd)"
18
+ echo "PYTHONPATH: ${PYTHONPATH}"
19
+ echo "Project root: ${PROJECT_ROOT}"
 
 
 
 
 
 
 
20
 
21
  # Run database migrations
22
  echo "Running database migrations..."
23
+ python "${SCRIPT_DIR}/migrate.py"
 
 
 
 
 
 
24
 
25
+ # Start the FastAPI application with uvicorn
26
+ echo "Starting FastAPI application..."
27
+ uvicorn app.main:app --host 0.0.0.0 --port 7860 --reload