Advanced Blink Camera Management Platform
A comprehensive, web-based management system for Blink security cameras with automated 2FA, scheduled operations, and complete camera control through an intuitive PWA interface.
- Features
- Quick Start
- Web Interface & Camera Control
- Authentication
- Credential Configuration
- Configuration
- API Reference
- Docker Deployment
- Project Structure
- Camera Features & Capabilities
- Troubleshooting
- Additional Documentation
- Contributing
- License
- 🔒 Automatic 2FA Authentication: Seamless VoIP.ms SMS integration for Blink 2FA codes
- 🔐 Multi-Auth Support: Optional basic authentication or enterprise OIDC/SSO (Google, GitHub, Okta, etc.)
- 📸 Complete Camera Control: Full access to every Blink camera feature
- 🔄 Scheduled Operations: Automated thumbnail updates, camera arming, and motion detection management
- 💪 Resilient & Self-Healing: Auto-retry with intelligent error recovery and reinitialization
- 🏥 Advanced Health Monitoring: Production-ready Docker healthcheck with active status validation
- 📱 Progressive Web App: Install on any device for native-app experience
- 🖼️ Camera Dashboard: Visual overview of all cameras with real-time status
- 🎛️ Individual Camera Controls:
- Toggle snooze (notification silencing)
- Arm/disarm motion detection
- Auto-thumbnail updates
- Night vision mode (On/Off/Auto)
- 📸 One-click photo capture
- 🎥 Instant video recording
- ℹ️ Detailed info modal with complete camera data
- 📹 Media Management:
- View and download cached thumbnails
- Capture new photos on-demand
- Download latest video clips
- Browse and download recent clips with timestamps
- 🎨 Professional UI:
- Responsive design (mobile/tablet/desktop)
- Dark/light theme auto-switching
- Intuitive card-based layout
- Real-time status updates
- Toast notifications for all actions
- 🔧 Zero-Config Startup: Complete setup wizard on first run
- 🎯 Smart Configuration: Auto-optimization of camera-to-sync settings
- 📊 Comprehensive API: RESTful endpoints for all operations
- 🐳 Docker-First: Production-ready containerization with health monitoring
- 🔄 Auto-Discovery: Detects new cameras automatically
- 💾 Persistent Storage: Configuration survives container restarts
- 🌍 Multi-Instance: Run multiple deployments with isolated configs
-
Clone the repository:
git clone --recurse-submodules https://github.com/austinc3030/myblink.git cd myblink -
Start the container:
docker-compose up -d
-
Configure via web interface:
- Open http://localhost:8080 in your browser
- Enter your Blink credentials (email and password)
- Enter your VoIP.ms API credentials (username, password, and DID)
- Click "Save & Start"
That's it! The system will automatically:
- Save your credentials securely
- Initialize the Blink connection with 2FA
- Start managing your cameras
- Run scheduled jobs every hour
📱 Install as PWA: On mobile, use "Add to Home Screen" for a native app experience!
MyBlink provides a feature-rich web interface with complete control over all Blink camera functions. Everything is accessible through an intuitive, responsive design that works on any device.
Each camera displays as a card with instant access to:
- Snooze - Temporarily disable motion notifications
- Arm - Enable/disable motion detection and recording
- Thumbnail - Enable automatic thumbnail updates
- Dropdown selector with three modes:
- Off: IR illuminator disabled
- On: IR illuminator always on
- Auto: Automatic based on lighting conditions
- 📸 Capture: Take a new photo instantly (auto-downloads)
- 🎥 Record: Start video recording (saves to recent clips)
Click the info (ℹ️) button on any camera to view comprehensive details:
- Camera ID and serial number
- Product type and firmware version
- Network ID and sync module assignment
- Motion: Enabled status and detection state
- Battery: Level percentage, state (ok/replace), and voltage
- Temperature: Current reading in °F and °C
- WiFi: Signal strength
- Sync Strength: Connection quality to sync module
- Last Record: Timestamp of most recent motion event
- Night Vision: Change mode directly from info modal
- Settings automatically sync with camera card controls
- Cached Thumbnail: Download last cached image (no new capture)
- New Thumbnail: Capture fresh photo and download
- Latest Video Clip: Download most recent video
- Recent Clips: View list with:
- Full timestamps (e.g., "2/12/2026, 3:45:23 PM")
- Relative time ("5 minutes ago", "2 hours ago")
- Individual download buttons for each clip
Control all cameras in a sync module at once:
- Snooze All: Silence all cameras simultaneously
- Arm All: Enable motion detection for entire module
- Individual cameras can override sync-level settings
- Auto-Loading: Night vision status loads automatically for each camera
- Real-Time Updates: Changes reflect immediately in the interface
- Error Handling: Clear success/error messages for every action
- Loading States: Visual feedback during operations ("⏳ Capturing...", "⏳ Recording...")
- Auto-Downloads: Media files download with descriptive names automatically
- Theme Support: Seamless dark/light mode switching
- Responsive Design: Optimized for phones, tablets, and desktops
- Touch-Friendly: Large tap targets and swipe gestures
- PWA Installation: Add to home screen for offline access
- Fast & Lightweight: Minimal data usage, instant response
MyBlink now supports optional authentication to protect your web interface and API:
- No Authentication (default): Open access, no login required
- Basic Authentication: Simple username/password protection
- OIDC/SSO: Enterprise single sign-on (Google, GitHub, Okta, etc.)
Enable Basic Auth:
# config.yaml
auth_enabled: true
auth_method: basic
auth_basic_username: admin
auth_basic_password_hash: $2b$12$... # bcrypt hashGenerate password hash:
python3 -c "import bcrypt; print(bcrypt.hashpw(b'YourPassword', bcrypt.gensalt()).decode())"Enable OIDC/SSO:
# config.yaml
auth_enabled: true
auth_method: oidc
auth_oidc_client_id: your-client-id
auth_oidc_client_secret: your-secret
auth_oidc_server_metadata_url: https://accounts.google.com/.well-known/openid-configuration
auth_oidc_allowed_domains:
- yourdomain.com📖 Full Authentication Guide: See AUTH_GUIDE.md and AUTH_QUICKSTART.md for detailed configuration instructions.
MyBlink supports three ways to provide credentials, checked in this priority order:
Perfect for containerized deployments and CI/CD pipelines. Environment variables are automatically saved to the config file so they can be edited via the web UI later.
docker run -d \
-e BLINK_USERNAME="your-email@example.com" \
-e BLINK_PASSWORD="your-blink-password" \
-e VOIPMS_USERNAME="your-voipms-email@example.com" \
-e VOIPMS_PASSWORD="your-voipms-api-password" \
-e VOIPMS_DID="5551234567" \
-p 8080:8080 \
myblinkOr in docker-compose.yml:
services:
myblink:
environment:
- BLINK_USERNAME=your-email@example.com
- BLINK_PASSWORD=your-blink-password
- VOIPMS_USERNAME=your-voipms-email@example.com
- VOIPMS_PASSWORD=your-voipms-api-password
- VOIPMS_DID=5551234567Credentials are stored in the main config file (config.yaml). You can manually create this or let the web UI generate it:
# ...other config settings...
blink_username: "your-email@example.com"
blink_password: "your-blink-password"
voipms_username: "your-voipms-email@example.com"
voipms_password: "your-voipms-api-password"
voipms_did: "5551234567"If no credentials are found, the web UI automatically shows a setup wizard:
- Open http://localhost:8080
- Enter your credentials in the form
- Click "Save & Start"
Credentials are saved to config.yaml and can be edited anytime via the web UI.
Note: Once configured, you can change credentials anytime through the web interface at http://localhost:8080
-
Clone and setup:
git clone --recurse-submodules https://github.com/austinc3030/myblink.git cd myblink/app pip install -r requirements.txt -
Start the application:
python myblink.py
-
Configure: Open http://localhost:8080 and complete the setup wizard
Note: No config files needed! Everything is configured through the web interface or environment variables.
The application works out-of-the-box with sensible defaults. All configuration is done through the web interface.
For advanced users who need to customize low-level system settings, you can create a config.yaml file in the Docker volume (/data/config.yaml) or local directory with these options:
# Debug and monitoring
debug_mode: false
health_file: /tmp/myblink_health.json
health_check_interval: 30
max_consecutive_errors: 3
# VoIP.ms SMS filtering (not configurable via web UI)
voipms_message_keyword: "Blink"
voipms_retry_limit: 10
voipms_retry_delay: 3
# Internal timing
status_log_interval: 60
main_loop_sleep: 1
error_recovery_sleep: 5Common settings (retry limits, intervals, theme) are configurable via the web interface and automatically saved to the config file.
Configure the application paths and web server:
WEB_PORT=8080 # Port for web interface (default: 8080)
WEB_HOST=0.0.0.0 # Host to bind to (default: 0.0.0.0)
MYBLINK_CONFIG=/data/config.yaml # Config file path (default: /app/config.yaml)Credential Environment Variables (see Credential Configuration section above):
BLINK_USERNAME # Blink account email
BLINK_PASSWORD # Blink account password
VOIPMS_USERNAME # VoIP.ms API username
VOIPMS_PASSWORD # VoIP.ms API password
VOIPMS_DID # VoIP.ms DID (phone number)All camera and sync module settings are managed exclusively through the web interface:
- Snooze: Enable/disable motion detection
- Arm: Enable/disable camera arming
- Thumbnails: Enable/disable automatic thumbnail updates
Changes are saved automatically and take effect on the next scheduled run.
MyBlink exposes a comprehensive RESTful API for programmatic access to all camera and system functions. All endpoints require authentication if auth is enabled.
POST /auth/login # Basic auth: submit credentials
GET /auth/callback # OIDC: OAuth callback endpoint
GET /auth/logout # End session
GET /auth/status # Check authentication status
GET /api/state # Current state of all cameras and syncs
GET /api/config # Application configuration
POST /api/config # Update configuration
POST /api/refresh # Force refresh from Blink API
POST /api/run-jobs # Manually trigger scheduled jobs
GET /api/logs # Retrieve application logs
POST /api/logs/clear # Clear log history
GET /api/setup/status # Check if credentials configured
POST /api/setup/credentials # Set/update Blink and VoIP.ms credentials
POST /api/camera/<name>/snooze # Enable/disable snooze
POST /api/camera/<name>/arm # Enable/disable arming
POST /api/camera/<name>/thumbnail # Enable/disable thumbnails
GET /api/camera/<name>/night_vision # Get night vision mode
POST /api/camera/<name>/night_vision # Set night vision (on/off/auto)
POST /api/camera/<name>/record # Start video recording
GET /api/camera/<name>/info # Get detailed camera information
GET /api/camera/<name>/media/thumbnail # Download cached thumbnail
POST /api/camera/<name>/media/thumbnail/new # Capture new thumbnail
GET /api/camera/<name>/media/clip # Download latest video clip
GET /api/camera/<name>/media/clips # List recent clips
POST /api/camera/<name>/media/clip/download # Download specific clip by URL
POST /api/sync/<name>/snooze # Enable/disable snooze for all cameras
POST /api/sync/<name>/arm # Enable/disable arming for all cameras
curl http://localhost:8080/api/stateResponse:
{
"syncs": [
{
"name": "Sync Module",
"snooze_enabled": false,
"arm_enabled": true,
"cameras": [
{
"name": "Front Door",
"snooze_enabled": false,
"arm_enabled": true,
"thumbnail_enabled": true
}
]
}
]
}curl http://localhost:8080/api/camera/Front%20Door/infoResponse:
{
"name": "Front Door",
"camera_id": 123456,
"serial": "ABCD1234",
"type": "catalina",
"version": "9.62",
"battery_level": 3,
"battery": "ok",
"battery_voltage": 165,
"temperature": 72,
"temperature_c": 22.2,
"wifi_strength": 5,
"motion_enabled": true,
"motion_detected": false,
"network_id": 789012,
"sync_module": "Sync Module",
"recent_clips": [...]
}curl -X POST http://localhost:8080/api/camera/Front%20Door/night_vision \
-H "Content-Type: application/json" \
-d '{"mode": "auto"}'Response:
{
"success": true,
"mode": "auto"
}curl -X POST http://localhost:8080/api/camera/Front%20Door/media/thumbnail/new \
--output front_door.jpgcurl -X POST http://localhost:8080/api/camera/Front%20Door/recordResponse:
{
"success": true,
"message": "Recording started"
}# First, get the list of recent clips
curl http://localhost:8080/api/camera/Front%20Door/media/clips
# Then download a specific clip
curl -X POST http://localhost:8080/api/camera/Front%20Door/media/clip/download \
-H "Content-Type: application/json" \
-d '{"clip_url": "https://..."}' \
--output video.mp4# Enable snooze
curl -X POST http://localhost:8080/api/camera/Front%20Door/snooze \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
# Disable arming
curl -X POST http://localhost:8080/api/camera/Front%20Door/arm \
-H "Content-Type: application/json" \
-d '{"enabled": false}'# Arm all cameras in sync module
curl -X POST http://localhost:8080/api/sync/Sync%20Module/arm \
-H "Content-Type: application/json" \
-d '{"enabled": true}'When authentication is enabled, include credentials:
Basic Auth:
curl -u username:password http://localhost:8080/api/stateSession Cookie:
# Login first
curl -c cookies.txt -X POST http://localhost:8080/auth/login \
-d "username=admin&password=secret"
# Use session cookie
curl -b cookies.txt http://localhost:8080/api/state-
Clone and start:
git clone --recurse-submodules https://github.com/austinc3030/myblink.git cd myblink docker-compose up -d -
Configure: Open http://localhost:8080 and enter your credentials
-
Check logs:
docker-compose logs -f myblink
Note: Configuration and credentials are stored in the Docker volume myblink-data for persistence across container restarts.
# Build the image
docker build -t myblink .
# Create a volume for persistent data
docker volume create myblink-data
# Run the container
docker run -d \
--name myblink \
-v myblink-data:/data \
-p 8080:8080 \
-e WEB_PORT=8080 \
-e WEB_HOST=0.0.0.0 \
-e TZ=America/New_York \
--restart unless-stopped \
myblinkWEB_PORT: Port for web interface (default: 8080)WEB_HOST: Host to bind to (default: 0.0.0.0)MYBLINK_CONFIG: Path to config file (default: /data/config.yaml)MYBLINK_CREDS: Path to credentials file (default: /data/credentials.json)TZ: Timezone (e.g., America/New_York)
View volume location:
docker volume inspect myblink-dataBackup volume:
docker run --rm -v myblink-data:/data -v $(pwd):/backup alpine tar czf /backup/myblink-backup.tar.gz -C /data .Restore volume:
docker run --rm -v myblink-data:/data -v $(pwd):/backup alpine tar xzf /backup/myblink-backup.tar.gz -C /dataRemove volume (
docker-compose down -v
# Or: docker volume rm myblink-dataIf you're upgrading from a previous version with YAML credentials:
-
Backup your old credentials:
cp app/credentials.yaml app/credentials.yaml.backup
-
Start the new version:
python app/myblink.py # Or: docker-compose up -d -
Re-enter credentials via web interface at http://localhost:8080
-
Verify everything works, then remove the old file:
rm app/credentials.yaml.backup
If upgrading from the old structure (files at root), run the migration script:
chmod +x migrate_to_app.sh
./migrate_to_app.shThis moves all files into the app/ directory and updates submodule paths.
myblink/
├── app/ # All application code
│ ├── myblink.py # Main application orchestrator (470 lines)
│ ├── web_server.py # Flask web server with PWA interface (930+ lines)
│ ├── healthcheck.py # Docker healthcheck validator
│ ├── startup.sh # Container initialization script
│ ├── requirements.txt # Python dependencies
│ │
│ ├── modules/ # Modular application components
│ │ ├── __init__.py # Package exports
│ │ ├── models.py # Data models and configuration (318 lines)
│ │ ├── exceptions.py # Custom exception hierarchy
│ │ ├── config_manager.py # Configuration persistence (378 lines)
│ │ ├── health_monitor.py # Health status tracking
│ │ ├── voipms_handler.py # VoIP.ms 2FA integration (205 lines)
│ │ ├── blink_handler.py # Blink API integration (638 lines)
│ │ └── auth.py # Authentication system (620 lines)
│ │
│ ├── web_static/ # Progressive Web App
│ │ ├── index.html # Responsive UI with camera cards
│ │ ├── app.js # Full-featured SPA (875+ lines)
│ │ ├── manifest.json # PWA configuration
│ │ ├── sw.js # Service worker for offline support
│ │ └── create_icons.py # Icon generator utility
│ │
│ ├── blinkpy/ # Blink API library (git submodule)
│ │ └── blinkpy/ # Core library with camera/sync modules
│ │
│ └── python-voipms/ # VoIP.ms API library (git submodule)
│ └── voipms/ # VoIP.ms client implementation
│
├── Dockerfile # Multi-stage container build
├── docker-compose.yml # Docker Compose orchestration
├── config.example.yaml # Configuration template with docs
├── credentials.example.yaml # Credentials template (legacy)
├── migrate_config.py # Config migration utility
└── README.md # This comprehensive guide
Docker Volume (persistent data):
├── config.yaml # System & operational configuration
└── (no separate credentials file - stored in config.yaml)
Documentation:
├── AUTH_GUIDE.md # Complete authentication setup guide
├── AUTH_QUICKSTART.md # Quick auth configuration
├── AUTH_REFERENCE.md # Developer auth reference
├── AUTHENTICATION_IMPLEMENTED.md # Implementation details
├── CONFIG_GUIDE.md # Configuration reference
├── STATE_PERSISTENCE.md # How state management works
└── MIGRATION_GUIDE.md # Upgrade instructions
- Modular Design: Clean separation of concerns across 6 focused modules
- Web-First: Comprehensive REST API + intuitive PWA interface
- Type Safety: Dataclass models with validation
- Error Resilience: Hierarchical exception handling
- Async Core: Full async/await for non-blocking I/O
- Health Monitoring: Production-ready with active status tracking
- Authentication: Flexible multi-provider system (optional)
- State Persistence: Auto-saving YAML configuration
The container includes a comprehensive healthcheck system that monitors the application's actual health status, not just whether the process is running.
Important: The healthcheck will correctly mark the container as unhealthy if Blink initialization fails, even if the process is still running. This allows Docker orchestration tools to detect and restart failed containers.
- Health Status Tracking:
myblink.pycontinuously writes its health status to/tmp/myblink_health.json - Error Monitoring: The application tracks consecutive errors and marks itself unhealthy after 3 consecutive failures
- Staleness Detection: If the health status file isn't updated within 5 minutes, the container is marked unhealthy
- Active Verification: The
healthcheck.pyscript actively validates the health status every 30 seconds
- Update Interval: Health status is updated every 30 seconds during normal operation
- Timeout: 5 minutes without updates = unhealthy
- Max Consecutive Errors: 3 errors in a row = unhealthy
- Docker Check Interval: Every 30 seconds
- Retries: 3 failed checks before marking container unhealthy
Check container health status:
docker ps # Shows health status in STATUS column
docker inspect myblink --format='{{.State.Health.Status}}'View health check logs:
docker inspect myblink --format='{{range .State.Health.Log}}{{.Output}}{{end}}'Manual health check:
docker exec myblink python3 /app/healthcheck.pyThe healthcheck is built into the Dockerfile, but you can also configure or override it in your docker-compose.yml:
version: '3.8'
services:
myblink:
build: .
container_name: myblink
volumes:
- ./app/config.yaml:/app/config.yaml
- ./app/credentials.yaml:/app/credentials.yaml
ports:
- "8080:8080"
restart: unless-stoppedversion: '3.8'
services:
myblink:
build: .
container_name: myblink
volumes:
- ./app/config.yaml:/app/config.yaml
- ./app/credentials.yaml:/app/credentials.yaml
ports:
- "8080:8080"
restart: unless-stopped
healthcheck:
test: ["CMD", "python3", "/app/healthcheck.py"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60sversion: '3.8'
services:
myblink:
build: .
container_name: myblink
volumes:
- ./app/config.yaml:/app/config.yaml
- ./app/credentials.yaml:/app/credentials.yaml
ports:
- "8080:8080"
restart: unless-stopped
healthcheck:
test: ["CMD", "python3", "/app/healthcheck.py"]
interval: 1m # Check every minute
timeout: 10s # Max 10 seconds per check
retries: 5 # 5 failures before unhealthy
start_period: 2m # 2 minute grace period on startupFirst, add the autoheal container to automatically restart unhealthy services:
version: '3.8'
services:
myblink:
build: .
container_name: myblink
volumes:
- ./app/config.yaml:/app/config.yaml
- ./app/credentials.yaml:/app/credentials.yaml
ports:
- "8080:8080"
restart: unless-stopped
healthcheck:
test: ["CMD", "python3", "/app/healthcheck.py"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
labels:
- "autoheal=true"
autoheal:
image: willfarrell/autoheal:latest
container_name: autoheal
restart: unless-stopped
environment:
- AUTOHEAL_CONTAINER_LABEL=autoheal
- AUTOHEAL_INTERVAL=10
- AUTOHEAL_START_PERIOD=30
volumes:
- /var/run/docker.sock:/var/run/docker.sockThe autoheal container will automatically restart myblink if it becomes unhealthy.
MyBlink exposes every function of the BlinkPy library through its web interface and API. Here's a complete breakdown of what you can do with your cameras:
-
Arm/Disarm (
arm_enabled)- Enable/disable motion detection
- Controls whether camera records on motion
- Can be set per-camera or per-sync module
-
Snooze (
snooze_enabled)- Temporarily disable motion notifications
- Camera still records, but notifications are silenced
- Useful for high-traffic periods
-
Record Video (
/api/camera/<name>/record)- Manually trigger video recording
- Creates clip saved to Blink cloud
- Available in recent clips after completion
-
Thumbnail Updates (
thumbnail_enabled)- Auto-update thumbnails on schedule
- Managed through configuration
-
Manual Capture (
/api/camera/<name>/media/thumbnail/new)- Instant photo capture via web UI or API
- Downloads immediately after capture
- Does not affect scheduled thumbnails
- Three Modes (
/api/camera/<name>/night_vision)- Off: IR illuminator disabled
- On: IR illuminator always active
- Auto: Automatic based on ambient light
- Controllable from camera card or info modal
MyBlink provides access to all camera properties:
- Camera name, ID, and serial number
- Product type (Catalina, Owl, Mini, Doorbell, etc.)
- Firmware version
- Network ID and sync module assignment
- Battery: Level (1-3), state (ok/replace), voltage
- Temperature: Current reading (°F and °C)
- Temperature Calibrated: Adjusted reading
- WiFi Strength: Signal quality (1-5 bars)
- Sync Signal Strength: Connection to sync module
- Motion Detected: Current motion state
- Motion Enabled: Armed status
- Thumbnail: Current cached image
- Latest Clip: Most recent video recording
- Recent Clips: List of recent motion events with:
- Timestamp (ISO format)
- Clip URL for download
- Automatic expiration after 24 hours
- Last Record: Timestamp of most recent event
- Arm All Cameras: Enable motion detection for entire module
- Snooze All: Silence notifications for all cameras
- Individual cameras can override module settings
- Sync module name and ID
- Connected camera list
- Local storage status (Sync Module 2 only):
- Enabled/disabled state
- Storage compatibility
- Active status
- Manifest readiness
- Check storage status and compatibility
- View manifest state
- Access locally stored clips (when available)
- Initialize live stream connection
- Get RTSP/IMMIS URLs
- Real-time video access (API integration required)
- Download Operations:
- Cached thumbnails (instant)
- Fresh captures (triggers camera)
- Latest video clips
- Individual recent clips
- Auto-Expiration: Recent clips expire after set period
- Bulk Download: Via web UI or API
All camera settings persist across restarts:
- config.yaml serves as state cache
- Web UI changes auto-save
- Settings applied on startup via
run_scheduled_jobs() - Smart sync-level optimization for efficiency
Every BlinkPy feature is accessible through:
- Camera Cards: Quick controls (arm, snooze, thumbnails, night vision)
- Action Buttons: Capture and record
- Info Modal: Complete details and media management
- API Endpoints: Programmatic access for automation
- No Manual Config: Everything through intuitive UI
- Real-Time Feedback: Loading states and success/error messages
- Auto-Downloads: Media files download with descriptive names
- Smart Defaults: Sensible settings out-of-the-box
- Clear Labels: No technical jargon, just plain actions
Your saved Blink credentials may be expired. See detailed troubleshooting guide: BLINK_AUTH_TROUBLESHOOTING.md
Quick fix:
docker stop myblink
# Clear the "blinkpy_conf" value in config.json (set it to "")
docker start myblink
docker logs -f myblinkThis error means the git submodules are not initialized:
Solution:
# Initialize submodules
git submodule update --init --recursive
# Rebuild the Docker image
docker build -t myblink . --no-cache
# Recreate the container
docker-compose down
docker-compose up -dThis warning has been fixed in the latest version. If you see it:
git pull
docker build -t myblink .
docker-compose up -d --force-recreateIf you see permission errors like Permission denied: '/app/.venv' or Permission denied: '/.local':
Solution: The startup.sh has been updated to not use virtual environments inside Docker. Rebuild your image:
docker build -t myblink .
docker-compose up -d --force-recreateIf you see errors installing ./blinkpy or ./python-voipms:
Solution: Ensure git submodules are initialized before building:
git submodule update --init --recursive
docker build -t myblink .Check the logs for specific errors:
docker logs myblink -fIf you see AttributeError: 'Blink' object has no attribute 'key_required', this may indicate an outdated blinkpy version. Update submodules:
cd blinkpy
git pull origin main
cd ..
docker build -t myblink . --no-cacheThe healthcheck has a 60-second grace period on startup. If it fails before that:
- Check that
/tmp/myblink_health.jsonexists in the container - Verify the application is writing health status:
docker exec myblink cat /tmp/myblink_health.json - Check application logs:
docker logs myblink
MyBlink includes an optional responsive web interface (PWA) for easy camera management.
- 📱 Progressive Web App: Install on iOS/Android for native app experience
- 🎛️ Camera Controls: Toggle snooze/arm/thumbnail for individual cameras
- 🔄 Sync Management: Control entire sync modules at once
- ⚙️ Configuration: Adjust settings through the UI
- 🌓 Dark Mode: Automatic light/dark theme support
- 📊 Real-time Updates: Auto-refresh to show new cameras
- 🎯 Smart Optimization: Automatically consolidates camera settings to sync-level
-
Edit config.yaml:
web_enabled: true web_port: 8080 web_host: "0.0.0.0"
-
Access the interface:
- Local: http://localhost:8080
- Network: http://YOUR_SERVER_IP:8080
-
Install as PWA (optional):
- iOS: Safari → Share → Add to Home Screen
- Android: Chrome → Menu → Install app
Add port mapping to docker-compose.yml:
version: '3.8'
services:
myblink:
build: .
container_name: myblink
volumes:
- ./app/config.yaml:/app/config.yaml
- ./app/credentials.yaml:/app/credentials.yaml
ports:
- "8080:8080" # Add this line
restart: unless-stoppedThen enable in your config.yaml and restart:
docker-compose down
docker-compose up -dRecommendations:
- Only expose on trusted networks
- Use a reverse proxy with authentication for remote access
- Configure firewall rules to restrict access
- Consider VPN for remote management
See WEB_INTERFACE.md for detailed security recommendations.
MyBlink uses a hybrid configuration approach:
Managed via config.yaml (system/infrastructure settings):
debug_mode- Enable debug logginghealth_file- Health check file pathhealth_check_interval- Health monitoring frequencymax_consecutive_errors- Error thresholdvoipms_message_keyword- SMS keyword for 2FAvoipms_retry_limit- 2FA retrieval attemptsvoipms_retry_delay- Delay between 2FA attemptsstatus_log_interval- Status logging frequencymain_loop_sleep- Main loop sleep durationerror_recovery_sleep- Error recovery delayweb_enabled- Enable/disable web interfaceweb_port- Web server portweb_host- Web server host binding
Managed via Web UI (operational settings):
schedule_interval_hours- Job scheduling intervalblink_retry_limit- Blink API retry limitvoipms_sms_wait- SMS delivery wait time- All camera/sync operation settings:
snooze_syncs,no_snooze_syncssnooze_cams,no_snooze_camsarm_syncs,no_arm_syncsarm_cams,no_arm_camsthumbnail_cams,no_thumbnail_cams
The web UI automatically saves changes back to config.yaml, so all settings persist across restarts.
- Quick Start Guide - Get started quickly
- Full Web Interface Documentation - Complete guide including API endpoints, customization, and security
- Authentication Guide - Complete authentication setup (Basic + OIDC)
- Authentication Quick Start - Quick auth configuration
- Authentication Reference - Developer quick reference
- State Persistence - How configuration state works
- Configuration Guide - Detailed configuration reference
- Migration Guide - Upgrading to app/ structure
- Config Update Summary - Latest configuration changes
- Blink Auth Troubleshooting - Credential issues
- Authentication Implementation - Technical implementation details
Contributions are welcome! Here's how you can help:
- Check existing issues first
- Use issue templates when available
- Include:
- MyBlink version
- Docker/Python version
- Steps to reproduce
- Relevant log excerpts
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes:
- Follow existing code style
- Add tests if applicable
- Update documentation
- Commit with clear messages (
git commit -m 'Add amazing feature') - Push to your fork (
git push origin feature/amazing-feature) - Open a Pull Request
# Clone with submodules
git clone --recurse-submodules https://github.com/austinc3030/myblink.git
cd myblink/app
# Install dependencies
pip install -r requirements.txt
# Run locally
python myblink.py- Python: Follow PEP 8, use type hints where possible
- JavaScript: ES6+, clear variable names, comments for complex logic
- Documentation: Update README.md and relevant docs
- Testing: Test manually with real Blink cameras when possible
MyBlink is built on the shoulders of giants:
- BlinkPy by @fronzbot - The excellent Blink API library that powers camera communication
- python-voipms by @4doom4 - VoIP.ms API client for 2FA SMS retrieval
- Flask - Lightweight web framework
- Flask-Login - Session management
- Authlib - OAuth/OIDC implementation
- bcrypt - Secure password hashing
- aiohttp - Async HTTP client/server
- PyYAML - YAML parser
- All contributors who have submitted PRs, issues, and feedback
- The Blink community for testing and feature requests
- Docker team for excellent containerization tools
This project is licensed under the MIT License - see below for details:
MIT License
Copyright (c) 2024 Austin Chastain
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- Repository: https://github.com/austinc3030/myblink
- Issues: https://github.com/austinc3030/myblink/issues
- Docker Hub: (coming soon)
- Discussions: https://github.com/austinc3030/myblink/discussions
Made with ❤️ for the Blink community
If you find MyBlink useful, please give it a ⭐ on GitHub!