A web-based management interface for Quartz Scheduler, built with Spring Boot and React.
License Notice: This software is free for non-commercial use only. Commercial use is prohibited without permission. See LICENSE for details.
- Job Management: Create, edit, delete, and view scheduled jobs
- HTTP Job Support: Configure HTTP requests as scheduled jobs (GET, POST, PUT, DELETE)
- Execution History: Track job execution history with status, timestamps, and duration
- Real-time Monitoring: View job status, next execution time, and execution logs
- Modern UI: Professional interface with sidebar navigation, floating headers, and responsive design
- Cron Expression Support: Flexible scheduling with cron expressions
Overview of all scheduled jobs with real-time status and quick actions.

Simple form to create new scheduled jobs with HTTP request configuration.

Detailed history of job executions with status, duration, and response data.

- Spring Boot 4.0.2
- Quartz Scheduler 2.5.1
- MySQL 8.0
- Java 25
- React 18
- TypeScript
- Vite
- Lucide React (icons)
- Backend: Spring Boot REST API (
quartz-manager-backend) - Frontend: React SPA (
quartz-manager-frontend) - Database: MySQL for Quartz tables and execution history
- Reverse Proxy: Nginx for routing
Before running the application, ensure you have the following installed:
- Docker (version 20.10 or higher)
- Docker Compose (version 2.0 or higher)
- Java 25 (for local development)
- Maven 3.8+ (for local development)
- Node.js 18+ (for local development)
The easiest way to run the application is using Docker Compose:
git clone https://github.com/ppuskar/quartz-manager.git
cd quartz-managercd quartz-manager-backend
mvn clean package -DskipTests
cd ..docker-compose up -dThis will start:
- MySQL database on port
3307 - Backend API on port
8080 - Frontend on port
3000 - Nginx reverse proxy on port
80
Open your browser and navigate to:
http://localhost:3000
The application will be available at the root URL, with:
- Frontend served at
/ - Backend API at
/api/*
-
Start MySQL Database:
docker-compose up -d db
-
Configure Application Properties: Edit
quartz-manager-backend/src/main/resources/application.properties:spring.datasource.url=jdbc:mysql://localhost:3307/quartz_manager spring.datasource.username=root spring.datasource.password=rootpassword
-
Run Backend:
cd quartz-manager-backend mvn spring-boot:runBackend will be available at
http://localhost:8080
-
Install Dependencies:
cd quartz-manager-frontend npm install -
Start Development Server:
npm run dev
Frontend will be available at
http://localhost:5173 -
Configure Proxy (if needed): Update
vite.config.tsto proxy API requests to backend:server: { proxy: { '/api': 'http://localhost:8080' } }
docker-compose up -ddocker-compose down# All services
docker-compose logs -f
# Specific service
docker-compose logs -f app-backend
docker-compose logs -f app-frontend
docker-compose logs -f db# Rebuild all
docker-compose up -d --build
# Rebuild specific service
docker-compose up -d --build app-backend
docker-compose up -d --build app-frontenddocker exec -it quartz-db mysql -u root -p
# Password: rootpasswordThe database is configured in docker-compose.yml:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: quartz_managerAnd in application.properties:
spring.datasource.url=jdbc:mysql://db:3306/quartz_manager
spring.datasource.username=root
spring.datasource.password=rootpasswordConfigure how long execution history is kept (default: 30 days):
quartz.history.retention-days=30The Nginx reverse proxy is configured in nginx/nginx.conf:
- Frontend:
/βhttp://app-frontend:80 - Backend API:
/api/βhttp://app-backend:8080/api/
- Click the "Create Job" button on the dashboard
- Fill in the job details:
- Job Name: Unique identifier for the job
- Job Group: Logical grouping (default: DEFAULT)
- Description: Optional description
- Cron Expression: Schedule (e.g.,
0 */5 * * * ?for every 5 minutes)
- Configure HTTP request:
- Method: GET, POST, PUT, or DELETE
- URL: Target endpoint
- Body: Request body (for POST/PUT)
- Add custom job data (key-value pairs) if needed
- Click "Create Job"
- Click the eye icon (ποΈ) on any job in the list
- View job configuration, cron expression, and execution history
- Click "Back" to return to the dashboard
- Click the history icon (π) on any job in the list
- View:
- Last run datetime
- Next run datetime
- Total executions
- Detailed execution history table
- Click the edit icon (βοΈ) on any job in the list
- Modify job details
- Click "Update Job" to save changes
- Click the delete icon (ποΈ) on any job in the list
- Confirm deletion
GET /api/jobs- List all jobsPOST /api/jobs- Create a new jobPUT /api/jobs/{group}/{name}- Update a jobDELETE /api/jobs/{group}/{name}- Delete a job
GET /api/history/{group}/{name}- Get execution history for a job
If you get a "port already in use" error:
# Check what's using the port (Windows)
netstat -ano | findstr :80
netstat -ano | findstr :3307
# Check what's using the port (Linux/Mac)
lsof -i :80
lsof -i :3307
# Stop the conflicting service or change ports in docker-compose.yml-
Verify MySQL is running:
docker-compose ps
-
Check database logs:
docker-compose logs db
-
Verify connection from backend:
docker-compose logs app-backend | grep -i "database\|connection"
-
Check if frontend container is running:
docker-compose ps app-frontend
-
Rebuild frontend:
docker-compose up -d --build app-frontend
-
Check Nginx logs:
docker-compose logs nginx
-
Check backend logs:
docker-compose logs app-backend
-
Verify backend is healthy:
curl http://localhost:8080/api/jobs
-
Rebuild backend:
cd quartz-manager-backend mvn clean package -DskipTests cd .. docker-compose up -d --build app-backend
-
Verify the
execution_logstable exists:docker exec -it quartz-db mysql -u root -p USE quartz_manager; SHOW TABLES; SELECT * FROM execution_logs LIMIT 10;
-
If table doesn't exist, create it manually:
CREATE TABLE execution_logs ( id BIGINT AUTO_INCREMENT PRIMARY KEY, job_name VARCHAR(200) NOT NULL, job_group VARCHAR(200) NOT NULL, fire_time DATETIME NOT NULL, end_time DATETIME, status VARCHAR(50), duration BIGINT, message TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
To completely reset the application:
# Stop and remove all containers, volumes
docker-compose down -v
# Remove images
docker rmi quartz-manager-app-backend quartz-manager-app-frontend
# Rebuild and start
cd quartz-manager-backend
mvn clean package -DskipTests
cd ..
docker-compose up -d --buildcd quartz-manager-backend
mvn clean packagecd quartz-manager-frontend
npm run build# Backend
cd quartz-manager-backend
mvn test
# Frontend
cd quartz-manager-frontend
npm testSPRING_DATASOURCE_URL- Database URLSPRING_DATASOURCE_USERNAME- Database usernameSPRING_DATASOURCE_PASSWORD- Database passwordQUARTZ_HISTORY_RETENTION_DAYS- History retention period (default: 30)
MYSQL_ROOT_PASSWORD- MySQL root passwordMYSQL_DATABASE- Database name
quartz-manager/
βββ quartz-manager-backend/ # Spring Boot backend
β βββ src/
β β βββ main/
β β βββ java/
β β β βββ com/ppuskar/quartzmanager/
β β β βββ controller/
β β β βββ service/
β β β βββ entity/
β β β βββ repository/
β β β βββ listener/
β β β βββ job/
β β βββ resources/
β β βββ application.properties
β β βββ logback-spring.xml
β βββ Dockerfile
β βββ pom.xml
βββ quartz-manager-frontend/ # React frontend
β βββ src/
β β βββ components/
β β β βββ JobForm.tsx
β β β βββ JobDetails.tsx
β β β βββ JobHistory.tsx
β β β βββ TriggerList.tsx
β β βββ styles/
β β β βββ main.css
β β βββ types.ts
β β βββ App.tsx
β βββ Dockerfile
β βββ package.json
βββ nginx/
β βββ nginx.conf
βββ docker-compose.yml
This project is licensed under the MIT License with Non-Commercial Restriction.
- β Free to use for personal, educational, and non-commercial purposes
- β Open source - you can view, modify, and distribute the code
- β NOT allowed for commercial use without explicit permission
- β Cannot be used in commercial products or services
See the LICENSE file for the full license text.
For commercial licensing inquiries, please contact the project maintainers.
Contributions are welcome! Please note:
- All contributions must comply with the non-commercial license
- By contributing, you agree that your contributions will be licensed under the same license
- Please ensure your code follows the project's coding standards
- Add license headers to any new source files (see
.license-templates/README.md)
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Add license headers to new files (run
.\add-license-headers.ps1) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
For issues and questions, please open an issue on GitHub.