Portus is a local DNS and reverse-proxy orchestration system for managing services on a LAN.
It integrates FastAPI, React, CoreDNS, and Zoraxy for seamless service discovery, routing, and management.
- RESTful API for orchestrating LAN services
- Local DNS management via CoreDNS
- Reverse proxy with Zoraxy
- SQLite-backed configuration
- Optional authentication (username/password, WebAuthn)
- React + Vite UI dashboard
- Dockerized deployment for easy setup
- Health checks and monitoring endpoints
[ UI ] ---> [ Backend API ] ---> [ Zoraxy Proxy ]
                 |
                 +--> [ CoreDNS ]
                 |
                 +--> [ SQLite DB ]
- UI: React app for service management and authentication
- Backend: FastAPI orchestrates Zoraxy, CoreDNS, and DB
- Zoraxy: Reverse proxy for HTTP/TCP routing
- CoreDNS: Local DNS resolver for .landomains
- SQLite: Configuration and state storage
- Backend: Python 3.11+, FastAPI, SQLAlchemy, Alembic, Uvicorn
- Frontend: React 18, Vite, TypeScript, TailwindCSS, shadcn/ui
- Proxy: Zoraxy (containerized)
- DNS: CoreDNS (containerized)
- Database: SQLite
- CI/CD: GitHub Actions
- Containerization: Docker, Docker Compose
- 
Clone the repository: git clone rogu3bear/portus.git cd portus
- 
Copy and configure environment variables: cp .env.example .env # Edit .env as needed
- 
Start the stack: docker-compose up -d --build 
- 
Access services: 
- Python 3.11+ required
- Install dependencies:
cd backend python -m venv .venv source .venv/bin/activate pip install -r requirements.txt 
- Run locally:
uvicorn app.main:app --reload 
- Node.js 18+ required
- Install dependencies:
cd ui npm install
- Start dev server:
npm run dev 
- UI available at http://localhost:5173
- Backend:
- Lint: ruff check backend/app
- Test: pytest
 
- Lint: 
- Frontend:
- Lint: npm run lint
- Typecheck: npm run typecheck
 
- Lint: 
- CI:
 GitHub Actions run lint and tests on push/PR.
See .env.example for all variables.
Key settings:
- API_PORT,- API_HOST,- DB_PATH
- ZORAXY_PORT,- ZORAXY_ADMIN_USER,- ZORAXY_ADMIN_PASSWORD
- DNS_PORT,- DNS_DOMAIN
- UI_PORT,- UI_API_URL
- SECRET_KEY,- JWT_SECRET_KEY,- AUTH_ENABLED
- CORS_ORIGINS,- RATE_LIMIT_ENABLED
- TEST_MODEcontrols stub behavior during tests
- Change all secrets before production!
See docs/advanced-config.md for optional settings such as custom ports, TLS setup, and authentication tweaks.
- Toggle with AUTH_ENABLEDin.env
- Session expiry: AUTH_SESSION_EXPIRY_MINUTES
- WebAuthn biometric login (see docs/biometric.md)
- Auth endpoints:
- POST /auth/login,- POST /auth/logout,- GET /auth/status
- GET|POST /auth/webauthn(biometric)
- GET /auth/config,- POST /auth/config
 
- Production:
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build 
- Reverse proxy: Traefik config in docker-compose.prod.yml
- Volumes: Data and logs persisted via Docker volumes
- Set strong values for all secrets in .env
- Enable authentication in production
- TLS recommended (see Traefik config)
- HTTP security headers set by backend
- See docs/security.md for hardening tips
- Branch from main
- Use Conventional Commits
- Run make ciandpytestbefore PR
- Open PRs for review
- docs/index.md: Overview of available documentation
- docs/architecture.md: System diagram
- docs/biometric.md: WebAuthn setup
- docs/security.md: Security guide
- docs/advanced-config.md: Optional settings
- pipelines.md: Dev/test/deploy workflows
MIT
- TODO(#123): Add project badges
- TODO(#124): Complete frontend and backend test coverage
- TODO(#125): Document advanced configuration options