Replaced env variable DATABASE_PATH with DATA_PATH and DATABASE_FILENAME

This commit is contained in:
2025-05-05 16:56:03 -05:00
parent 2be8865537
commit f062f72017
5 changed files with 61 additions and 21 deletions

View File

@@ -9,7 +9,9 @@ COPY . .
ENV SUPER_ADMIN_USER=admin ENV SUPER_ADMIN_USER=admin
ENV SUPER_ADMIN_PASSWORD=adminpassword ENV SUPER_ADMIN_PASSWORD=adminpassword
ENV DATABASE_PATH=/data/users.db ENV DATABASE_FILENAME=users.db
ENV DATA_PATH=/data
ENV CONTENT_PATH=/content
VOLUME ["/data", "/Content"] VOLUME ["/data", "/Content"]

View File

@@ -54,10 +54,13 @@ You can install and run the project either manually or using Docker.
```env ```env
SUPER_ADMIN_USER=your_super_admin_username SUPER_ADMIN_USER=your_super_admin_username
SUPER_ADMIN_PASSWORD=your_super_admin_password SUPER_ADMIN_PASSWORD=your_super_admin_password
DATABASE_PATH=data/users.db DATABASE_FILENAME=users.db
DATA_PATH=/data
CONTENT_PATH=/content
``` ```
Note: The `DATABASE_PATH` uses a relative path. For persistence and consistency, it's recommended to use an absolute path or ensure the volume mount covers this path if using Docker. The `utils/database.py` script will attempt to create the directory `data` if it doesn't exist relative to where the script is run. **Important Notes:**
* For Docker deployments, paths should match volume mounts from the `docker run` command
### Docker Installation ### Docker Installation
@@ -82,7 +85,7 @@ You can install and run the project either manually or using Docker.
### Running Manually ### Running Manually
1. Ensure you have activated the virtual environment (if installed manually). 1. Ensure you have activated the virtual environment (if installed manually).
2. Ensure your environment variables (`SUPER_ADMIN_USER`, `SUPER_ADMIN_PASSWORD`, `DATABASE_PATH`) are set. 2. Ensure your environment variables (`SUPER_ADMIN_USER`, `SUPER_ADMIN_PASSWORD`, `DATABASE_FILENAME`, `DATA_PATH`, `CONTENT_PATH`) are set.
3. Run the application using uvicorn: 3. Run the application using uvicorn:
```bash ```bash
@@ -103,15 +106,33 @@ You can install and run the project either manually or using Docker.
--name user-service \ --name user-service \
-p 8000:8000 \ -p 8000:8000 \
-v user-service-data:/data \ -v user-service-data:/data \
-v user-service-content:/content \
-e SUPER_ADMIN_USER=your_super_admin_username \ -e SUPER_ADMIN_USER=your_super_admin_username \
-e SUPER_ADMIN_PASSWORD=your_super_admin_password \ -e SUPER_ADMIN_PASSWORD=your_super_admin_password \
user-registration-service iptv-server
``` ```
Replace `your_super_admin_username` and `your_super_admin_password` with your desired credentials. The `-v user-service-data:/data` maps a Docker volume for persistent storage of the SQLite database defined by `DATABASE_PATH=/data/users.db` in the Dockerfile. Replace `your_super_admin_username` and `your_super_admin_password` with your desired credentials.
Key components:
* `-v user-service-data:/data` creates/manages a Docker volume for persistent database storage
* `-v user-service-content:/content` ensures content directory persistence
* Environment variables match those expected by the application (defined in Dockerfile)
The application will be available at `http://localhost:8000` (or your Docker host's IP). The application will be available at `http://localhost:8000` (or your Docker host's IP).
**For bind mounts instead of named volumes** (useful for development):
```bash
docker run -d \
--name user-service \
-p 8000:8000 \
-v ./local/data:/data \
-v ./local/content:/content \
-e SUPER_ADMIN_USER=admin \
-e SUPER_ADMIN_PASSWORD=securepassword \
user-registration-service
## Usage ## Usage
The API documentation will be available at `http://localhost:8000/docs` (Swagger UI) or `http://localhost:8000/redoc` (ReDoc) once the server is running. The API documentation will be available at `http://localhost:8000/docs` (Swagger UI) or `http://localhost:8000/redoc` (ReDoc) once the server is running.

