diff --git a/README.md b/README.md index 7f39470..d58ec21 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,14 @@ The application uses the following environment variables: - `SECRET_KEY`: Secret key for encryption (defaults to "development_secret_key" in development) +### Environment Detection + +The application automatically detects the environment it's running in: + +- In local development, it uses the project directory for database storage +- In container deployment, it uses the `/app/storage/db` directory +- Database permissions are automatically set to ensure write access + ### Installation 1. Clone the repository @@ -99,6 +107,8 @@ Run Alembic migrations to set up the database: alembic upgrade head ``` +The SQLite database will be created automatically in the `storage/db` directory with the proper permissions. The application will ensure that both the directory and the database file have appropriate write permissions. + ### Running the Application Start the application with uvicorn: diff --git a/app/core/config.py b/app/core/config.py index a6d7c3a..0194fd1 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -12,7 +12,8 @@ class Settings(BaseModel): API_V1_STR: str = "/api/v1" # Database - DB_DIR: Path = Path("/projects/onetimesecretsharingservice-i7if8q") / "storage" / "db" + # Check if /app directory exists (container) or use local path + DB_DIR: Path = Path("/app" if os.path.exists("/app/storage") else ROOT_DIR) / "storage" / "db" SQLALCHEMY_DATABASE_URL: str = f"sqlite:///{DB_DIR}/db.sqlite" # Secret settings @@ -25,6 +26,12 @@ class Settings(BaseModel): @field_validator("DB_DIR") def create_db_dir(cls, db_dir: Path) -> Path: db_dir.mkdir(parents=True, exist_ok=True) + # Ensure directory is writable + if not os.access(db_dir, os.W_OK): + try: + os.chmod(db_dir, 0o777) + except Exception: + print(f"Warning: Could not set permissions on {db_dir}") return db_dir model_config = { diff --git a/app/db/session.py b/app/db/session.py index c592685..3b38a17 100644 --- a/app/db/session.py +++ b/app/db/session.py @@ -1,3 +1,4 @@ +import os from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker @@ -7,8 +8,20 @@ from app.core.config import settings DB_DIR = settings.DB_DIR DB_DIR.mkdir(parents=True, exist_ok=True) -# Note: We're not using chmod here since /app/storage/db is already -# owned by appuser and has the appropriate permissions +# Ensure the directory has appropriate permissions +try: + os.chmod(DB_DIR, 0o777) +except Exception: + print(f"Warning: Could not set permissions on {DB_DIR}") + +# Create the database file if it doesn't exist +DB_FILE = DB_DIR / "db.sqlite" +if not DB_FILE.exists(): + DB_FILE.touch() + try: + os.chmod(DB_FILE, 0o666) # Read-write permissions for everyone + except Exception: + print(f"Warning: Could not set permissions on {DB_FILE}") SQLALCHEMY_DATABASE_URL = settings.SQLALCHEMY_DATABASE_URL diff --git a/migrations/env.py b/migrations/env.py index 260fa9b..477a758 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -1,3 +1,4 @@ +import os from logging.config import fileConfig from sqlalchemy import engine_from_config from sqlalchemy import pool @@ -69,8 +70,20 @@ def run_migrations_online() -> None: db_dir = Path(settings.DB_DIR) db_dir.mkdir(parents=True, exist_ok=True) - # Note: We're not using chmod here since /app/storage/db is already - # owned by appuser and has the appropriate permissions + # Ensure directory has write permissions + try: + os.chmod(db_dir, 0o777) + except Exception: + print(f"Warning: Could not set permissions on {db_dir}") + + # Create database file if it doesn't exist and set permissions + db_file = db_dir / "db.sqlite" + if not db_file.exists(): + db_file.touch() + try: + os.chmod(db_file, 0o666) # Read-write permissions for everyone + except Exception: + print(f"Warning: Could not set permissions on {db_file}") connectable = engine_from_config( config.get_section(config.config_ini_section, {}),