Merge pull request #28 from grafana/hobby-docker-compose

Add docker compose stack
This commit is contained in:
Matvey Kukuy 2022-06-09 17:38:38 +03:00 committed by GitHub
commit 8b1c5e7f24
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 260 additions and 56 deletions

View file

@ -1,76 +1,54 @@
# Grafana OnCall Incident Response
Grafana OnCall, cloud version of Grafana OnCall: https://grafana.com/products/cloud/
<img width="400px" src="docs/img/logo.png">
Developer-friendly, incident response management with brilliant Slack integration.
- Connect monitoring systems
- Collect and analyze data
- On-call rotation
- Automatic escalation
- Never miss alerts with calls and SMS
![Grafana OnCall Screenshot](screenshot.png)
<img width="60%" src="screenshot.png">
- Collect and analyze alerts from multiple monitoring systems
- On-call rotations based on schedules
- Automatic escalations
- Phone calls, SMS, Slack, Telegram notifications
<a href="https://github.com/grafana/oncall/discussions/categories/community-calls"><img width="200px" src="docs/img/community_call.png"></a>
<a href="https://github.com/grafana/oncall/discussions"><img width="200px" src="docs/img/GH_discussions.png"></a>
<a href="https://slack.grafana.com/"><img width="200px" src="docs/img/slack.png"></a>
## Getting Started
OnCall consists of two parts:
1. OnCall backend
2. "Grafana OnCall" plugin you need to install in your Grafana
### How to run OnCall backend
1. An all-in-one image of OnCall is available on docker hub to run it:
### Environments:
Production: [PRODUCTION.md](PRODUCTION.md).
Developer: [DEVELOPER.md](DEVELOPER.md).
### Hobby environment
Download docker-compose.yaml:
```bash
docker run -it --name oncall-backend -p 8000:8000 grafana/oncall-all-in-one
curl https://github.com/... -o docker-compose.yaml
```
2. When the image starts up you will see a message like this:
Set environment:
```bash
👋 This script will issue an invite token to securely connect the frontend.
Maintainers will be happy to help in the slack channel #grafana-oncall: https://slack.grafana.com/
Your invite token: <TOKEN>, use it in the Grafana OnCall plugin.
export DOMAIN=http://localhost
export SECRET_KEY=my_random_secret_must_be_more_than_32_characters_long
export RABBITMQ_PASSWORD=rabbitmq_secret_pw
export MYSQL_PASSWORD=mysql_secret_pw
export COMPOSE_PROFILES=with_grafana
export GRAFANA_USER=admin
export GRAFANA_PASSWORD=admin
```
3. If you started your container detached with -d check the log:
Launch services:
```bash
docker logs oncall-backend
docker-compose -f docker-compose.yml up --build -d
```
### How to install "Grafana OnCall" Plugin and connect with a backend
1. Open Grafana in your browser and login as an Admin
2. Navigate to Configuration &rarr; Plugins
3. Type Grafana OnCall into the "Search Grafana plugins" field
4. Select the Grafana OnCall plugin and press the "Install" button
5. On the Grafana OnCall Plugin page Enable the plugin and go to the Configuration tab you should see a status field with the message
Issue invite token and get further instructions:
```bash
docker-compose -f docker-compose.yml run engine python manage.py issue_invite_for_the_frontend --override
```
OnCall has not been setup, configure & initialize below.
```
6. Fill in configuration fields using the token you got from the backend earlier, then press "Install Configuration"
```
OnCall API URL: (The URL & port used to access OnCall)
http://host.docker.internal:8000
OnCall Invitation Token (Single use token to connect Grafana instance):
Invitation token from docker startup
Grafana URL (URL OnCall will use to talk to this Grafana instance):
http://localhost:3000 (or http://host.docker.internal:3000 if your grafana is running in Docker locally)
```
## Getting Help
- `#grafana-oncall` channel at https://slack.grafana.com/
- Grafana Labs community forum for OnCall: https://community.grafana.com
- File an [issue](https://github.com/grafana/oncall/issues) for bugs, issues and feature suggestions.
## Production Setup
Looking for the production instructions? We're going to release them soon. Please join our Slack channel to be the first to know about them.
## Further Reading
- *Documentation* - [Grafana OnCall](https://grafana.com/docs/grafana-cloud/oncall/)
- *Blog Post* - [Announcing Grafana OnCall, the easiest way to do on-call management](https://grafana.com/blog/2021/11/09/announcing-grafana-oncall/)
- *Presentation* - [Deep dive into the Grafana, Prometheus, and Alertmanager stack for alerting and on-call management](https://grafana.com/go/observabilitycon/2021/alerting/?pg=blog)
## FAQ
- How do I generate a new invitation token to connect plugin with a backend?
```bash
docker exec oncall-backend python manage.py issue_invite_for_the_frontend --override
```

View file

View file

@ -0,0 +1,169 @@
services:
engine:
# TODO: change to the public image once it's public
# image: ...
build: ../../engine
ports:
- 8080:8080
command: >
sh -c "uwsgi --ini uwsgi.ini"
environment:
BASE_URL: https://$DOMAIN
SECRET_KEY: $SECRET_KEY
RABBITMQ_USERNAME: "rabbitmq"
RABBITMQ_PASSWORD: $RABBITMQ_PASSWORD
RABBITMQ_HOST: "rabbitmq"
RABBITMQ_PORT: "5672"
RABBITMQ_DEFAULT_VHOST: "/"
MYSQL_PASSWORD: $MYSQL_PASSWORD
MYSQL_DB_NAME: oncall_hobby
MYSQL_USER: ${MYSQL_USER:-root}
MYSQL_HOST: ${MYSQL_HOST:-mysql}
MYSQL_PORT: 3306
REDIS_URI: redis://redis:6379/0
DJANGO_SETTINGS_MODULE: settings.hobby
depends_on:
mysql:
condition: service_healthy
oncall_db_migration:
condition: service_completed_successfully
rabbitmq:
condition: service_started
redis:
condition: service_started
celery:
# TODO: change to the public image once it's public
build: ../../engine
command: sh -c "./celery_with_exporter.sh"
environment:
BASE_URL: https://$DOMAIN
SECRET_KEY: $SECRET_KEY
RABBITMQ_USERNAME: "rabbitmq"
RABBITMQ_PASSWORD: $RABBITMQ_PASSWORD
RABBITMQ_HOST: "rabbitmq"
RABBITMQ_PORT: "5672"
RABBITMQ_DEFAULT_VHOST: "/"
MYSQL_PASSWORD: $MYSQL_PASSWORD
MYSQL_DB_NAME: oncall_hobby
MYSQL_USER: ${MYSQL_USER:-root}
MYSQL_HOST: ${MYSQL_HOST:-mysql}
MYSQL_PORT: 3306
REDIS_URI: redis://redis:6379/0
DJANGO_SETTINGS_MODULE: settings.hobby
CELERY_WORKER_QUEUE: "celery"
CELERY_WORKER_CONCURRENCY: "1"
CELERY_WORKER_MAX_TASKS_PER_CHILD: "100"
CELERY_WORKER_SHUTDOWN_INTERVAL: "65m"
CELERY_WORKER_BEAT_ENABLED: "True"
depends_on:
mysql:
condition: service_healthy
oncall_db_migration:
condition: service_completed_successfully
rabbitmq:
condition: service_started
redis:
condition: service_started
oncall_db_migration:
build: ../../engine
command: python manage.py migrate --noinput
environment:
BASE_URL: https://$DOMAIN
SECRET_KEY: $SECRET_KEY
RABBITMQ_USERNAME: "rabbitmq"
RABBITMQ_PASSWORD: $RABBITMQ_PASSWORD
RABBITMQ_HOST: "rabbitmq"
RABBITMQ_PORT: "5672"
RABBITMQ_DEFAULT_VHOST: "/"
MYSQL_PASSWORD: $MYSQL_PASSWORD
MYSQL_DB_NAME: oncall_hobby
MYSQL_USER: ${MYSQL_USER:-root}
MYSQL_HOST: ${MYSQL_HOST:-mysql}
MYSQL_PORT: 3306
REDIS_URI: redis://redis:6379/0
DJANGO_SETTINGS_MODULE: settings.hobby
depends_on:
mysql:
condition: service_healthy
mysql:
image: mysql:5.7
platform: linux/x86_64
mem_limit: 500m
cpus: 0.5
command: --default-authentication-plugin=mysql_native_password
restart: always
ports:
- 3306:3306
volumes:
- dbdata:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: $MYSQL_PASSWORD
MYSQL_DATABASE: oncall_hobby
healthcheck:
test: "mysql -uroot -p$MYSQL_PASSWORD oncall_hobby -e 'select 1'"
timeout: 20s
retries: 10
redis:
image: redis
mem_limit: 100m
cpus: 0.1
restart: always
ports:
- 6379:6379
rabbitmq:
image: "rabbitmq:3.7.15-management"
hostname: rabbitmq
mem_limit: 1000m
cpus: 0.5
volumes:
- rabbitmqdata:/var/lib/rabbitmq
environment:
RABBITMQ_DEFAULT_USER: "rabbitmq"
RABBITMQ_DEFAULT_PASS: $RABBITMQ_PASSWORD
RABBITMQ_DEFAULT_VHOST: "/"
mysql_to_create_grafana_db:
image: mysql:5.7
platform: linux/x86_64
command: bash -c "mysql -h ${MYSQL_HOST:-mysql} -uroot -p${MYSQL_PASSWORD:?err} -e 'CREATE DATABASE IF NOT EXISTS grafana CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'"
depends_on:
mysql:
condition: service_healthy
profiles:
- with_grafana
grafana:
image: "grafana/grafana:8.3.2"
mem_limit: 500m
ports:
- 3000:3000
cpus: 0.5
environment:
GF_DATABASE_TYPE: mysql
GF_DATABASE_HOST: ${MYSQL_HOST:-mysql}
GF_DATABASE_USER: ${MYSQL_USER:-root}
GF_DATABASE_PASSWORD: ${MYSQL_PASSWORD:?err}
GF_SECURITY_ADMIN_USER: ${GRAFANA_USER:-admin}
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:?err}
GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: grafana-oncall-app
GF_INSTALL_PLUGINS: grafana-oncall-app
volumes:
- ../../grafana-plugin:/var/lib/grafana/plugins/grafana-plugin
depends_on:
mysql_to_create_grafana_db:
condition: service_completed_successfully
mysql:
condition: service_healthy
profiles:
- with_grafana
volumes:
dbdata:
rabbitmqdata:
caddy_data:
caddy_config:

BIN
docs/img/GH_discussions.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

BIN
docs/img/community_call.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
docs/img/slack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View file

@ -9,4 +9,4 @@ You can use webhooks to send alert group notifications, and also to receive aler
Follow these links to learn more about using webhooks for OnCall alert notifications:
{{< section >}}
{{< section >}}

57
engine/settings/hobby.py Normal file
View file

@ -0,0 +1,57 @@
# flake8: noqa: F405
from random import randrange
# Workaround to use pymysql instead of mysqlclient
import pymysql
from .prod_without_db import * # noqa
pymysql.install_as_MySQLdb()
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": os.environ.get("MYSQL_DB_NAME"),
"USER": os.environ.get("MYSQL_USER"),
"PASSWORD": os.environ["MYSQL_PASSWORD"],
"HOST": os.environ.get("MYSQL_HOST"),
"PORT": os.environ.get("MYSQL_PORT"),
"OPTIONS": {
"charset": "utf8mb4",
"connect_timeout": 1,
},
},
}
RABBITMQ_USERNAME = os.environ.get("RABBITMQ_USERNAME")
RABBITMQ_PASSWORD = os.environ.get("RABBITMQ_PASSWORD")
RABBITMQ_HOST = os.environ.get("RABBITMQ_HOST")
RABBITMQ_PORT = os.environ.get("RABBITMQ_PORT")
CELERY_BROKER_URL = f"amqp://{RABBITMQ_USERNAME}:{RABBITMQ_PASSWORD}@{RABBITMQ_HOST}:{RABBITMQ_PORT}"
MIRAGE_SECRET_KEY = SECRET_KEY
MIRAGE_CIPHER_IV = "1234567890abcdef" # use default
APPEND_SLASH = False
SECURE_SSL_REDIRECT = False
# TODO: OSS: Add these setting to oss settings file. Add Version there too.
OSS_INSTALLATION_FEATURES_ENABLED = True
INSTALLED_APPS += ["apps.oss_installation"] # noqa
CELERY_BEAT_SCHEDULE["send_usage_stats"] = { # noqa
"task": "apps.oss_installation.tasks.send_usage_stats_report",
"schedule": crontab(hour=0, minute=randrange(0, 59)), # Send stats report at a random minute past midnight # noqa
"args": (),
} # noqa
CELERY_BEAT_SCHEDULE["send_cloud_heartbeat"] = { # noqa
"task": "apps.oss_installation.tasks.send_cloud_heartbeat",
"schedule": crontab(minute="*/3"), # noqa
"args": (),
} # noqa
SEND_ANONYMOUS_USAGE_STATS = True