Schedyt is a simple service for scheduling events.
565
Schedyt schedules events based on the provided time zone, ensuring that scheduled tasks are executed according to the specified region's time. You can find the complete list of frequently used short time-zone names here.
Schedyt is a simple service for scheduling events. An event can be a task, a note, a message, or other types of activities. Events can be scheduled:
Additionally, Schedyt supports RabbitMQ Direct Exchange, enabling precise message routing to specific queues based on routing keys.

Use Cases: Scheduled notifications, event-driven workflows, time-based campaigns

CRITICAL - READ BEFORE DEPLOYMENT:
Change default admin credentials (Application: schedyt, Password: Pas5w.rd)
ADMIN_SECRET environment variableprod-api-key or prod-http-basic profilesChange default passwords in examples (database, RabbitMQ)
Never use quick-start profile in production - NO AUTHENTICATION
Always use HTTPS in production with either prod-http-basic or prod-api-key (recommended)
Secure your RabbitMQ instance with strong credentials and network isolation
Example:
environment:
ADMIN_SECRET: YourVeryStrongAdminPassword123!
Security Profiles (choose one):
| Profile | Purpose | Features | Use Case |
|---|---|---|---|
quick-start | Development | ⚠️ No auth, H2 embedded DB, console logging | Local dev, demos |
prod-http-basic | Production | HTTP Basic Authentication | Internal services, simple auth |
prod-api-key | Production ⭐ | API key authentication | External APIs, multiple clients |
Note:
quick-startis fully self-contained — it always runs with an embedded H2 database and must not be combined with a database profile (mariadb,mysql,postgresql).
Database Profiles (required for production):
| Profile | Purpose | Features | Use Case |
|---|---|---|---|
mariadb | Database | MariaDB 10.4+ | Production database |
mysql | Database | MySQL 8.0+ | Production database |
postgresql | Database | PostgreSQL 12+ | Production database |
v1.0.x: Single profile only
JAVA_OPTS: -Dspring.profiles.active=prod-api-key
v1.1.x+: Security + Database (except quick-start)
JAVA_OPTS: -Dspring.profiles.active=postgresql,prod-api-key
| Role | Permissions | Notes |
|---|---|---|
| CLIENT | Manage own events only | Default for new applications |
| ADMIN | Full access to all applications and events | Auto-created on first start with prod-* profiles |
Default ADMIN Credentials:
schedytPas5w.rdADMIN_SECRET environment variableAdmin Application ID (fixed, never changes):
74894a2088394cb7acdc700a85f0443d
Use this ID to generate or retrieve the admin API key via the X-APP-SECRET header:
# Retrieve admin API key (prod-api-key profile)
curl -X GET 'http://localhost:8080/v1/applications/74894a2088394cb7acdc700a85f0443d/keys' \
--header 'X-APP-SECRET: Pas5w.rd'
{
"applicationId": "74894a2088394cb7acdc700a85f0443d",
"applicationName": "schedyt",
"apiKey": "<your-admin-api-key>",
"updatedAt": "..."
}
Use the returned apiKey as the X-API-KEY header value for all subsequent admin requests.
| Use Case | Profile(s) | Security | Database | When to Use |
|---|---|---|---|---|
| Development/Testing | quick-start | ⚠️ None | H2 (embedded) | Local dev, testing, demos |
| Production (Simple) | prod-http-basic + DB | HTTP Basic Auth | External DB required | Internal services, trusted networks |
| Production (Recommended) | prod-api-key + DB | API Key | External DB required | Multiple clients, external APIs, enhanced security |
Database Options (Production only): mariadb, mysql, postgresql
Version-Specific Requirements:
quick-start which remains standalonedocker network create schedyt-network
⚠️ NO AUTHENTICATION - Development only
# RabbitMQ
docker run -d \
--network schedyt-network \
--hostname schedyt-broker \
--name schedyt-broker \
-p 5672:5672 \
-p 15672:15672 \
--env RABBITMQ_DEFAULT_USER=kageyama \
--env RABBITMQ_DEFAULT_PASS=k@geSecre7 \
rabbitmq:3.12.4-management-alpine
# Schedyt
docker run -d \
--network schedyt-network \
--name schedyt-app \
--env JAVA_OPTS=-Dspring.profiles.active=quick-start \
--env BROKER_HOST=schedyt-broker \
-p 8080:8080 \
4dauby/schedyt:latest
# RabbitMQ
docker run -d \
--network schedyt-network \
--hostname schedyt-broker \
--name schedyt-broker \
-p 5672:5672 \
-p 15672:15672 \
--env RABBITMQ_DEFAULT_USER=kageyama \
--env RABBITMQ_DEFAULT_PASS=k@geSecre7 \
rabbitmq:3.12.4-management-alpine
# PostgreSQL
docker run -d \
--network schedyt-network \
--hostname schedyt-db \
--name schedyt-db \
--env POSTGRES_USER=dbUser \
--env POSTGRES_PASSWORD=my-secret-pwd \
--env POSTGRES_DB=schedyt_db \
postgres:17-alpine3.22
# Schedyt
docker run -d \
--network schedyt-network \
--name schedyt-app \
--env JAVA_OPTS=-Dspring.profiles.active=postgresql,prod-api-key \
--env DB_HOST=schedyt-db \
--env SCHEDYT_DB_USER=dbUser \
--env SCHEDYT_DB_PASSWORD=my-secret-pwd \
--env BROKER_HOST=schedyt-broker \
--env BROKER_USER=kageyama \
--env BROKER_PASSWORD=k@geSecre7 \
--env ADMIN_SECRET=YourSecureAdminPassword123! \
-p 8080:8080 \
4dauby/schedyt:latest
For MySQL or MariaDB: Replace the database container and update profile:
| Database | Image | Profile |
|---|---|---|
| MySQL | mysql:8.0 | mysql,prod-api-key |
| MariaDB | mariadb:10.4.4 | mariadb,prod-api-key |
Note: Use MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE environment variables for MySQL/MariaDB
# View logs
docker logs schedyt-app
docker logs schedyt-db
docker logs schedyt-broker
# Stop containers
docker stop schedyt-app schedyt-db schedyt-broker
# Remove containers
docker rm schedyt-app schedyt-db schedyt-broker
# Remove network
docker network rm schedyt-network
curl --location 'http://localhost:8080/v1/applications' \
--header 'Content-Type: application/json' \
--data '{
"name":"my_application_test",
"description":"My scheduling application",
"exchangeName":"quick_exchange",
"secret": "MySecureSecret123!",
"zoneId":"Africa/Abidjan"
}'
Response Example:
{
"id": "9779548b335c470096c6bc6863348af9",
"name": "my_application_test",
"description": "My scheduling application",
"exchangeName": "quick_exchange",
"zoneId": "Africa/Abidjan",
"createdAt": "2026-06-14 03:33:51 GMT"
}
Profile-Specific Values:
quick-start: exchangeName must be quick_exchangeSave the id - you'll need it for scheduling events.
Replace {application_id} with the ID from Step 1.
curl --location 'http://localhost:8080/v2/applications/{application_id}/schedules' \
--header 'Content-Type: application/json' \
--data '{
"eventName":"Test Notification",
"triggerDate": {
"year": 2025,
"month": 10,
"day": 24,
"hour": 14,
"minute": 30,
"second": 0
},
"zoneId":"Africa/Abidjan",
"frequency":0,
"duration":0,
"event":{
"content":"Event successfully scheduled and triggered"
},
"routingKey":"quick_start"
}'
Response Example:
{
"scheduleId": 1,
"eventName": "Test Notification",
"zoneId": "Africa/Abidjan",
"createdAt": "2025-10-23 08:04:43 GMT",
"triggerDate": "2025-10-24 14:30:00 GMT",
"frequency": 0,
"duration": 0,
"triggerFirstAt": null,
"event": {
"content": "Event successfully scheduled and triggered"
},
"application": {
"id": "391f25426ad14f9f9bcfeac3725afc33",
"name": "my_application_test"
},
"routingKey": "quick_start"
}
Profile-Specific Values:
quick-start: routingKey must be quick_startTip: Set triggerDate 2-3 minutes in the future for quick testing.
For quick-start profile - Check container logs:
docker logs schedyt-app
Expected output when event triggers:
[QUICK START][INFO] Event received: {"content":"Event successfully scheduled and triggered"}
For Production profiles - Consume from RabbitMQ:
Python Consumer Example:
#!/usr/bin/env python
import pika
from pika.credentials import PlainCredentials
credentials = PlainCredentials("rabbitUser", "my-secret-pwd")
connection = pika.BlockingConnection(
pika.ConnectionParameters(host='localhost', credentials=credentials))
channel = connection.channel()
channel.exchange_declare(exchange='events_exch', exchange_type='topic')
result = channel.queue_declare('', exclusive=True)
queue_name = result.method.queue
# Bind with your routing key
channel.queue_bind(exchange='events_exch', queue=queue_name, routing_key='your.routing.key')
print(' [*] Waiting for events. Press CTRL+C to exit')
def callback(ch, method, properties, body):
print(f" [x] {method.routing_key}: {body}")
channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
channel.start_consuming()
Register Application [Public] → Schedule Event [Client] v2 requestsservices:
schedyt-db:
container_name: schedyt-db
image: postgres:17-alpine3.22
restart: always
environment:
POSTGRES_USER: userDb
POSTGRES_PASSWORD: my-secret-pwd
POSTGRES_DB: schedyt_db
POSTGRES_INITDB_ARGS: '--data-checksums'
command: |
postgres -c shared_preload_libraries=pgcrypto
ports:
- '5432:5432'
schedyt-broker:
container_name: schedyt-broker
image: rabbitmq:3.12.4-management-alpine
environment:
RABBITMQ_DEFAULT_USER: kageyama
RABBITMQ_DEFAULT_PASS: k@geSecre7
ports:
- "5672:5672"
- "15672:15672"
schedyt-playground:
container_name: 4dauby/schedyt-playground
image: schedyt-playground:latest
depends_on:
- schedyt-broker
environment:
RABBITMQ_HOST: schedyt-broker
RABBITMQ_VHOST: /
RABBITMQ_PORT: 5672
RABBITMQ_USER: kageyama
RABBITMQ_USER_PASSWORD: k@geSecre7
RABBITMQ_EXCHANGE_NAME: playground_exchange
RABBITMQ_QUEUE: q.playground
RABBITMQ_ROUTING_KEY: event.playground.*
ports:
- 3001:3001
schedyt-app:
container_name: schedyt-app
image: 4dauby/schedyt:latest
restart: on-failure
environment:
JAVA_OPTS: -Dspring.profiles.active=postgresql,prod-api-key
DB_HOST: schedyt-db
SCHEDYT_DB_USER: userDb
SCHEDYT_DB_PASSWORD: my-secret-pwd
BROKER_HOST: kageyama
BROKER_USER: k@geSecre7
BROKER_PASSWORD: my-secret-pwd
ADMIN_SECRET: YourSecureAdminPassword123!
ports:
- "8080:8080"
depends_on:
- schedyt-db
- schedyt-broker
networks:
default:
name: schedyt-net
About schedyt-playground: An example client application for Schedyt. It binds a queue (q.playground) to the
playground_exchange exchange with routing key event.playground.* and displays triggered events in
real-time at http://localhost:3001 — it doesn't do anything else with the events it receives.
schedyt-playground listens on a fixed exchange and routing key pattern:
| Parameter | Value |
|---|---|
exchangeName | playground_exchange |
routingKey | event.playground.* |
queue | q.playground |
To send events to it, your application must use the same exchange, and your schedule must use a routing key matching event.playground.<key>.
Step 1 — Register your application with playground_exchange as exchange:
curl -X POST 'http://localhost:8080/v1/applications' \
--header 'Content-Type: application/json' \
--data '{
"name": "playground-app",
"description": "quick test",
"exchangeName": "playground_exchange",
"secret": "myPass",
"zoneId": "Africa/Abidjan"
}'
Step 2 — Schedule an event with a routing key matching event.playground.<key>:
curl -X POST 'http://localhost:8080/v2/applications/{your-app-id}/schedules' \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <your-api-key>' \
--data '{
"eventName": "my first event",
"triggerFirstAt": {
"year": 2025,
"month": 10,
"day": 24,
"hour": 16,
"minute": 2,
"second": 5
},
"zoneId": "Africa/Abidjan",
"frequency": 1,
"duration": 6,
"event": {
"theme": "schedyt",
"content": "Schedyt is the best",
"where": "Abidjan"
},
"routingKey": "event.playground.meeting"
}'
The
routingKeymust start withevent.playground.— the suffix (heremeeting) is free. Once the schedule fires, the event appears in real-time at http://localhost:3001.
Commands:
docker-compose up -d # Start services
docker-compose logs -f # View logs
docker-compose down # Stop services
| Variable | Description | Default Value | Required |
|---|---|---|---|
DB_HOST | Database host | localhost | Yes |
DB_PORT | Database port | 3306 (MariaDB/MySQL), 5432 (PostgreSQL) | No |
SCHEDYT_DB_USER | Database username | schedyt | Yes (production only) |
SCHEDYT_DB_PASSWORD | Database password | Pas5wr.d | Yes (production only) |
BROKER_HOST | RabbitMQ host | localhost | Yes |
BROKER_USER | RabbitMQ username | kageyama | Yes (production only) |
BROKER_PASSWORD | RabbitMQ password | k@geSecre7 | Yes (production only) |
BROKER_PORT | RabbitMQ port | 5672 | No |
ADMIN_SECRET | Admin password | Pas5w.rd | Yes (production only) |
Symptoms: Error messages like "Connection refused" or "Unknown host"
Solutions:
docker psSCHEDYT_DB_USER must match POSTGRES_USERSCHEDYT_DB_PASSWORD must match POSTGRES_PASSWORDPOSTGRES_DB must be set to schedyt_dbSCHEDYT_DB_USER must match MYSQL_USERSCHEDYT_DB_PASSWORD must match MYSQL_PASSWORDMYSQL_DATABASE must be set to schedyt_dbdocker logs schedyt-dbSymptoms: "Failed to connect to RabbitMQ" errors
Solutions:
docker psBROKER_USER and BROKER_PASSWORDdocker logs schedyt-brokerSymptoms: "Invalid username or password" or "Unauthorized" errors
Solutions:
prod-http-basic: Use correct application name and secret in Basic Auth headerprod-api-key: Verify API key is correctly set in request headersprod-http-basic vs prod-api-key)Symptoms: Scheduled events don't execute at the specified time
Solutions:
triggerDate is in the future and correctly formattedzoneId) matches your expectationsdocker logs schedyt-appSymptoms: Container keeps restarting
Solutions:
docker logs schedyt-appIf you encounter issues not covered here:
docker logsThis project is licensed under Apache License Version 2.0. See the LICENSE for details.
Content type
Image
Digest
sha256:4f3989345…
Size
125.7 MB
Last updated
25 days ago
docker pull 4dauby/schedyt:1.1.2