Getting Started
Simpleye is an easy‑to‑use, self‑hosted dashboard for monitoring IP cameras — no cloud, no vendor lock‑in. It now includes recording, a review timeline, and the ability to make, save, and download clips.
If no users exist, Simpleye will walk you through creating the first admin account on first run.
Before you begin
- Docker and Docker Compose installed
- Git installed
Get up and running
-
Clone the repository
git clone https://github.com/TMills343/Simpleye cd Simpleye -
Configure environment variables
docker-compose automatically loads variables from the
.envfile in the project root and injects them into thewebcontainer via theenvironmentsection indocker-compose.yml. Noenv_fileis required.Minimum variables:
Variable Example Purpose MONGO_URI mongodb://mongo:27017 MongoDB connection string MONGO_DB simpleye Database name FLASK_SECRET_KEY change-me Secret key for Flask session Example .env:
MONGO_URI=mongodb://mongo:27017 MONGO_DB=simpleye FLASK_SECRET_KEY=change-meTip: In Portainer or other orchestrators, define MONGO_URI, MONGO_DB, and FLASK_SECRET_KEY as environment variables for the stack/service. The application reads these directly from the container environment. No
.envfile is needed in the container. -
Start the stack
# If you want docker-compose to also start the bundled MongoDB service, # enable the `local-db` profile (recommended for local use): docker compose --profile local-db up -d --buildHelpful commands:
# Tail logs for all services docker compose logs -f # Stop and remove containers docker compose down -
Open the app
- Visit http://localhost:8000
- Complete the first‑run flow to create the initial admin user, then add cameras
What Docker Compose runs
- mongo — MongoDB database (behind the
local-dbprofile; only created if you pass--profile local-db) - simpleye — Simpleye web app (listens on port 8000; health check at GET /health)
Notes:
- The app listens on container port 8000; adjust the published host port in docker-compose.yml if needed.
- Admin privileges are required to add, edit, or delete cameras.
- If you use an external MongoDB, omit the
local-dbprofile and setMONGO_URIto your external instance.
Local development (without Docker)
- Python 3.12 recommended.
- Create and activate a virtualenv.
pip install -r requirements.txt- Create a
.envfile and setMONGO_URIto a MongoDB instance you have running locally. You may also setMONGO_DBandFLASK_SECRET_KEY. - Run the app:
python app.pythen browse http://localhost:8000
Common tweaks
- Change host port: edit the ports mapping (e.g., 8080:8000) in docker-compose.yml.
- Point to external MongoDB: set MONGO_URI to your external connection string.
- Persist database data: ensure a volume is configured for the mongo service.
Troubleshooting
- Port in use: change the published port in docker-compose.yml (e.g., 8080:8000) and restart.
- Cannot connect to MongoDB: verify MONGO_URI, that the mongo service is healthy, or that your external DB is reachable from the container network.
- Secret key missing/invalid: ensure FLASK_SECRET_KEY is set in your .env or stack configuration.
Recording and review
- Configure cameras
- Cameras → Add/Edit: set a name, IP/port, and RTSP URL.
- Recording Mode defaults to HLS (recommended). You can change to JPEG if needed.
- Optional per-camera settings: Retention (hours), HLS Bitrate (kbps), HLS Segment length (seconds), FPS cap/JPEG quality (JPEG mode).
- Storage & retention
- Container writes to RECORDINGS_DIR, mounted by docker-compose at
/data/recordings. - Layout per camera:
/data/recordings/<camera_id>/YYYY/MM/DD/HH/MM/- HLS minutes:
index.m3u8+seg_*.ts - JPEG minutes:
SS_ms.jpgfiles
- HLS minutes:
- A background janitor deletes minute folders older than each camera’s
retention_hours(default 24h). Cleanup runs every 5 minutes.
- Review page
- From a camera’s Live View, click “Review”.
- Set From/To and “Load timeline”. The left panel shows a collapsible Day → Hour → Minute tree. Expanding a minute shows per-second ticks.
- Click a second to jump. Controls: Play/Pause/Stop, ±5s, Speed. HLS playback is seamless across minute boundaries.
- Clips
- Right “Clips” panel → Make a clip → set Start/Stop (defaults to current time), Create.
- Each clip shows a green Play button (modal playback) and a ⋮ menu with Download and (if permitted) Delete.
- Double-click a clip’s name to rename.
Routes
- UI
- GET / — Dashboard grid of all enabled cameras with RTSP
- GET /dashboard — Same as /
- GET /cameras — Camera list (table view)
- GET,POST /cameras/new — Add camera
- GET,POST /cameras/
/edit — Edit camera - POST /cameras/
/delete — Delete camera - POST /cameras/
/check — Check reachability of camera’s HTTP port - GET /cameras/
/view — Live viewer page for a camera - GET /cameras/
/review — Review page with timeline/playback/clips - GET /cameras/
/stream.mjpg — MJPEG stream for embedding - GET /cameras/
/recordings/ — Serve recorded files (JPEG frames, HLS playlists/segments) - GET /cameras/
/clips/ — Download a generated clip (MP4 attachment) - GET /cameras/
/clips/stream/ — Stream a generated clip (inline MP4) - GET,POST /signup — First-boot only; create initial admin user
- GET,POST /login — User login
- GET /logout — End session
- API
- GET /api/cameras — List cameras
- POST /api/cameras — Create camera (JSON body)
- GET /api/cameras/
— Get camera - POST /api/cameras/
— Update camera (form/JSON; admin) - DELETE /api/cameras/
— Delete camera - GET /api/cameras/
/recordings?start= &end= — List minute buckets and files; detects JPEG vs HLS - GET /api/cameras/
/hls_playlist?start= &end= — On-the-fly unified HLS playlist across a time range - GET /api/cameras/
/clips — List clips for a camera - POST /api/cameras/
/clips — Create a clip (HLS only) with { start, end, name? } - PATCH /api/cameras/
/clips/<clip_id> — Rename a clip (creator or admin) - DELETE /api/cameras/
/clips/<clip_id> — Delete a clip (creator or admin)
Notes
- The “Check” action only tests TCP connectivity to the configured HTTP port (default 80). It does not authenticate to or stream from the camera.
- Live view translates RTSP video into an MJPEG stream using OpenCV + FFmpeg in the backend. For most cameras, provide a full RTSP URL (e.g., rtsp://user:pass@192.168.1.10:554/stream). Network/firewall rules must allow the app container to reach the camera on its RTSP ports.
- Recording uses FFmpeg for HLS (default) or OpenCV for JPEG frames. Ensure ffmpeg is available (installed in the Docker image by default).
- Storage and retention: recordings live under RECORDINGS_DIR (mounted by docker-compose at /data/recordings). Retention cleanup runs every 5 minutes.
- Permissions: only admins can create/edit cameras; clip deletion is allowed to the clip’s creator or admins. Viewers can create clips but cannot delete others’ clips.
Static assets structure
- static/css — shared styles (e.g., style.css)
- static/js — client-side scripts (e.g., main.js)
- static/images — images/placeholders
- static/scripts — optional helper scripts/assets
Next steps
- Frequently Asked Questions: /docs/faq