mirror of
https://github.com/maxdorninger/MediaManager.git
synced 2026-04-17 15:43:28 +02:00
Improve local dev experience
This commit is contained in:
39
Dockerfile
39
Dockerfile
@@ -1,28 +1,16 @@
|
|||||||
FROM node:24-alpine AS frontend-build
|
FROM node:24-alpine AS frontend-build
|
||||||
WORKDIR /frontend
|
WORKDIR /frontend
|
||||||
ARG VERSION
|
|
||||||
ARG BASE_PATH=""
|
|
||||||
|
|
||||||
COPY web/package*.json ./
|
COPY web/package*.json ./
|
||||||
RUN npm ci && npm cache clean --force
|
RUN npm ci && npm cache clean --force
|
||||||
|
|
||||||
COPY web/ ./
|
COPY web/ ./
|
||||||
RUN env PUBLIC_VERSION=${VERSION} PUBLIC_API_URL=${BASE_PATH} BASE_PATH=${BASE_PATH}/web npm run build
|
|
||||||
|
|
||||||
FROM ghcr.io/astral-sh/uv:python3.13-trixie-slim
|
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
ARG BASE_PATH=""
|
ARG BASE_PATH=""
|
||||||
LABEL author="github.com/maxdorninger"
|
RUN env PUBLIC_VERSION=${VERSION} PUBLIC_API_URL=${BASE_PATH} BASE_PATH=${BASE_PATH}/web npm run build
|
||||||
LABEL version=${VERSION}
|
|
||||||
LABEL description="Docker image for MediaManager"
|
|
||||||
|
|
||||||
ENV PUBLIC_VERSION=${VERSION} \
|
FROM ghcr.io/astral-sh/uv:python3.13-trixie-slim AS base
|
||||||
CONFIG_DIR="/app/config"\
|
|
||||||
BASE_PATH=${BASE_PATH}\
|
|
||||||
FRONTEND_FILES_DIR="/app/web/build"
|
|
||||||
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y ca-certificates bash libtorrent21 gcc bc locales postgresql media-types mailcap curl gzip unzip tar 7zip bzip2 unar && \
|
apt-get install -y ca-certificates bash libtorrent21 gcc bc locales postgresql media-types mailcap curl gzip unzip tar 7zip bzip2 unar && \
|
||||||
@@ -34,8 +22,24 @@ RUN locale-gen
|
|||||||
ENV LANG=en_US.UTF-8
|
ENV LANG=en_US.UTF-8
|
||||||
ENV LC_ALL=en_US.UTF-8
|
ENV LC_ALL=en_US.UTF-8
|
||||||
|
|
||||||
|
FROM base AS dependencies
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
COPY pyproject.toml uv.lock ./
|
COPY pyproject.toml uv.lock ./
|
||||||
RUN uv sync --locked
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
|
uv sync --locked
|
||||||
|
|
||||||
|
FROM dependencies AS app
|
||||||
|
ARG VERSION
|
||||||
|
ARG BASE_PATH=""
|
||||||
|
LABEL author="github.com/maxdorninger"
|
||||||
|
LABEL version=${VERSION}
|
||||||
|
LABEL description="Docker image for MediaManager"
|
||||||
|
|
||||||
|
ENV PUBLIC_VERSION=${VERSION} \
|
||||||
|
CONFIG_DIR="/app/config"\
|
||||||
|
BASE_PATH=${BASE_PATH}\
|
||||||
|
FRONTEND_FILES_DIR="/app/web/build"
|
||||||
|
|
||||||
COPY --chmod=755 mediamanager-startup.sh .
|
COPY --chmod=755 mediamanager-startup.sh .
|
||||||
COPY config.example.toml .
|
COPY config.example.toml .
|
||||||
@@ -43,8 +47,9 @@ COPY media_manager ./media_manager
|
|||||||
COPY alembic ./alembic
|
COPY alembic ./alembic
|
||||||
COPY alembic.ini .
|
COPY alembic.ini .
|
||||||
|
|
||||||
COPY --from=frontend-build /frontend/build /app/web/build
|
|
||||||
|
|
||||||
HEALTHCHECK CMD curl -f http://localhost:8000${BASE_PATH}/api/v1/health || exit 1
|
HEALTHCHECK CMD curl -f http://localhost:8000${BASE_PATH}/api/v1/health || exit 1
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
CMD ["/app/mediamanager-startup.sh"]
|
CMD ["/app/mediamanager-startup.sh"]
|
||||||
|
|
||||||
|
FROM app AS production
|
||||||
|
COPY --from=frontend-build /frontend/build /app/web/build
|
||||||
49
Makefile
Normal file
49
Makefile
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
# Docker Compose command (override if needed)
|
||||||
|
COMPOSE ?= docker compose
|
||||||
|
DC := $(COMPOSE) -f docker-compose.dev.yaml
|
||||||
|
|
||||||
|
# Log args passthrough, e.g.:
|
||||||
|
# make logs ARGS="--follow --tail=100"
|
||||||
|
ARGS ?=
|
||||||
|
|
||||||
|
# Service names (override if your compose uses different names)
|
||||||
|
APP_SVC ?= mediamanager
|
||||||
|
FRONTEND_SVC ?= frontend
|
||||||
|
|
||||||
|
.PHONY: help up down logs ps restartapp frontend
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "Usage:"
|
||||||
|
@echo " All commands run using the dev docker compose file ($(DEV_FILE))"
|
||||||
|
@echo ""
|
||||||
|
@echo " make up # Development environment up, runs with --build flag to rebuild if necessary"
|
||||||
|
@echo " make down # Development environment down"
|
||||||
|
@echo " make logs ARGS=\"...\" # (Optional) Set ARGS like \"--follow --tail=100\""
|
||||||
|
@echo " make ps | restart # Check status or restart containers"
|
||||||
|
@echo " make app # Shell into $(APP_SVC) container"
|
||||||
|
@echo " make frontend # Shell into $(FRONTEND_SVC) container"
|
||||||
|
|
||||||
|
# Core lifecycle
|
||||||
|
up:
|
||||||
|
$(DC) up -d --build
|
||||||
|
|
||||||
|
down:
|
||||||
|
$(DC) down
|
||||||
|
|
||||||
|
logs:
|
||||||
|
$(DC) logs $(ARGS)
|
||||||
|
|
||||||
|
ps:
|
||||||
|
$(DC) ps
|
||||||
|
|
||||||
|
restart:
|
||||||
|
$(DC) restart
|
||||||
|
|
||||||
|
# Interactive shells (prefer bash, fallback to sh)
|
||||||
|
app:
|
||||||
|
@$(DC) exec -it $(APP_SVC) bash 2>/dev/null || $(DC) exec -it $(APP_SVC) sh
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
@$(DC) exec -it $(FRONTEND_SVC) bash 2>/dev/null || $(DC) exec -it $(FRONTEND_SVC) sh
|
||||||
@@ -11,13 +11,28 @@ This section is for those who want to contribute to Media Manager or understand
|
|||||||
|
|
||||||
## Special Dev Configuration
|
## Special Dev Configuration
|
||||||
|
|
||||||
#### Env Variables
|
### Environment Variables
|
||||||
|
|
||||||
- `BASE_PATH`: this sets the base path for the app (can be set for both backend and frontend)
|
MediaManager uses various environment variables for configuration. In the Docker development setup (`docker-compose.dev.yaml`), most of these are automatically configured for you.
|
||||||
- `PUBLIC_VERSION`: this sets the version variable, it is displayed in the frontend (requires rebuilding of the
|
|
||||||
frontend) and in the /api/v1/health endpoint (can be set for both backend and frontend)
|
#### Backend Variables
|
||||||
- `FRONTEND_FILES_DIR`: directory for frontend files, e.g. in Docker container it is `/app/web/build` (only backend)
|
- `BASE_PATH`: Sets the base path for the app (e.g., for subdirectory deployments)
|
||||||
- `MEDIAMANAGER_MISC__DEVELOPMENT`: If set to `TRUE`, enables hot reloading of FastAPI (only when using the docker container)
|
- `PUBLIC_VERSION`: Version string displayed in `/api/v1/health` endpoint
|
||||||
|
- `FRONTEND_FILES_DIR`: Directory for built frontend files (e.g., `/app/web/build` in Docker)
|
||||||
|
- `MEDIAMANAGER_MISC__DEVELOPMENT`: When set to `TRUE`, enables FastAPI hot-reloading in Docker
|
||||||
|
|
||||||
|
#### Frontend Variables
|
||||||
|
- `PUBLIC_API_URL`: API URL for backend communication (automatically configured via Vite proxy in Docker)
|
||||||
|
- `PUBLIC_VERSION`: Version string displayed in the frontend UI
|
||||||
|
- `BASE_PATH`: Base path for frontend routing (matches backend BASE_PATH)
|
||||||
|
|
||||||
|
#### Docker Development Variables
|
||||||
|
- `DISABLE_FRONTEND_MOUNT`: When `TRUE`, disables mounting built frontend files (allows separate frontend container)
|
||||||
|
- **Note:** This is automatically set in `docker-compose.dev.yaml` to enable the separate frontend development container
|
||||||
|
|
||||||
|
#### Configuration Files
|
||||||
|
- Backend: `res/config/config.toml` (created from `config.dev.toml`)
|
||||||
|
- Frontend: `web/.env` (created from `.env.example`)
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -44,29 +59,68 @@ features.
|
|||||||
- VirtualKit
|
- VirtualKit
|
||||||
- Writerside (for writing documentation)
|
- Writerside (for writing documentation)
|
||||||
|
|
||||||
### Other recommendations
|
### Recommended Development Workflow
|
||||||
|
|
||||||
I recommend developing using Docker, i.e. you can use the provided `docker-compose.dev.yaml` file. This dev
|
The **recommended way** to develop MediaManager is using the fully Dockerized setup with `docker-compose.dev.yaml`.
|
||||||
docker-compose file has the `./media_manager` directory mounted at `/app/media_manager` in the container, meaning you
|
This ensures you're working in the same environment as production and makes it easy for new contributors to get started without installing Python, Node.js, or other dependencies locally.
|
||||||
can run the code using the container in exactly the environment it will be running in.
|
|
||||||
|
|
||||||
Additionally, to develop the frontend I use a locally installed Node.js server. So basically a hybrid approach, where
|
The development environment includes:
|
||||||
the backend runs in a container and the frontend runs on Windows. To make this work, you need to make sure the
|
- **Backend (FastAPI)** with automatic hot-reloading for Python code changes
|
||||||
`cors_urls` and `frontend_url` are set correctly in the backend's config file.
|
- **Frontend (SvelteKit/Vite)** with Hot Module Replacement (HMR) for instant updates
|
||||||
|
- **Database (PostgreSQL)** pre-configured and ready to use
|
||||||
|
|
||||||
Unfortunately, a side effect of this setup is that you have to rebuild the Docker image every time when you change the
|
**What requires what:**
|
||||||
python dependencies in any way or at least restart the container if you change the code. For a fast-paced development it
|
- **Python code changes (.py files)**: Automatically detected and hot-reloaded, no action needed ✨
|
||||||
may be more convenient to run the backend locally too, because then it supports hot reloading.
|
- **Frontend code changes (.svelte, .ts, .css)**: Instant HMR updates in browser, no action needed ✨
|
||||||
|
- **Configuration changes (config.toml)**: Live updates via volume mount, no action needed ✨
|
||||||
|
- **Backend dependencies (pyproject.toml)**: Require rebuilding: `docker compose -f docker-compose.dev.yaml build mediamanager`
|
||||||
|
- **Frontend dependencies (package.json)**: Restart frontend container: `docker compose -f docker-compose.dev.yaml restart frontend`
|
||||||
|
- **Database migrations**: Automatically run on backend container startup
|
||||||
|
|
||||||
### Setting up the basic development environment with Docker
|
This approach eliminates the need for container restarts during normal development and provides the best developer experience with instant feedback for code changes.
|
||||||
|
|
||||||
- Copy the `config.dev.toml` file to `config.toml` in the `./res` directory and edit it to your needs.
|
#### How the Frontend Connects to the Backend
|
||||||
- Use the following command to start the development environment with Docker:
|
|
||||||
```bash
|
|
||||||
docker compose -f docker-compose.dev.yaml up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Setting up the backend development environment
|
In the Docker development setup, the frontend and backend communicate through Vite's proxy configuration:
|
||||||
|
|
||||||
|
- **Frontend runs on**: `http://localhost:5173` (exposed from Docker)
|
||||||
|
- **Backend runs on**: `http://mediamanager:8000` (Docker internal network)
|
||||||
|
- **Vite proxy**: Automatically forwards all `/api/*` requests from frontend to backend
|
||||||
|
|
||||||
|
This means when your browser makes a request to `http://localhost:5173/api/v1/tv/shows`, Vite automatically proxies it to `http://mediamanager:8000/api/v1/tv/shows`. The `PUBLIC_API_URL` environment variable is set to use this proxy, so you don't need to configure anything manually.
|
||||||
|
|
||||||
|
### Setting up the full development environment with Docker (Recommended)
|
||||||
|
|
||||||
|
This is the easiest and recommended way to get started. Everything runs in Docker with hot-reloading enabled.
|
||||||
|
|
||||||
|
1. **Copy the example config & .env:**
|
||||||
|
```bash
|
||||||
|
cp config.dev.toml res/config/config.toml
|
||||||
|
cp web/.env.example web/.env
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Start all services:**
|
||||||
|
```bash
|
||||||
|
# Recommended: Use make commands for easy development
|
||||||
|
make up
|
||||||
|
|
||||||
|
# Alternative: Use docker compose directly (if make is not available)
|
||||||
|
docker compose -f docker-compose.dev.yaml up
|
||||||
|
```
|
||||||
|
|
||||||
|
**Tip:** Run `make help` to see all available development commands including `make down`, `make logs`, `make app` (shell into backend), and more.
|
||||||
|
|
||||||
|
3. **Access the application:**
|
||||||
|
- Frontend (with HMR): http://localhost:5173
|
||||||
|
- Backend API: http://localhost:8000
|
||||||
|
- Database: localhost:5432
|
||||||
|
|
||||||
|
That's it! Now you can edit code and see changes instantly:
|
||||||
|
- Edit Python files → Backend auto-reloads
|
||||||
|
- Edit Svelte/TypeScript files → Frontend HMR updates in browser
|
||||||
|
- Edit config.toml → Changes apply immediately
|
||||||
|
|
||||||
|
### Setting up the backend development environment (Local)
|
||||||
|
|
||||||
1. Clone the repository
|
1. Clone the repository
|
||||||
2. cd into repo root
|
2. cd into repo root
|
||||||
@@ -93,18 +147,21 @@ may be more convenient to run the backend locally too, because then it supports
|
|||||||
|
|
||||||
9. run the backend with
|
9. run the backend with
|
||||||
```bash
|
```bash
|
||||||
uv run ./media_manager/main.py --reload --port 8000
|
uv run fastapi run media_manager/main.py --reload --port 8000
|
||||||
```
|
```
|
||||||
|
|
||||||
- format code with `uvx ruff format`
|
- format code with `uv run ruff format .`
|
||||||
- lint code with `uvx ruff check`
|
- lint code with `uv run ruff check .`
|
||||||
|
|
||||||
### Setting up the frontend development environment
|
### Setting up the frontend development environment (Local, Optional)
|
||||||
|
|
||||||
|
**Note:** Using the Docker setup above is recommended. This section is for those who prefer to run the frontend locally
|
||||||
|
outside of Docker.
|
||||||
|
|
||||||
1. Clone the repository
|
1. Clone the repository
|
||||||
2. cd into repo root
|
2. cd into repo root
|
||||||
3. cd into `web` directory
|
3. cd into `web` directory
|
||||||
4. install Node.js and npm if you haven't already, I
|
4. Install Node.js and npm if you haven't already, I
|
||||||
used [nvm-windows](https://github.com/coreybutler/nvm-windows?tab=readme-ov-file):
|
used [nvm-windows](https://github.com/coreybutler/nvm-windows?tab=readme-ov-file):
|
||||||
```powershell
|
```powershell
|
||||||
nvm install 24.1.0
|
nvm install 24.1.0
|
||||||
@@ -114,11 +171,73 @@ may be more convenient to run the backend locally too, because then it supports
|
|||||||
```powershell
|
```powershell
|
||||||
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||||
```
|
```
|
||||||
5. Install the dependencies with npm: `npm install`
|
5. Create a `.env` file in the `web` directory:
|
||||||
6. Start the frontend development server: `npm run dev`
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
Update `PUBLIC_API_URL` if your backend is not at `http://localhost:8000`
|
||||||
|
|
||||||
- format the code with `npm run format`
|
6. Install the dependencies with npm: `npm install`
|
||||||
- lint the code with `npm run lint`
|
7. Start the frontend development server: `npm run dev`
|
||||||
|
|
||||||
|
**Important:** If running frontend locally, make sure to add `http://localhost:5173` to the `cors_urls` in your backend
|
||||||
|
config file.
|
||||||
|
|
||||||
|
- Format the code with `npm run format`
|
||||||
|
- Lint the code with `npm run lint`
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Docker Development Issues
|
||||||
|
|
||||||
|
**Port already in use errors:**
|
||||||
|
- Check if ports 5173, 8000, or 5432 are already in use: `lsof -i :5173` (macOS/Linux) or `netstat -ano | findstr :5173` (Windows)
|
||||||
|
- Stop conflicting services or change ports in `docker-compose.dev.yaml`
|
||||||
|
|
||||||
|
**Container not showing code changes:**
|
||||||
|
- Verify volume mounts are correct in `docker-compose.dev.yaml`
|
||||||
|
- For backend: Ensure `./media_manager:/app/media_manager` is mounted
|
||||||
|
- For frontend: Ensure `./web:/app` is mounted
|
||||||
|
- On Windows: Check that file watching is enabled in Docker Desktop settings
|
||||||
|
|
||||||
|
**Frontend changes not updating:**
|
||||||
|
- Check that the frontend container is running: `make ps` or `docker compose -f docker-compose.dev.yaml ps`
|
||||||
|
- Verify Vite's file watching is working (should see HMR updates in browser console)
|
||||||
|
- Try restarting the frontend container: `docker compose -f docker-compose.dev.yaml restart frontend`
|
||||||
|
|
||||||
|
**Backend changes not reloading:**
|
||||||
|
- Verify `MEDIAMANAGER_MISC__DEVELOPMENT=TRUE` is set in `docker-compose.dev.yaml`
|
||||||
|
- Check backend logs: `make logs ARGS="--follow mediamanager"` or `docker compose -f docker-compose.dev.yaml logs -f mediamanager`
|
||||||
|
- If dependencies changed, rebuild: `docker compose -f docker-compose.dev.yaml build mediamanager`
|
||||||
|
|
||||||
|
**Database migration issues:**
|
||||||
|
- Migrations run automatically on container startup
|
||||||
|
- To run manually: `make app` then `uv run alembic upgrade head`
|
||||||
|
- To create new migration: `make app` then `uv run alembic revision --autogenerate -m "description"`
|
||||||
|
|
||||||
|
**Viewing logs:**
|
||||||
|
- All services: `make logs`
|
||||||
|
- Follow logs in real-time: `make logs ARGS="--follow"`
|
||||||
|
- Specific service: `make logs ARGS="mediamanager --follow"`
|
||||||
|
|
||||||
|
**Interactive debugging:**
|
||||||
|
- Shell into backend: `make app` (or `docker compose -f docker-compose.dev.yaml exec -it mediamanager bash`)
|
||||||
|
- Shell into frontend: `make frontend` (or `docker compose -f docker-compose.dev.yaml exec -it frontend sh`)
|
||||||
|
- Once inside, you can run commands like `uv run alembic upgrade head`, `npm install`, etc.
|
||||||
|
|
||||||
|
**Volume permission issues (Linux):**
|
||||||
|
- Docker containers may create files as root, causing permission issues
|
||||||
|
- Solution: Run containers with your user ID or use Docker's `user:` directive
|
||||||
|
- Alternatively: `sudo chown -R $USER:$USER .` to reclaim ownership
|
||||||
|
|
||||||
|
**Complete reset:**
|
||||||
|
If all else fails, you can completely reset your development environment:
|
||||||
|
```bash
|
||||||
|
make down
|
||||||
|
docker compose -f docker-compose.dev.yaml down -v # Remove volumes
|
||||||
|
docker compose -f docker-compose.dev.yaml build --no-cache # Rebuild without cache
|
||||||
|
make up
|
||||||
|
```
|
||||||
|
|
||||||
## Sequence Diagrams
|
## Sequence Diagrams
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
[misc]
|
[misc]
|
||||||
# it's very likely that you need to change this for MediaManager to work
|
# it's very likely that you need to change this for MediaManager to work
|
||||||
frontend_url = "http://localhost:5173/" # note the trailing slash
|
frontend_url = "http://localhost:5173/" # note the trailing slash
|
||||||
cors_urls = ["http://localhost:8000", "http://localhost:5173"] # note the lack of a trailing slash
|
cors_urls = ["http://localhost:8000", "http://localhost:5173", "http://mediamanager:8000"] # note the lack of a trailing slash
|
||||||
|
|
||||||
image_directory = "/data/images"
|
image_directory = "/data/images"
|
||||||
tv_directory = "/data/tv"
|
tv_directory = "/data/tv"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
target: app
|
||||||
args:
|
args:
|
||||||
- VERSION=locally-built
|
- VERSION=locally-built
|
||||||
- BASE_PATH=
|
- BASE_PATH=
|
||||||
@@ -24,12 +25,26 @@ services:
|
|||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
environment:
|
environment:
|
||||||
- CONFIG_DIR=/app/config
|
- CONFIG_DIR=/app/config
|
||||||
|
- MEDIAMANAGER_MISC__DEVELOPMENT=TRUE
|
||||||
|
- DISABLE_FRONTEND_MOUNT=TRUE
|
||||||
volumes:
|
volumes:
|
||||||
#- ./web/build:/app/web/build # this is only needed to test built frontend when developing frontend
|
#- ./web/build:/app/web/build # this is only needed to test built frontend when developing frontend
|
||||||
- ./res/images/:/data/images/
|
- ./res/images/:/data/images/
|
||||||
- ./res/:/data/
|
- ./res/:/data/
|
||||||
- ./res/config/:/app/config/
|
- ./res/config/:/app/config/
|
||||||
- ./media_manager:/app/media_manager
|
- ./media_manager:/app/media_manager
|
||||||
|
frontend:
|
||||||
|
image: node:24-alpine
|
||||||
|
container_name: mediamanager-frontend-dev
|
||||||
|
working_dir: /app
|
||||||
|
command: sh -c "npm install && npm run dev -- --host 0.0.0.0"
|
||||||
|
ports:
|
||||||
|
- "5173:5173"
|
||||||
|
- "24678:24678"
|
||||||
|
volumes:
|
||||||
|
- ./web:/app
|
||||||
|
depends_on:
|
||||||
|
- mediamanager
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
# Additional services can be uncommented and configured as needed
|
# Additional services can be uncommented and configured as needed
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ async def lifespan(app: FastAPI):
|
|||||||
|
|
||||||
BASE_PATH = os.getenv("BASE_PATH", "")
|
BASE_PATH = os.getenv("BASE_PATH", "")
|
||||||
FRONTEND_FILES_DIR = os.getenv("FRONTEND_FILES_DIR")
|
FRONTEND_FILES_DIR = os.getenv("FRONTEND_FILES_DIR")
|
||||||
|
DISABLE_FRONTEND_MOUNT = os.getenv("DISABLE_FRONTEND_MOUNT", "").lower() in ["true", "1", "yes"]
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI(lifespan=lifespan, root_path=BASE_PATH)
|
app = FastAPI(lifespan=lifespan, root_path=BASE_PATH)
|
||||||
@@ -290,7 +291,16 @@ app.mount(
|
|||||||
)
|
)
|
||||||
|
|
||||||
app.include_router(api_app)
|
app.include_router(api_app)
|
||||||
app.mount("/web", StaticFiles(directory=FRONTEND_FILES_DIR, html=True), name="frontend")
|
|
||||||
|
# ----------------------------
|
||||||
|
# Frontend mounting (disabled in development)
|
||||||
|
# ----------------------------
|
||||||
|
|
||||||
|
if not DISABLE_FRONTEND_MOUNT:
|
||||||
|
app.mount("/web", StaticFiles(directory=FRONTEND_FILES_DIR, html=True), name="frontend")
|
||||||
|
log.info(f"Mounted frontend at /web from {FRONTEND_FILES_DIR}")
|
||||||
|
else:
|
||||||
|
log.info("Frontend mounting disabled (DISABLE_FRONTEND_MOUNT is set)")
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
# Redirects to frontend
|
# Redirects to frontend
|
||||||
@@ -325,7 +335,7 @@ app.add_exception_handler(UniqueViolation, sqlalchemy_integrity_error_handler)
|
|||||||
|
|
||||||
@app.exception_handler(404)
|
@app.exception_handler(404)
|
||||||
async def not_found_handler(request, exc):
|
async def not_found_handler(request, exc):
|
||||||
if any(
|
if not DISABLE_FRONTEND_MOUNT and any(
|
||||||
base_path in ["/web", "/dashboard", "/login"] for base_path in request.url.path
|
base_path in ["/web", "/dashboard", "/login"] for base_path in request.url.path
|
||||||
):
|
):
|
||||||
return FileResponse(f"{FRONTEND_FILES_DIR}/404.html")
|
return FileResponse(f"{FRONTEND_FILES_DIR}/404.html")
|
||||||
|
|||||||
13
web/.env.example
Normal file
13
web/.env.example
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Frontend Environment Variables
|
||||||
|
# These are set automatically in docker-compose.dev.yaml for development
|
||||||
|
|
||||||
|
# API URL for backend communication
|
||||||
|
# Development: http://localhost:5173
|
||||||
|
# Production: Built into the static files during Docker build
|
||||||
|
PUBLIC_API_URL=http://localhost:5173
|
||||||
|
|
||||||
|
# Base path for routing (leave empty unless using a subdirectory deployment)
|
||||||
|
BASE_PATH=
|
||||||
|
|
||||||
|
# Version string (automatically set during build)
|
||||||
|
PUBLIC_VERSION=dev
|
||||||
@@ -4,5 +4,21 @@ import { enhancedImages } from '@sveltejs/enhanced-img';
|
|||||||
import tailwindcss from '@tailwindcss/vite';
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [tailwindcss(), enhancedImages(), sveltekit()]
|
plugins: [tailwindcss(), enhancedImages(), sveltekit()],
|
||||||
|
server: {
|
||||||
|
host: '0.0.0.0', // Allow external connections (required for Docker)
|
||||||
|
port: 5173,
|
||||||
|
strictPort: true, // Fail if port is already in use
|
||||||
|
watch: {
|
||||||
|
usePolling: true, // Required for file watching in Docker on some systems
|
||||||
|
interval: 100 // Check for changes every 100ms
|
||||||
|
},
|
||||||
|
proxy: {
|
||||||
|
// Proxy API requests to backend container
|
||||||
|
'/api': {
|
||||||
|
target: 'http://mediamanager:8000',
|
||||||
|
changeOrigin: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user