View File

@@ -19,12 +19,16 @@ if content_path and not os.path.exists(content_path):
print(f"Creating directory for serving content: {CONTENT_PATH}") print(f"Creating directory for serving content: {CONTENT_PATH}")
os.makedirs(content_path, exist_ok=True) os.makedirs(content_path, exist_ok=True)
# Database file path # Database file name
# Reads from environment variable DATABASE_PATH or defaults to '/data/users.db' # Reads from environment variable DATABASE_FILENAME or defaults to 'users.db'
DATABASE_PATH = os.getenv("DATABASE_PATH", "/data/users.db") DATABASE_FILENAME= os.getenv("DATABASE_FILENAME", "users.db")
# Ensure the directory for the database exists # Define the directory where data files are stored
db_dir = os.path.dirname(DATABASE_PATH) # Reads from environment variable DATA_PATH or defaults to '/data'
if db_dir and not os.path.exists(db_dir): DATA_PATH = os.getenv("DATA_PATH", "/data")
print(f"Creating directory for database: {DATABASE_PATH}")
os.makedirs(db_dir, exist_ok=True) # Ensure the directory for the data files
data_dir = os.path.dirname(DATA_PATH)
if data_dir and not os.path.exists(data_dir):
print(f"Creating directory for data files: {DATA_PATH}")
os.makedirs(data_dir, exist_ok=True)

View File

@@ -1,18 +1,25 @@
from pathlib import Path
import aiosqlite import aiosqlite
from fastapi import Depends, HTTPException, status, Query from fastapi import Depends, HTTPException, status, Query
from fastapi.security import HTTPBasicCredentials, HTTPBasic from fastapi.security import HTTPBasicCredentials, HTTPBasic
from passlib.context import CryptContext from passlib.context import CryptContext
from config import SUPER_ADMIN_USER, SUPER_ADMIN_PASSWORD, DATABASE_PATH from config import SUPER_ADMIN_USER, SUPER_ADMIN_PASSWORD, DATABASE_FILENAME, DATA_PATH
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
security = HTTPBasic() security = HTTPBasic()
admin_security = HTTPBasic() admin_security = HTTPBasic()
async def get_user(username: str): async def get_user(username: str):
# Use the dependency pattern even for internal calls for consistency # Build proper database path
async with aiosqlite.connect(DATABASE_PATH) as db: db_path = Path(DATA_PATH) / DATABASE_FILENAME
# Ensure directory exists (security measure)
db_path.parent.mkdir(parents=True, exist_ok=True)
async with aiosqlite.connect(db_path) as db:
cursor = await db.execute( cursor = await db.execute(
"SELECT * FROM users WHERE username = ?", (username,) "SELECT username, hashed_password FROM users WHERE username = ?",
(username,)
) )
return await cursor.fetchone() return await cursor.fetchone()

View File

@@ -1,9 +1,15 @@
import aiosqlite import aiosqlite
from dotenv import load_dotenv from pathlib import Path
from config import DATABASE_PATH from config import DATABASE_FILENAME, DATA_PATH
async def get_db(): async def get_db():
async with aiosqlite.connect(DATABASE_PATH) as db: # Build the full database path
db_path = Path(DATA_PATH) / DATABASE_FILENAME
# Ensure the directory exists
db_path.parent.mkdir(parents=True, exist_ok=True)
async with aiosqlite.connect(db_path) as db:
# Enable WAL mode for better concurrency # Enable WAL mode for better concurrency
await db.execute("PRAGMA journal_mode=WAL;") await db.execute("PRAGMA journal_mode=WAL;")
await db.execute(""" await db.execute("""