{"id":21974094,"url":"https://github.com/akornatskyy/scheduler","last_synced_at":"2026-06-05T07:01:34.000Z","repository":{"id":37951683,"uuid":"201011212","full_name":"akornatskyy/scheduler","owner":"akornatskyy","description":":watch: A fully managed cron job scheduler.","archived":false,"fork":false,"pushed_at":"2026-05-31T10:25:52.000Z","size":5229,"stargazers_count":68,"open_issues_count":11,"forks_count":17,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-05-31T12:13:15.889Z","etag":null,"topics":["cron","docker","golang","job","job-scheduler","nodejs","postgres","scheduler","service","spa"],"latest_commit_sha":null,"homepage":"https://akornatskyy.github.io/scheduler","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akornatskyy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-08-07T08:51:16.000Z","updated_at":"2026-05-31T10:23:37.000Z","dependencies_parsed_at":"2023-02-16T11:15:46.560Z","dependency_job_id":"26218815-035d-4284-969a-c8761c2e8c4a","html_url":"https://github.com/akornatskyy/scheduler","commit_stats":{"total_commits":392,"total_committers":3,"mean_commits":"130.66666666666666","dds":0.005102040816326481,"last_synced_commit":"1c8dd8cd6ef8da7e28adcde94a351f701a8eb44a"},"previous_names":[],"tags_count":47,"template":false,"template_full_name":null,"purl":"pkg:github/akornatskyy/scheduler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akornatskyy%2Fscheduler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akornatskyy%2Fscheduler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akornatskyy%2Fscheduler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akornatskyy%2Fscheduler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akornatskyy","download_url":"https://codeload.github.com/akornatskyy/scheduler/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akornatskyy%2Fscheduler/sbom","scorecard":{"id":176528,"data":{"date":"2025-08-11","repo":{"name":"github.com/akornatskyy/scheduler","commit":"0b522e4b4203f7bf15cb396c6865746919b85b3c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/image.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/tests.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":5,"reason":"6 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":10,"reason":"SAST tool detected: CodeQL","details":["Info: SAST configuration detected: CodeQL","Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":3,"reason":"dependency not pinned by hash detected -- score normalized to 3","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/image.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/image.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/image.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/image.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/image.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/image.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/image.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/image.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yaml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/tests.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yaml:58: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/tests.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yaml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/tests.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yaml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/tests.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yaml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/tests.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yaml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/tests.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yaml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/akornatskyy/scheduler/tests.yaml/master?enable=pin","Warn: containerImage not pinned by hash: misc/docker/Dockerfile:1","Warn: containerImage not pinned by hash: misc/docker/Dockerfile:17","Info:   0 out of  10 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned","Info:   0 out of   2 containerImage dependencies pinned","Info:   1 out of   1 goCommand dependencies pinned","Info:   2 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/image.yml:14"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-16T17:47:08.180Z","repository_id":37951683,"created_at":"2025-08-16T17:47:08.180Z","updated_at":"2025-08-16T17:47:08.180Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33932048,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-05T02:00:06.157Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cron","docker","golang","job","job-scheduler","nodejs","postgres","scheduler","service","spa"],"created_at":"2024-11-29T15:37:46.244Z","updated_at":"2026-06-05T07:01:33.974Z","avatar_url":"https://github.com/akornatskyy.png","language":"TypeScript","funding_links":[],"categories":["docker"],"sub_categories":[],"readme":"# Scheduler\n\n[![tests](https://github.com/akornatskyy/scheduler/actions/workflows/tests.yaml/badge.svg)](https://github.com/akornatskyy/scheduler/actions/workflows/tests.yaml) [![Coverage Status](https://coveralls.io/repos/github/akornatskyy/scheduler/badge.svg?branch=master)](https://coveralls.io/github/akornatskyy/scheduler?branch=master)\n\nThe scheduler is a fully managed cron job scheduler. It allows you to schedule virtually any job (e.g. such as calling HTTP/S endpoints). You can automate everything, including retries in case of failure, run jobs right away, on a recurring schedule, or at some point in the future.\n\nThe scheduler allows you to manage all of your automation tasks in a single place via simple UI or command line.\n\nThis service works on any Kubernetes cluster (such as Minikube), it’s easy to deploy with little to no configuration.\n\nIf you’re using this service, **★Star** this repository to show your interest, please!\n\n## Screenshots\n\n| Collections Page | Collection Details Page |\n| --- | --- |\n| ![Screenshot of collections screen](./docs/img/collections.png) | ![Screenshot of collection details screen](./docs/img/collection.png) |\n| **Variables Page** | **Variable Details Page** |\n| ![Screenshot of variables screen](./docs/img/variables.png) | ![Screenshot of variable details screen](./docs/img/variable.png) |\n| **Jobs Page** | **Job Details Page** |\n| ![Screenshot of jobs screen](./docs/img/jobs.png) | ![Screenshot of job details screen](./docs/img/job.png) |\n| **General Error Page** | **Job History Page** |\n| ![Screenshot of general error screen](./docs/img/general-error.png) | ![Screenshot of job history screen](./docs/img/job-history.png) |\n\n## Service Architecture\n\nScheduler Microservice is composed of scheduler service (HTTP API and SPA UI) that uses Postgres for persistence. The service part (HTTP, RESTful API, JSON) is written in Go, UI part is in Node.js (SPA, ES6, react, webpack). Packaged into a docker image and orchestrated by Kubernetes.\n\n![architecture](./docs/img/architecture.png)\n\nThe service contains stateless parts (API) and stateful part (job scheduler and Postgres notification events subscriber).\n\nThere is Open API service [specification](./packages/api-spec/openapi.yaml) published [online](https://akornatskyy.github.io/scheduler).\n\nThe stateful part scales out by subscribing to Postgres notification events and refecting corresponding changes in job scheduler. The job scheduler ensures that only one job is run at a given point of time (although each instance has a full list of enabled jobs and competes to acquire one).\n\n### Database Schema\n\n![database schema](./docs/img/db-schema.png)\n\n## Installation\n\nThere are several installation methods:\n\n1. Running locally.\n2. Running with Docker Compose.\n3. Running on Kubernetes.\n\n\u003e 💡 The service automatically migrates SQL schema.\n\n### Option 1: Running locally\n\nIf you are going to play around first or contribute you might consider to run service locally.\n\nFirst, set up environment variables by copying the example file:\n\n```sh\ncp .env.example .env.local\n```\n\nEdit `.env.local` to configure your database connection:\n\n```sh\nexport DSN=postgres://postgres:@127.0.0.1:5432/scheduler?sslmode=disable\n```\n\nThen source the environment file and install dependencies:\n\n```sh\nsource .env.local  # or `. .env.local`\nmake install\n```\n\n#### Production Build\n\nBuild both the web UI and API server:\n\n```sh\nmake build\n```\n\nThis builds the web app into `apps/api/static` directory. Start the service executable and navigate to \u003chttp://localhost:8080\u003e.\n\n#### Development Mode\n\nFor development with hot reloading, run both the API server and web dev server:\n\n```sh\nmake dev\n```\n\nThis starts:\n\n- API server on \u003chttp://localhost:8080\u003e\n- Web dev server on \u003chttp://localhost:3000\u003e (with hot reloading)\n\nNavigate to \u003chttp://localhost:3000\u003e for the best development experience.\n\nYou can also run them separately:\n\n- `make dev-api` - runs only the API server\n- `make dev-web` - runs only the web development server\n\n### Option 2: Running with Docker Compose\n\nYou can use automatically built Docker [image](https://hub.docker.com/r/akorn/scheduler) from Docker Hub and start service right away.\n\n```sh\ncd deployments/docker\ndocker compose up -d\n```\n\nView output from containers with `docker compose logs -f --tail=10`.\n\nThe service frontend should be available on port _8080_ of your docker machine.\n\nFor more information refer to files at the [`deployments/docker`](./deployments/docker) directory.\n\n### Option 3: Running on Kubernetes\n\nIf you are using Minikube to run a Kubernetes cluster locally, start it via `minikube start`.\n\nRoll out service with `kubectl apply -f deployments/k8s`.\n\nRun `kubectl get pods` to verify the pods are ready and running.\n\n\u003e NOTE: You can expose DB via `kubectl port-forward service/scheduler-db 5432`.\n\nThe service can be accessed with `minikube service scheduler`. Use `minikube dashboard` to access the Kubernetes dashboard running within the cluster.\n\n### Cleanup\n\nIf you have deployed the application with docker compose, you can stop and remove containers with `docker compose down`.\n\nIf you have deployed the application with `kubectl apply -f deployments/k8s`, you can run `kubectl delete -f deployments/k8s` to clean up the deployed resources.\n\nIf you have deployed to minikube, stop the cluster with `minikube stop` or delete virtual machine with `minikube delete`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakornatskyy%2Fscheduler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakornatskyy%2Fscheduler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakornatskyy%2Fscheduler/lists"}