[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-8085":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":15,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":15,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":31,"readmeContent":32,"aiSummary":33,"trendingCount":16,"starSnapshotCount":16,"syncStatus":34,"lastSyncTime":35,"discoverSource":36},8085,"ciao","brotandgames\u002Fciao","brotandgames","HTTP checks & tests (private & public) monitoring - check the status of your URL","https:\u002F\u002Fbrotandgames.com\u002Fciao\u002F",null,"Ruby",1968,108,16,1,0,5,19.11,"MIT License",false,"master",true,[24,25,26,27,28,29,30],"alerting","application-monitoring","http","monitoring","prometheus","uptime","website-monitor","2026-06-12 02:01:48","# ciao\n\n[![Latest release](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Frelease\u002Fbrotandgames\u002Fciao.svg)](https:\u002F\u002Fgithub.com\u002Fbrotandgames\u002Fciao\u002Freleases\u002Flatest)\n[![Docker pulls](https:\u002F\u002Fimg.shields.io\u002Fdocker\u002Fpulls\u002Fbrotandgames\u002Fciao.svg)](https:\u002F\u002Fstore.docker.com\u002Fcommunity\u002Fimages\u002Fbrotandgames\u002Fciao)\n[![Website link](https:\u002F\u002Fbrotandgames.com\u002Fassets\u002Fciao-link-website.svg)](https:\u002F\u002Fbrotandgames.com\u002Fciao\u002F)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT-blue.svg)](https:\u002F\u002Fraw.githubusercontent.com\u002Fbrotandgames\u002Fciao\u002Fmaster\u002FLICENSE)\n[![Build Status](https:\u002F\u002Fgithub.com\u002Fbrotandgames\u002Fciao\u002Factions\u002Fworkflows\u002Fmain.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fbrotandgames\u002Fciao\u002Factions\u002F)\n\n**[ciao](https:\u002F\u002Fwww.brotandgames.com\u002Fciao\u002F)** checks HTTP(S) URL endpoints for a HTTP status code (or errors on the lower TCP stack) and sends a notification on status change via E-Mail or Webhooks.\n\nIt uses Cron syntax to schedule the checks and comes along with a Web UI and a RESTful JSON API.\n\n![ciao Checks overview](https:\u002F\u002Fbrotandgames.com\u002Fassets\u002Fciao-checks.png \"ciao Checks overview\")\n*You can find more screenshots on the [Homepage](https:\u002F\u002Fwww.brotandgames.com\u002Fciao\u002F).*\n\n**ciao** (\u002Ftʃaʊ\u002F) - **c**heck **i**n **a**nd **o**ut - borrowed from Italian *ciao* for greeting someone.\n\n*Motivation:* create an open source web application for checking URL statuses with an UI and a REST API which is easy to install and maintain (no external dependencies like Databases, Caches etc.) in public and private environments.\n\nFollow [@brotandgames](https:\u002F\u002Fwww.twitter.com\u002Fbrotandgames) on Twitter to get the latest News like Releases. Use [#ciaohttp](https:\u002F\u002Ftwitter.com\u002Fhashtag\u002Fciaohttp) Hashtag for ciao related stuff.\n\n## Quickstart\n\n```sh\ndocker run --name ciao -p 8090:3000 brotandgames\u002Fciao\n```\n\nOpen http:\u002F\u002Flocalhost:8090 in your webbrowser.\n\n## Features\n\n* Check HTTP\u002FS endpoints in an interval\n* Use Cron syntax like `* * * * *` (every minute), `*\u002F15 * * * *` (every 15 minutes), `@hourly` or `@daily` etc.\n* Keep track of status changes (since version 1.8.0)\n* Check TLS certificate expiration once a day and get a notification if it expires in less than 30 days (since version 1.9.0)\n* Web UI\n* [RESTful JSON API](#rest-api)\n* Get a notification on status change via [E-Mail](smtp_configuration.md) eg. Gmail, Sendgrid, MailChimp etc. (optional)\n* Get a notification on status change via [Webhooks](webhook_configuration.md) eg. Rocket.Chat, Slack etc. (optional)\n* Configuration via ENVIRONMENT variables (suitable for most runtimes)\n* Expose Prometheus Metrics endpoint `\u002Fmetrics` with information to digest by tools like Grafana (optional)\n* Protect with HTTP Basic auth on application basis (optional, only recommended in combination with TLS)\n* Instructions for [installing](#install)\u002F[deploying](#deploy) in\u002Fto different Platforms\n* [Docker Image](#via-docker-image)\n* [Helm Chart](#via-helm)\n* [Terraform Provider](https:\u002F\u002Fgithub.com\u002Fautonubil\u002Fterraform-provider-ciao) (Maintainer: [@autonubil](https:\u002F\u002Fgithub.com\u002Fautonubil))\n\n\n## Configuration\n\nciao is configured via ENVIRONMENT variables following the [12-factor app methodology](https:\u002F\u002F12factor.net\u002Fconfig).\n\n- `SECRET_KEY_BASE` will be auto-generated if you omit it\n- Time zone is configurable per `TIME_ZONE` variable (default: `UTC`) eg. `TIME_ZONE=\"Vienna\"` - you can find all possible values by executing `docker run --rm brotandgames\u002Fciao rake time:zones` (since version 1.2.0)\n- Check [SMTP Configuration](smtp_configuration.md) for all possible configuration variables, notes and example configurations for Gmail, Sendgrid etc.\n- Check [Webhook Configuration](webhook_configuration.md) for instructions how to send (webhook) notifications to RocketChat, Slack etc. (since version 1.4.0)\n- You can enable HTTP Basic auth for ciao by defining `BASIC_AUTH_USERNAME` and `BASIC_AUTH_PASSWORD` eg. `BASIC_AUTH_USERNAME=\"ciao-admin\"` and `BASIC_AUTH_PASSWORD=\"sensitive_password\"` (since version 1.3.0)\n- You can enable a Prometheus Metrics endpoint served under `\u002Fmetrics` by setting `PROMETHEUS_ENABLED=true` - furthermore you can enable HTTP Basic auth for this endpoint by defining `PROMETHEUS_BASIC_AUTH_USERNAME=\"ciao-metrics\"` and `PROMETHEUS_BASIC_AUTH_PASSWORD=\"sensitive_password\"` (since version 1.5.0)\n- Log level is configurable via `CIAO_LOG_LEVEL` variable (default: `WARN`) - levels: DEBUG, INFO, WARN, ERROR, FATAL (since version 1.7.0)\n\n## Install\n\nYou can install ciao via the official Docker image `brotandgames\u002Fciao` or using Git and installing the dependencies manually.\n\nBy mounting a Docker volume you can avoid loosing data on restart or upgrade.\n\nIMPORTANT: Be sure to enable authentication (eg. HTTP Basic auth) and TLS certificates if you serve ciao publicly.\n\n### Via Docker image\n\n```sh\ndocker run \\\n  --name ciao \\\n  -p 8090:3000 \\\n  -e SECRET_KEY_BASE=\"sensitive_secret_key_base\" \\\n  -e SMTP_ADDRESS=smtp.yourhost.com \\\n  -e SMTP_EMAIL_FROM=\"ciao@yourhost.com\" \\\n  -e SMTP_EMAIL_TO=\"you@yourhost.com\" \\\n  -e SMTP_PORT=587 \\\n  -e SMTP_DOMAIN=smtp.yourhost.com \\\n  -e SMTP_AUTHENTICATION=plain \\\n  -e SMTP_ENABLE_STARTTLS_AUTO=true \\\n  -e SMTP_USERNAME=ciao \\\n  -e SMTP_PASSWORD=\"sensitive_password\" \\\n  -v \u002Fopt\u002Fciao\u002Fdata:\u002Fapp\u002Fdb\u002Fsqlite \\\n  brotandgames\u002Fciao\n```\n\nOpen localhost:8090 in your webbrowser.\n\n### Via Docker-compose\n\nCreate docker-compose.yml file\n\n```yaml\nversion: \"3\"\nservices:\n  ciao:\n    image: brotandgames\u002Fciao\n    container_name: ciao\n    ports:\n      - '8090:3000'\n    environment:\n      - SECRET_KEY_BASE=sensitive_secret_key_base\n      - SMTP_ADDRESS=smtp.yourhost.com\n      - SMTP_EMAIL_FROM=ciao@yourhost.com\n      - SMTP_EMAIL_TO=you@yourhost.com\n      - SMTP_PORT=587\n      - SMTP_AUTHENTICATION=plain\n      - SMTP_DOMAIN=smtp.yourhost.com\n      - SMTP_ENABLE_STARTTLS_AUTO=true\n      - SMTP_USERNAME=ciao\n      - SMTP_PASSWORD=sensitive_password\n    volumes:\n      - \u002Fopt\u002Fciao\u002Fdata:\u002Fapp\u002Fdb\u002Fsqlite\u002F\n```\n\nPull and run\n\n```sh\ndocker-compose pull\ndocker-compose up -d\n```\n\nOpen localhost:8090 in the webbrowser.\n\n*Note: if you have problems with environment variables (quoting, spaces etc), take a look at these GitHub issues ([1](https:\u002F\u002Fgithub.com\u002Fbrotandgames\u002Fciao\u002Fissues\u002F40), [2](https:\u002F\u002Fgithub.com\u002Fdocker\u002Fcompose\u002Fissues\u002F2854)) and these Stack Overflow questions ([1](https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F53082932\u002Fyaml-docker-compose-spaces-quotes), [2](https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F41988809\u002Fdocker-compose-how-to-escape-environment-variables))*.\n\n### Via Git clone\n\n```sh\n# Clone repo\ngit clone https:\u002F\u002Fgithub.com\u002Fbrotandgames\u002Fciao\n\ncd ciao\n\n# Install all dependencies (rubygems)\nRAILS_ENV=production bundle install\n\n# Configure\nexport SECRET_KEY_BASE=\"sensitive_secret_key_base\" \\\n  SMTP_ADDRESS=smtp.yourhost.com \\\n  SMTP_EMAIL_FROM=\"ciao@yourhost.com\" \\\n  SMTP_EMAIL_TO=\"you@yourhost.com\" \\\n  SMTP_PORT=587 \\\n  SMTP_DOMAIN=smtp.yourhost.com \\\n  SMTP_AUTHENTICATION=plain \\\n  SMTP_ENABLE_STARTTLS_AUTO=true \\\n  SMTP_USERNAME=ciao \\\n  SMTP_PASSWORD=\"sensitive_password\"\n\n# Precompile assets\nrails assets:precompile\n\n# Run start script - basically this is check SECRET_KEY_BASE, database init\u002Fmigrate and rails server\nRAILS_ENV=production .\u002Fstart.sh\n```\n\nOpen localhost:3000 in the webbrowser.\n\n## REST API\n\n**GET \u002Fchecks.json**\n\nShow collection (array) of all checks\n\n```sh\ncurl -X GET -H \"Content-type: application\u002Fjson\" \u002Fchecks.json\n```\n\n**GET \u002Fchecks\u002F\u003C:id>.json**\n\nShow a specific check\n\n```sh\ncurl -X GET -H \"Content-type: application\u002Fjson\" \u002Fchecks\u002F\u003C:id>.json\n```\n\n**POST \u002Fchecks.json**\n\nCreate a check\n\n```sh\ncurl -X POST -H \"Content-type: application\u002Fjson\" \u002Fchecks.json \\\n  -d '{ \"name\": \"brotandgames.com\", \"active\": true, \"url\": \"https:\u002F\u002Fbrotandgames.com\", \"cron\": \"* * * *\"}'\n```\n\n**PATCH\u002FPUT \u002Fchecks\u002F\u003C:id>.json**\n\nUpdate a check\n\n```sh\ncurl -X PUT -H \"Content-type: application\u002Fjson\" \u002Fchecks\u002F\u003C:id>.json \\\n  -d '{ \"name\": \"brotandgames.com\", \"active\": false, \"url\": \"https:\u002F\u002Fbrotandgames.com\", \"cron\": \"* * * *\"}'\n```\n\n**DELETE \u002Fchecks\u002F\u003C:id>.json**\n\nDelete a check\n\n```sh\ncurl -X DELETE -H \"Content-type: application\u002Fjson\" \u002Fchecks\u002F\u003C:id>.json\n```\n\n## Backup & Restore\n\nState is stored in an internal SQLite database located in `db\u002Fsqlite\u002Fproduction.sqlite3`.\n\n*Note: Prior to version 1.1.0 the database was located in `db\u002F` (missing sqlite subfolder). From 1.1.0 onwards the location is `db\u002Fsqlite\u002F` to enable docker to use a volume.*\n\n### Backup\n\n```sh\ndocker cp ciao:\u002Fapp\u002Fdb\u002Fsqlite\u002Fproduction.sqlite3 production.sqlite3.backup\n```\n\n### Restore\n\n```sh\ndocker cp production.sqlite3.backup ciao:\u002Fapp\u002Fdb\u002Fsqlite\u002Fproduction.sqlite3\ndocker restart ciao\n```\n*Prior to version 1.2.0: visit `\u002Fchecks\u002Fadmin` and recreate the background jobs for active checks.*\n\n\n## Upgrade\n\n1. [Backup](#backup) the database\n2. Run container with new version\n3. [Restore](#restore) the database\n\n## Deploy\n\nHere you'll find instructions for deploying ciao to different platforms like Kubernetes or Dokku.\n\nBy mounting a Docker or Kubernetes volume you can avoid loosing data on restart or upgrade.\n\nIMPORTANT: Be sure to enable authentication (eg. HTTP Basic auth) and TLS certificates if you serve ciao publicly.\n\n### Kubernetes\n\n#### Via Helm\n\n1. Install ciao via `helm upgrade --install`\n\nQuickstart (without configuring)\n\n```sh\nhelm upgrade --install --namespace ciao ciao https:\u002F\u002Fgithub.com\u002Fbrotandgames\u002Fciao\u002Fraw\u002Fmaster\u002Fhelm-chart\u002Fciao-0.5.0.tgz\n```\n\nWith [configuration](#configuration)\n\n```sh\nhelm upgrade --install --namespace ciao ciao https:\u002F\u002Fgithub.com\u002Fbrotandgames\u002Fciao\u002Fraw\u002Fmaster\u002Fhelm-chart\u002Fciao-0.5.0.tgz \\\n  --set env.SECRET_KEY_BASE=\"sensitive_secret_key_base\" \\\n  --set env.SMTP_ADDRESS=smtp.yourhost.com \\\n  --set env.SMTP_EMAIL_FROM=\"ciao@yourhost.com\" \\\n  --set env.SMTP_EMAIL_TO=\"you@yourhost.com\" \\\n  --set env.SMTP_PORT=587 \\\n  --set env.SMTP_DOMAIN=smtp.yourhost.com \\\n  --set env.SMTP_AUTHENTICATION=plain \\\n  --set env.SMTP_ENABLE_STARTTLS_AUTO=true \\\n  --set env.SMTP_USERNAME=ciao \\\n  --set env.SMTP_PASSWORD=\"sensitive_password\"\n```\n\n#### Via kubectl\n\nThe following code snippet will create a Kubernetes\n\n* Namespace `ciao`,\n* Secret `ciao`,\n* Deployment `ciao` and\n* Service `ciao`.\n\n`kubectl apply -f k8s.yaml`\n\n```yaml\n# k8s.yaml\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: ciao\n---\napiVersion: v1\nkind: Secret\nmetadata:\n  name: ciao\n  namespace: ciao\ndata:\n  # all values should be base64 encoded\n  # so some_secret would be c29tZV9zZWNyZXQ=\n  SECRET_KEY_BASE: some_secret\n  SMTP_ADDRESS: smtp_address\n  SMTP_EMAIL_FROM: noreply@somedomain.com\n  SMTP_EMAIL_TO: monitoring@somedomain.com\n  SMTP_PORT: 465\n  SMTP_DOMAIN: mail.somedomain.com\n  SMTP_AUTHENTICATION: plain\n  SMTP_ENABLE_STARTTLS_AUTO: true\n  SMTP_USERNAME: smtp_some_username\n  SMTP_PASSWORD: smtp_some_password\n  SMTP_SSL: true\n  BASIC_AUTH_USERNAME: auth_some_username\n  BASIC_AUTH_PASSWORD: auth_some_password\n---\napiVersion: apps\u002Fv1beta1\nkind: Deployment\nmetadata:\n  name: ciao\n  namespace: ciao\nspec:\n  replicas: 1\n  template:\n    metadata:\n      labels:\n        app: ciao\n    spec:\n      containers:\n      - image: brotandgames\u002Fciao:latest\n        imagePullPolicy: IfNotPresent\n        name: ciao\n        volumeMounts: # Emit if you do not have persistent volumes\n        - mountPath: \u002Fapp\u002Fdb\u002Fsqlite\u002F\n          name: persistent-volume\n          subPath: ciao\n        ports:\n        - containerPort: 3000\n        resources:\n          requests:\n            memory: 256Mi\n            cpu: 200m\n          limits:\n            memory: 512Mi\n            cpu: 400m\n        envFrom:\n        - secretRef:\n            name: ciao\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: ciao\n  namespace: ciao\nspec:\n  ports:\n    - port: 80\n      targetPort: 3000\n      protocol: TCP\n  type: ClusterIP\n  selector:\n    app: ciao\n```\n\n### Dokku\n\n1. Create app\n\n```sh\ndokku apps:create ciao\n```\n\n2. Configure\n\n```sh\ndokku config:set --no-restart ciao \\\n  SECRET_KEY_BASE=\"sensitive_secret_key_base\" \\\n  SMTP_ADDRESS=smtp.yourhost.com \\\n  SMTP_EMAIL_FROM=\"ciao@yourhost.com\" \\\n  SMTP_EMAIL_TO=\"you@yourhost.com\" \\\n  SMTP_PORT=587 \\\n  SMTP_DOMAIN=smtp.yourhost.com \\\n  SMTP_AUTHENTICATION=plain \\\n  SMTP_ENABLE_STARTTLS_AUTO=true \\\n  SMTP_USERNAME=ciao \\\n  SMTP_PASSWORD=\"sensitive_password\"\n```\n\n3. Deploy ciao using your deployment method eg. [Dockerfile Deployment](http:\u002F\u002Fdokku.viewdocs.io\u002Fdokku\u002Fdeployment\u002Fmethods\u002Fdockerfiles\u002F), [Docker Image Deployment](http:\u002F\u002Fdokku.viewdocs.io\u002Fdokku\u002Fdeployment\u002Fmethods\u002Fimages\u002F) etc.\n\n4. Protect your ciao instance by enabling HTTP Basic auth (using [dokku-http-auth](https:\u002F\u002Fgithub.com\u002Fdokku\u002Fdokku-http-auth)) and installing Lets Encrypt certificates via [dokku-letsencrypt](https:\u002F\u002Fgithub.com\u002Fdokku\u002Fdokku-letsencrypt).\n\n\n## Contributing\n\nWe encourage you to contribute to this project in whatever way you like!\n\nReport bugs\u002Ffeature requests in the [issues](https:\u002F\u002Fgithub.com\u002Fbrotandgames\u002Fciao\u002Fissues\u002Fnew\u002Fchoose) section.\n\nWhen contributing to this repository, please first discuss the change you wish to make via issue with the owners of this repository before making a change.\n\n## Versioning\n\n[Semantic Versioning 2.x](https:\u002F\u002Fsemver.org\u002F)\n\nIn a nutshell:\n\n> Given a version number MAJOR.MINOR.PATCH, increment the:\n>\n> 1. MAJOR version when you make incompatible API changes,\n> 2. MINOR version when you add functionality in a backwards-compatible manner, and\n> 3. PATCH version when you make backwards-compatible bug fixes.\n>\n> Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.\n\n## License\n\nciao is released under the [MIT License](https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT).\n\n## Guestbook\n\nWhy not reinvent the [guestbook](guestbook.md)?\n\n## Maintainer\n\nhttps:\u002F\u002Fgithub.com\u002Fbrotandgames\n","ciao 是一个用于监控 HTTP(S) URL 状态的工具，能够检查端点的 HTTP 状态码或底层 TCP 错误，并在状态变化时通过电子邮件或 Webhook 发送通知。其核心功能包括使用 Cron 语法调度检查任务、提供直观的 Web UI 和 RESTful JSON API 接口，支持跟踪状态变化历史以及 TLS 证书到期提醒。此外，ciao 还提供了与 Prometheus 兼容的指标暴露端点，方便集成到 Grafana 等监控系统中。该工具适用于需要对网站或服务进行持续可用性监控的场景，无论是公有云还是私有环境部署都非常便捷，无需依赖外部数据库或其他缓存服务。",2,"2026-06-11 03:15:58","top_language"]