diff --git a/README.md b/README.md index faa5fd6..63fc23a 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,8 @@ POSTGRES_DB=plasttrack POSTGRES_USER=plasttrack POSTGRES_PASSWORD=change-this-password FRONTEND_ORIGIN=http://SERVER_IP:5173 +FRONTEND_ORIGINS=http://SERVER_IP:5173,http://localhost:5173,http://127.0.0.1:5173 +BACKEND_PORT=8000 VITE_API_BASE_URL=http://SERVER_IP:8000 VITE_WS_URL=ws://SERVER_IP:8000/ws/dashboard VITE_ALLOWED_HOSTS=SERVER_IP,localhost,127.0.0.1 @@ -128,6 +130,8 @@ POSTGRES_DB=plasttrack POSTGRES_USER=plasttrack POSTGRES_PASSWORD=change-this-password FRONTEND_ORIGIN=https://plasttrack.example.com +FRONTEND_ORIGINS=https://plasttrack.example.com +BACKEND_PORT=8000 VITE_API_BASE_URL=https://api.plasttrack.example.com VITE_WS_URL=wss://api.plasttrack.example.com/ws/dashboard VITE_ALLOWED_HOSTS=plasttrack.example.com @@ -140,6 +144,22 @@ machine, not the Docker host. If Vite returns `Blocked request. This host is not allowed`, add the public frontend host to `VITE_ALLOWED_HOSTS` as a comma-separated value. +If the backend host port conflicts with another service such as Portainer, +change `BACKEND_PORT` instead of editing `docker-compose.yml`. For example: + +```env +BACKEND_PORT=8001 +VITE_API_BASE_URL=http://SERVER_IP:8001 +VITE_WS_URL=ws://SERVER_IP:8001/ws/dashboard +``` + +If the browser shows a CORS error, make sure the exact frontend origin is in +`FRONTEND_ORIGINS`. Example: + +```env +FRONTEND_ORIGINS=https://plasttrack.sable.ynsdev.site +``` + ### 3. Deploy Click `Deploy the stack`. diff --git a/backend/app/config.py b/backend/app/config.py index a09bdcf..a936d3e 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -18,7 +18,8 @@ class Settings(BaseSettings): mqtt_port: int = 1883 mqtt_topic: str = "plasttrack/machines/+/events" mqtt_client_id: str = "plast-track-backend" - frontend_origin: str = "http://localhost:5173" + frontend_origin: str | None = None + frontend_origins: str = "http://localhost:5173,http://127.0.0.1:5173" downtime_check_interval_sec: int = 5 database_startup_retries: int = 30 database_startup_retry_delay_sec: float = 2.0 @@ -36,6 +37,13 @@ class Settings(BaseSettings): database=self.postgres_db, ).render_as_string(hide_password=False) + @property + def cors_allowed_origins(self) -> list[str]: + configured_origins = [origin.strip() for origin in self.frontend_origins.split(",") if origin.strip()] + if self.frontend_origin: + configured_origins.append(self.frontend_origin.strip()) + return list(dict.fromkeys(configured_origins)) + @lru_cache def get_settings() -> Settings: diff --git a/backend/app/main.py b/backend/app/main.py index 2410703..b057120 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -148,7 +148,7 @@ async def lifespan(app: FastAPI): app = FastAPI(title=settings.app_name, lifespan=lifespan) app.add_middleware( CORSMiddleware, - allow_origins=[settings.frontend_origin, "http://localhost:5173", "http://127.0.0.1:5173"], + allow_origins=settings.cors_allowed_origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], diff --git a/docker-compose.yml b/docker-compose.yml index a9970df..8685749 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,13 +39,14 @@ services: MQTT_PORT: 1883 MQTT_TOPIC: plasttrack/machines/+/events FRONTEND_ORIGIN: ${FRONTEND_ORIGIN:-http://localhost:5173} + FRONTEND_ORIGINS: ${FRONTEND_ORIGINS:-http://localhost:5173,http://127.0.0.1:5173} depends_on: database: condition: service_healthy mqtt: condition: service_healthy ports: - - "8000:8000" + - "${BACKEND_PORT:-8000}:8000" edge-simulator: build: