A lightweight, web-based scheduler for automating Docker container restarts and management. Perfect for home lab environments running on Raspberry Pi 5 and NAS systems.
- ✅ Visual Dashboard: View all Docker containers at a glance
- ⏰ Cron Scheduling: Schedule automatic container actions (restart, start, stop, pause, unpause)
- 🎛️ Manual Control: Start, stop, restart, pause, and unpause containers from the web UI
- 🌐 Multi-Host Support: Manage containers across multiple Docker hosts (Raspberry Pi, NAS, servers)
- 📋 Container Logs: View container logs directly from the UI with configurable tail and refresh
- 🔔 Discord Notifications: Get notified when containers are restarted, started, or stopped
- 📊 Activity Logs: Track all scheduled and manual actions
- 🔄 Enable/Disable Schedules: Toggle schedules on/off without deleting them
- 💾 Persistent Storage: SQLite database for schedules and logs
- 🚀 Lightweight: Optimized for ARM64 (Raspberry Pi) and low-resource environments
- Automatically restart containers with known issues (PostgreSQL timeouts, nginx cache problems)
- Schedule periodic container maintenance
- Manage containers across multiple hosts (Raspberry Pi, Synology NAS, remote servers)
- Centralized dashboard for home lab Docker infrastructure
- Avoid paid Portainer Business subscription
- Docker and Docker Compose installed
- Docker socket access (
/var/run/docker.sock) - ARM64 (Raspberry Pi 5) or AMD64 architecture
-
Clone or download this directory to your host:
cd /path/to/your/projects # Copy the chrontainer directory here
-
Review docker-compose.yml and update if needed:
ports: - "5000:5000" # Change port if needed environment: - SECRET_KEY=your-secret-key-here # Change for production!
The default compose uses the published GHCR image. Uncomment
build: .if you prefer a local build. -
Start Chrontainer:
cd chrontainer docker-compose up -d -
Access the UI: Open your browser to
http://your-raspberry-pi-ip:5000
# Build the image
docker build -t chrontainer:latest .
# Run the container
docker run -d \
--name chrontainer \
-p 5000:5000 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v $(pwd)/data:/data \
-e SECRET_KEY=your-secret-key \
chrontainer:latest- Click the "Schedule" button next to any container
- Enter a cron expression (examples provided in the UI)
- Click "Create Schedule"
0 2 * * *- Daily at 2:00 AM0 */6 * * *- Every 6 hours*/30 * * * *- Every 30 minutes0 0 * * 0- Weekly on Sunday at midnight0 3 1 * *- Monthly on the 1st at 3:00 AM
Format: minute hour day month day_of_week
Use the action buttons next to each container:
- Restart: Restart a running container
- Stop: Stop a running container
- Start: Start a stopped container
- Toggle: Use the switch to enable/disable schedules
- Delete: Remove schedules you no longer need
- View Logs: Check the logs page for execution history
Chrontainer supports managing containers across multiple Docker hosts (Synology NAS, remote servers, etc.).
- Navigate to the Hosts page from the navigation menu
- Click "+ Add New Host"
- Enter a name (e.g., "Synology NAS") and URL (e.g.,
tcp://192.168.1.100:2375) - Click "Save" - Chrontainer will test the connection automatically
📖 Setup Notes:
- Use docker-socket-proxy (recommended) to expose the Docker API safely.
- Lock down firewall rules so only Chrontainer can reach the proxy.
- Never expose the raw Docker socket to the network.
Once added, all containers from remote hosts will appear on your dashboard with host badges, and you can schedule/manage them just like local containers.
- Navigate to Settings page
- Enter your Discord webhook URL
- Click "Save Settings"
- Test with "Send Test Notification"
Chrontainer will send rich notifications with color-coded embeds when containers are restarted, started, or stopped (both manual and scheduled actions).
- Raspberry Pi / Debian: enable memory cgroups so Docker can report container memory usage. Edit
/boot/firmware/cmdline.txt(single line) to removecgroup_disable=memoryand addcgroup_enable=memory cgroup_memory=1, then reboot. - Remote hosts via socket-proxy: set
SYSTEM=1in docker-socket-proxy to allow Docker disk usage metrics (/system/df).
┌─────────────────────┐
│ Web Browser │
│ (User Interface) │
└──────────┬──────────┘
│ HTTP
▼
┌─────────────────────┐
│ Chrontainer │
│ Flask App │
│ ├─ Web UI │
│ ├─ REST API │
│ └─ APScheduler │
└──────────┬──────────┘
│
├─► Docker Socket (/var/run/docker.sock)
│ └─► Container Management
│
└─► SQLite Database (/data/chrontainer.db)
└─► Schedules & Logs
Chrontainer now supports versioned APIs. Use /api/v1 for all new integrations. The legacy /api routes continue to work for now but will emit deprecation headers.
GET /api/v1/containers- List all containers (from all hosts)POST /api/v1/container/<id>/restart- Restart containerPOST /api/v1/container/<id>/start- Start containerPOST /api/v1/container/<id>/stop- Stop containerPOST /api/v1/container/<id>/pause- Pause containerPOST /api/v1/container/<id>/unpause- Unpause containerGET /api/v1/container/<id>/logs- Get container logs (supports tail, timestamps params)
POST /api/v1/schedule- Create new scheduleDELETE /api/v1/schedule/<id>- Delete schedulePOST /api/v1/schedule/<id>/toggle- Enable/disable schedule
GET /api/v1/hosts- List all Docker hostsPOST /api/v1/hosts- Add new Docker hostDELETE /api/v1/hosts/<id>- Delete Docker hostPOST /api/v1/hosts/<id>/test- Test host connection
GET /api/v1/settings- Get current settingsPOST /api/v1/settings/discord- Update Discord webhook URLPOST /api/v1/settings/discord/test- Send test notification
PORT- Web UI port (default: 5000)SECRET_KEY- Flask secret key (change for production!)
/var/run/docker.sock- Docker socket (required, read-only)/data- Persistent storage for database and logs
-
Docker Socket Access: Chrontainer requires access to the Docker socket, which provides full control over Docker. Only run this in trusted environments.
-
Remote Docker Hosts: NEVER expose the Docker socket directly to the network. Always use docker-socket-proxy to create a secure, filtered API layer. See REMOTE_HOSTS.md for proper setup.
-
Secret Key: Change the
SECRET_KEYin production:SECRET_KEY=$(openssl rand -hex 32) -
Network Exposure: By default, Chrontainer is accessible to anyone on your network. Consider:
- Running behind a reverse proxy with authentication
- Using Docker networks to restrict access
- Adding firewall rules
- Restricting remote host ports to trusted IPs only
-
Container Permissions: Ensure the Chrontainer container runs with appropriate permissions.
Cause: Docker socket not accessible
Solutions:
- Verify socket is mounted:
docker inspect chrontainer | grep docker.sock - Check socket permissions:
ls -la /var/run/docker.sock - Ensure user has Docker access:
sudo usermod -aG docker $USER
Cause: Permission issues or Docker connection problems
Solutions:
- Check logs:
docker logs chrontainer - Verify Docker is running:
docker ps - Test Docker access:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:ro alpine ls -la /var/run/docker.sock
Cause: Invalid cron expression or scheduler not running
Solutions:
- Verify cron syntax at crontab.guru
- Check logs for errors:
docker logs chrontainer - Ensure schedule is enabled (toggle switch)
- Restart Chrontainer:
docker restart chrontainer
Cause: Corrupted database or permission problems
Solutions:
- Check data directory permissions:
ls -la ./data - Backup and remove database:
mv data/chrontainer.db data/chrontainer.db.bak - Restart container to recreate:
docker restart chrontainer
-
API Endpoints Changed
- Old:
/api/container/<id>/restart - New:
/api/v1/containers/<id>/restart - Old API still works but is deprecated.
- Old:
-
Frontend Redesigned
- New Vue-based UI and new navigation structure.
-
Docker Compose Consolidated
- Single
docker-compose.ymlwith optional commented sections.
- Single
-
Backup
cp -r /path/to/data /path/to/data.backup cp docker-compose.yml docker-compose.yml.backup
-
Update Image
docker pull ghcr.io/rsousa88/chrontainer:1.0.0 docker-compose down
-
Run Migration Helper (recommended)
python3 scripts/migrate_v1.py
-
Start v1.0.0
docker-compose up -d docker-compose logs -f
-
Verify
- Open
http://localhost:5000 - Login with existing credentials
- Check containers, schedules, and settings
- Open
- Migration helper:
scripts/migrate_v1.py - Smoke tests:
scripts/smoke_test.sh http://localhost:5000 - Release checklist (manual):
scripts/release_v1.sh
- Multi-host support: Manage containers on remote Docker hosts
- Discord notifications: Rich embeds for container actions
- Authentication: Basic auth or OAuth for web UI
- Additional notifications: Slack/email alerts
- Backup schedules: Export/import schedule configurations
- Container logs: View container logs from UI
- Advanced scheduling: Support for one-time schedules, delays
- Health checks: Monitor container health and auto-restart
- Dashboard stats: Visualize uptime and restart patterns
- SSH tunnel support: Connect to remote hosts via SSH
This is a personal project for home lab use. Feel free to fork and adapt to your needs!
MIT License - Use freely, modify as needed.
For issues, questions, or feature requests, please create an issue on the repository.
Built with ❤️ for the home lab community