├── .env ├── .gitignore ├── .travis.yml ├── Dockerfile ├── Dockerfile.build ├── README.md ├── build-image.sh ├── charts └── cabot │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── charts │ ├── postgresql-0.11.0.tgz │ └── rabbitmq-0.8.1.tgz │ ├── requirements.lock │ ├── requirements.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── beat.yaml │ ├── config.yaml │ ├── ingress.yaml │ ├── service.yaml │ ├── web.yaml │ └── worker.yaml │ └── values.yaml ├── conf ├── Caddyfile.example ├── default.env └── production.env.example ├── docker-compose-base.yml ├── docker-compose-caddy.yml ├── docker-compose.yml ├── kubernetes ├── beat.yaml ├── config.yaml ├── ingress.yaml ├── namespace.yaml ├── postgres.yaml ├── rabbitmq.yaml ├── web.yaml └── worker.yaml └── upload-to-pypi.sh /.env: -------------------------------------------------------------------------------- 1 | CABOT_VERSION=0.11.12 2 | CABOT_ENVIRONMENT=production 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | .DS_Store 3 | conf/ 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | services: docker 2 | script: 3 | - cp conf/production.env.example conf/production.env 4 | - docker-compose up -d 5 | - sleep 15 6 | - > 7 | curl --silent localhost:5000/setup/ \ 8 | | grep --quiet "Cabot by Arachnys" 9 | - docker-compose down 10 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:4-alpine as builder 2 | 3 | ENV PYTHONUNBUFFERED 1 4 | RUN mkdir /code 5 | 6 | WORKDIR /code 7 | 8 | RUN apk add --no-cache \ 9 | python-dev \ 10 | py-pip \ 11 | postgresql-dev \ 12 | gcc \ 13 | musl-dev \ 14 | libffi-dev \ 15 | openldap-dev \ 16 | ca-certificates \ 17 | bash \ 18 | git 19 | 20 | RUN npm install -g \ 21 | --registry http://registry.npmjs.org/ \ 22 | coffee-script \ 23 | less@1.3 24 | 25 | RUN pip install --upgrade pip wheel twine 26 | # Gevent install is super slow...cache it early 27 | RUN pip install gevent==1.2.1 28 | 29 | ARG CABOT_VERSION 30 | RUN git clone --branch=${CABOT_VERSION} https://github.com/arachnys/cabot /code 31 | 32 | RUN pip install --no-cache-dir -r requirements.txt 33 | RUN pip install --no-cache-dir -r requirements-dev.txt 34 | RUN pip install --no-cache-dir -r requirements-plugins.txt 35 | 36 | RUN python manage.py collectstatic --noinput 37 | RUN python manage.py compress 38 | RUN python setup.py sdist bdist_wheel 39 | 40 | FROM python:2-alpine 41 | 42 | RUN apk add --no-cache \ 43 | python-dev \ 44 | postgresql-dev \ 45 | gcc \ 46 | musl-dev \ 47 | libffi-dev \ 48 | openldap-dev \ 49 | ca-certificates 50 | 51 | # Gevent install is super slow...cache it early 52 | RUN pip install gevent==1.2.1 53 | COPY --from=builder /code/dist/*.whl /tmp/ 54 | RUN pip install --no-cache-dir --disable-pip-version-check /tmp/*.whl 55 | RUN rm -rf /tmp 56 | 57 | RUN apk del \ 58 | python-dev \ 59 | gcc \ 60 | musl-dev \ 61 | libffi-dev \ 62 | openldap-dev 63 | 64 | ENTRYPOINT [] 65 | CMD ["/bin/sh"] 66 | -------------------------------------------------------------------------------- /Dockerfile.build: -------------------------------------------------------------------------------- 1 | FROM node:4-alpine 2 | 3 | ENV PYTHONUNBUFFERED 1 4 | RUN mkdir /code 5 | 6 | WORKDIR /code 7 | 8 | RUN apk add --no-cache \ 9 | python-dev \ 10 | py-pip \ 11 | postgresql-dev \ 12 | gcc \ 13 | musl-dev \ 14 | libffi-dev \ 15 | openldap-dev \ 16 | ca-certificates \ 17 | bash \ 18 | git 19 | 20 | RUN npm install -g \ 21 | --registry http://registry.npmjs.org/ \ 22 | coffee-script \ 23 | less@1.3 24 | 25 | RUN pip install --upgrade pip wheel twine 26 | # Gevent install is super slow...cache it early 27 | RUN pip install gevent==1.2.1 28 | 29 | ARG CABOT_VERSION 30 | RUN git clone --branch=${CABOT_VERSION} https://github.com/arachnys/cabot /code 31 | 32 | RUN pip install --no-cache-dir -r requirements.txt 33 | RUN pip install --no-cache-dir -r requirements-dev.txt 34 | RUN pip install --no-cache-dir -r requirements-plugins.txt 35 | 36 | RUN python manage.py collectstatic --noinput 37 | RUN python manage.py compress 38 | RUN python setup.py sdist bdist_wheel 39 | RUN python setup.py install 40 | 41 | ENTRYPOINT ["sh", "-c"] 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/cabotapp/docker-cabot.svg?branch=master)](https://travis-ci.org/cabotapp/docker-cabot) 2 | 3 | # Supported tags and respective Dockerfile links 4 | 5 | - `0.11.12`, `latest` [(0.11.12/Dockerfile)](https://github.com/cabotapp/docker-cabot/blob/0.11.12/Dockerfile) 6 | - `0.9.2` [(0.9.2/Dockerfile)](https://github.com/cabotapp/docker-cabot/blob/0.9.2/Dockerfile) 7 | - `0.8.6` [(0.8.6/Dockerfile)](https://github.com/cabotapp/docker-cabot/blob/0.8.6/Dockerfile) 8 | - `0.6.0` [(0.6.0/Dockerfile)](https://github.com/cabotapp/docker-cabot/blob/0.6.0/Dockerfile) 9 | 10 | ## What is Cabot? 11 | 12 | Cabot is a free, open-source, self-hosted infrastructure monitoring platform that provides some of the best features of [PagerDuty](http://www.pagerduty.com), [Server Density](http://www.serverdensity.com), [Pingdom](http://www.pingdom.com) and [Nagios](http://www.nagios.org) without their cost and complexity. 13 | 14 | > [github.com/arachnys/cabot](https://github.com/arachnys/cabot) 15 | 16 | # How to use this image 17 | 18 | - Create a Cabot configuration file from the [example in the cabot repository](https://github.com/arachnys/cabot/blob/master/conf/production.env.example) 19 | 20 | - Start a Redis container (or any [Celery Broker](http://docs.celeryproject.org/en/latest/getting-started/brokers/)) 21 | 22 | > `$ docker run -d --name cabot-redis redis` 23 | 24 | - Start a Postgres container 25 | 26 | > `$ docker run -d --name cabot-postgres postgres` 27 | 28 | - Run the initial database migrations 29 | 30 | > `$ docker run --rm --env-file production.env --link cabot-postgres:postgres cabotapp/cabot cabot migrate` 31 | 32 | - Start the cabot webserver 33 | 34 | > `$ docker run -d --name cabot-web --env-file production.env --link cabot-postgres:postgres --link cabot-redis:redis -p 5000:5000 cabotapp/cabot gunicorn cabot.wsgi:application -b 0.0.0.0:5000` 35 | 36 | - You also need a celery worker and scheduler to run the status checks 37 | 38 | > `$ docker run -d --name cabot-worker --env-file production.env --link cabot-postgres:postgres --link cabot-redis:redis cabotapp/cabot celery worker -A cabot` 39 | 40 | > `$ docker run -d --name cabot-beat --env-file production.env --link cabot-postgres:postgres --link cabot-redis:redis cabotapp/cabot celery beat -A cabot` 41 | 42 | # Using kubernetes 43 | 44 | Kubernetes files are templated using [kubetpl](https://github.com/shyiko/kubetpl). 45 | 46 | To apply them, create a configuration file as above (e.g. conf/production.env) and run 47 | 48 | `kubetpl -c . -i .env -s HOST=cabot.example.com kubernetes/* | kubectl apply -f -` 49 | 50 | This will create all the deployments and services you need including the database. It create's an ingress with SSL enabled using [https://github.com/jetstack/cert-manager](cert-manager) - you may wish to change the ingress or change the `web-service` to be a loadbalancer or node port 51 | 52 | ## Using Helm 53 | 54 | Cabot can now be installed using [Helm](https://github.com/kubernetes/helm). 55 | 56 | Simply clone the repository and run 57 | 58 | `helm install charts/cabot --set ingress.hostname=cabot.example.com` 59 | 60 | You'll need to apply any configuration changes in `charts/cabot/values.yaml` 61 | 62 | # Using docker-compose 63 | 64 | You can set up a complete cabot stack easily using docker-compose. 65 | 66 | - Clone the docker-cabot repository 67 | 68 | > `git clone https://github.com/cabotapp/docker-cabot` 69 | 70 | - Copy your cabot config to conf/production.env 71 | 72 | - Run `docker-compose up -d` 73 | 74 | By default the compose file only binds on localhost. We recommend putting it behind a reverse proxy such as [nginx](https://www.nginx.com) or [Caddy](https://caddyserver.com/), but if you want you can change it to bind publicly on port 80. 75 | 76 | There is a [Caddyfile](https://github.com/cabotapp/docker-cabot/blob/master/conf/Caddyfile.example) included which will automatically set up HTTPS using [Let's Encrypt](https://letsencrypt.org/). 77 | 78 | # Issues 79 | 80 | If you have any problems using these images please make a github issue on [cabotapp/docker-cabot](https://github.com/cabotapp/docker-cabot/issues). 81 | 82 | For any problems relating to Cabot itself, please make issues on [arachnys/cabot](https://github.com/arachnys/cabot/issues) 83 | -------------------------------------------------------------------------------- /build-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | set -a 3 | source .env 4 | docker build --squash -t cabotapp/cabot -t cabotapp/cabot:$CABOT_VERSION -t cabotapp/cabot:latest --build-arg CABOT_VERSION=$CABOT_VERSION -f Dockerfile . 5 | -------------------------------------------------------------------------------- /charts/cabot/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /charts/cabot/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: cabot 2 | version: 0.1.0 3 | appVersion: 0.11.12 4 | description: Self-hosted, easily-deployable monitoring and alerts service 5 | keywords: 6 | - cabot 7 | - monitoring 8 | - alerting 9 | - alert 10 | home: http://cabotapp.com/ 11 | maintainers: 12 | - name: frankh 13 | -------------------------------------------------------------------------------- /charts/cabot/README.md: -------------------------------------------------------------------------------- 1 | # Cabot 2 | 3 | [Cabot](https://github.com/arachnys/cabot) is an open source self-hosted infrastructure monitoring platform. 4 | 5 | ## TL;DR; 6 | 7 | ```bash 8 | $ helm install stable/cabot --set ingress.hostname=cabot.example.com 9 | ``` 10 | -------------------------------------------------------------------------------- /charts/cabot/charts/postgresql-0.11.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabotapp/docker-cabot/1f846b962dadc4afa7c3fd225b2362592c688210/charts/cabot/charts/postgresql-0.11.0.tgz -------------------------------------------------------------------------------- /charts/cabot/charts/rabbitmq-0.8.1.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabotapp/docker-cabot/1f846b962dadc4afa7c3fd225b2362592c688210/charts/cabot/charts/rabbitmq-0.8.1.tgz -------------------------------------------------------------------------------- /charts/cabot/requirements.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: postgresql 3 | repository: https://kubernetes-charts.storage.googleapis.com/ 4 | version: 0.11.0 5 | - name: rabbitmq 6 | repository: https://kubernetes-charts.storage.googleapis.com/ 7 | version: 0.8.1 8 | digest: sha256:d1c05489a2bcc63eded86e35c8d5c41ba0f9f8308aaa7cec0d8948adbd60693e 9 | generated: 2018-05-03T14:17:48.662193+01:00 10 | -------------------------------------------------------------------------------- /charts/cabot/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: postgresql 3 | version: 0.11.0 4 | repository: https://kubernetes-charts.storage.googleapis.com/ 5 | - name: rabbitmq 6 | version: 0.8.1 7 | repository: https://kubernetes-charts.storage.googleapis.com/ 8 | -------------------------------------------------------------------------------- /charts/cabot/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Cabot has been deployed! 2 | 3 | To access cabot you will need to have an ingress controller setup (e.g. https://github.com/kubernetes/ingress-nginx), and cert-manager (https://github.com/jetstack/cert-manager). Cert manager should either have a default issuer setup or you need to set the appropriate ingress annotations in values.yaml 4 | 5 | You should be able to access it at https://{{ .Values.ingress.hostname }} -------------------------------------------------------------------------------- /charts/cabot/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /charts/cabot/templates/beat.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "fullname" . }}-beat 5 | labels: 6 | app: {{ template "name" . }}-beat 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "name" . }}-beat 16 | release: {{ .Release.Name }} 17 | spec: 18 | containers: 19 | - name: {{ .Chart.Name }} 20 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 21 | imagePullPolicy: {{ .Values.image.pullPolicy }} 22 | args: 23 | - celery 24 | - beat 25 | - -A 26 | - cabot 27 | envFrom: 28 | - configMapRef: 29 | name: {{ template "fullname" . }}-config 30 | env: 31 | - name: DATABASE_URL 32 | value: postgres://cabot:cabot@{{ .Release.Name }}-postgresql:5432/cabot 33 | - name: CELERY_BROKER_URL 34 | value: amqp://cabot:cabot@{{ .Release.Name }}-rabbitmq:5672// 35 | resources: 36 | {{ toYaml .Values.resources | indent 12 }} 37 | {{- if .Values.nodeSelector }} 38 | nodeSelector: 39 | {{ toYaml .Values.nodeSelector | indent 8 }} 40 | {{- end }} 41 | -------------------------------------------------------------------------------- /charts/cabot/templates/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ template "fullname" .}}-config 5 | data: 6 | {{ toYaml .Values.cabot | indent 2 }} 7 | {{- if not .Values.cabot.DJANGO_SECRET_KEY -}} 8 | DJANGO_SECRET_KEY: {{ randAlphaNum 32 }} 9 | {{- end -}} 10 | -------------------------------------------------------------------------------- /charts/cabot/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := include "fullname" . -}} 3 | apiVersion: extensions/v1beta1 4 | kind: Ingress 5 | metadata: 6 | name: {{ template "fullname" . }} 7 | labels: 8 | app: {{ template "name" . }} 9 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 10 | release: {{ .Release.Name }} 11 | heritage: {{ .Release.Service }} 12 | annotations: 13 | {{- range $key, $value := .Values.ingress.annotations }} 14 | {{ $key }}: {{ $value | quote }} 15 | {{- end }} 16 | spec: 17 | rules: 18 | - host: {{ .Values.ingress.hostname }} 19 | http: 20 | paths: 21 | - path: / 22 | backend: 23 | serviceName: {{ $serviceName }} 24 | servicePort: 5000 25 | {{- if .Values.ingress.tls }} 26 | tls: 27 | {{ toYaml .Values.ingress.tls | indent 4 }} 28 | hosts: 29 | - {{ .Values.ingress.hostname }} 30 | {{- end -}} 31 | {{- end -}} 32 | -------------------------------------------------------------------------------- /charts/cabot/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | app: {{ template "name" . }} 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | type: ClusterIP 12 | ports: 13 | - port: 5000 14 | protocol: TCP 15 | name: {{ template "name" . }}-web 16 | selector: 17 | app: {{ template "name" . }}-web 18 | release: {{ .Release.Name }} 19 | -------------------------------------------------------------------------------- /charts/cabot/templates/web.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "fullname" . }}-web 5 | labels: 6 | app: {{ template "name" . }}-web 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | replicas: {{ .Values.webReplicaCount }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "name" . }}-web 16 | release: {{ .Release.Name }} 17 | spec: 18 | containers: 19 | - name: {{ .Chart.Name }} 20 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 21 | imagePullPolicy: {{ .Values.image.pullPolicy }} 22 | args: 23 | - sh 24 | - -c 25 | - cabot migrate && gunicorn cabot.wsgi:application -b 0.0.0.0:5000 --workers=5 26 | livenessProbe: 27 | httpGet: 28 | path: / 29 | port: 5000 30 | readinessProbe: 31 | httpGet: 32 | path: / 33 | port: 5000 34 | envFrom: 35 | - configMapRef: 36 | name: {{ template "fullname" . }}-config 37 | env: 38 | - name: DATABASE_URL 39 | value: postgres://cabot:cabot@{{ .Release.Name }}-postgresql:5432/cabot 40 | - name: CELERY_BROKER_URL 41 | value: amqp://cabot:cabot@{{ .Release.Name }}-rabbitmq:5672// 42 | resources: 43 | {{ toYaml .Values.resources | indent 12 }} 44 | {{- if .Values.nodeSelector }} 45 | nodeSelector: 46 | {{ toYaml .Values.nodeSelector | indent 8 }} 47 | {{- end }} 48 | -------------------------------------------------------------------------------- /charts/cabot/templates/worker.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "fullname" . }}-worker 5 | labels: 6 | app: {{ template "name" . }}-worker 7 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | spec: 11 | replicas: {{ .Values.workerReplicaCount }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "name" . }}-worker 16 | release: {{ .Release.Name }} 17 | spec: 18 | containers: 19 | - name: {{ .Chart.Name }} 20 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 21 | imagePullPolicy: {{ .Values.image.pullPolicy }} 22 | args: 23 | - celery 24 | - worker 25 | - -A 26 | - cabot 27 | envFrom: 28 | - configMapRef: 29 | name: {{ template "fullname" . }}-config 30 | env: 31 | - name: DATABASE_URL 32 | value: postgres://cabot:cabot@{{ .Release.Name }}-postgresql:5432/cabot 33 | - name: CELERY_BROKER_URL 34 | value: amqp://cabot:cabot@{{ .Release.Name }}-rabbitmq:5672// 35 | resources: 36 | {{ toYaml .Values.resources | indent 12 }} 37 | {{- if .Values.nodeSelector }} 38 | nodeSelector: 39 | {{ toYaml .Values.nodeSelector | indent 8 }} 40 | {{- end }} 41 | -------------------------------------------------------------------------------- /charts/cabot/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for cabot. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | webReplicaCount: 2 5 | workerReplicaCount: 2 6 | image: 7 | repository: cabotapp/cabot 8 | tag: 0.11.12 9 | pullPolicy: IfNotPresent 10 | ingress: 11 | enabled: true 12 | hostname: cabot.local 13 | annotations: 14 | kubernetes.io/tls-acme: "true" 15 | tls: 16 | - secretName: cabot-tls 17 | resources: {} 18 | cabot: 19 | CABOT_PLUGINS_ENABLED: cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email,cabot_alert_slack 20 | DJANGO_SETTINGS_MODULE: cabot.settings 21 | HTTP_USER_AGENT: Cabot 22 | LOG_FILE: /dev/null 23 | ADMIN_EMAIL: admin@example.com 24 | CABOT_FROM_EMAIL: cabot@example.com 25 | EMAIL_HOST: smtp.gmail.com 26 | EMAIL_PASSWORD: '*********' 27 | EMAIL_PORT: "587" 28 | EMAIL_USE_TLS: "1" 29 | EMAIL_USER: '********@gmail.com' 30 | WWW_HTTP_HOST: cabot.local 31 | WWW_SCHEME: https 32 | 33 | postgresql: 34 | postgresUser: "cabot" 35 | postgresPassword: "cabot" 36 | postgresDatabase: "cabot" 37 | 38 | rabbitmq: 39 | rabbitmq: 40 | password: "cabot" 41 | username: "cabot" 42 | -------------------------------------------------------------------------------- /conf/Caddyfile.example: -------------------------------------------------------------------------------- 1 | cabot.example.com { 2 | proxy / http://web:5000 { 3 | header_upstream Host {host} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /conf/default.env: -------------------------------------------------------------------------------- 1 | CABOT_PLUGINS_ENABLED=cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email,cabot_alert_slack 2 | 3 | DJANGO_SETTINGS_MODULE=cabot.settings 4 | 5 | DATABASE_URL=postgres://postgres:postgres_password@postgres:5432/postgres 6 | CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672// 7 | 8 | # It will still log to STDOUT 9 | LOG_FILE=/dev/null 10 | 11 | HTTP_USER_AGENT=Cabot 12 | -------------------------------------------------------------------------------- /conf/production.env.example: -------------------------------------------------------------------------------- 1 | ## Local time zone for this installation. Choices can be found here: 2 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 3 | TIME_ZONE=Etc/UTC 4 | 5 | 6 | ADMIN_EMAIL=admin@example.com 7 | CABOT_FROM_EMAIL=cabot@example.com 8 | 9 | EMAIL_HOST=smtp.gmail.com 10 | EMAIL_USER=********@gmail.com 11 | EMAIL_PASSWORD=********* 12 | EMAIL_PORT=587 13 | EMAIL_USE_TLS=1 14 | 15 | DJANGO_SECRET_KEY= 16 | 17 | WWW_HTTP_HOST=cabot.example.com 18 | WWW_SCHEME=http 19 | 20 | # OPTIONAL SETTINGS 21 | 22 | # URL of calendar to synchronise rota with 23 | # CALENDAR_ICAL_URL=http://www.google.com/calendar/ical/example.ics 24 | 25 | # Hostname of your Graphite server instance (including trailing slash) 26 | # GRAPHITE_API=http://graphite.example.com/ 27 | # GRAPHITE_USER=username 28 | # GRAPHITE_PASS=password 29 | 30 | # From parameter for the graphite request. If not defined, by default take -10 minutes 31 | # GRAPHITE_FROM=-10minute 32 | 33 | # Hipchat integration 34 | # HIPCHAT_ALERT_ROOM=room_name_or_id 35 | # HIPCHAT_API_KEY=your_hipchat_api_key 36 | 37 | # Jenkins integration 38 | # JENKINS_API=https://jenkins.example.com/ 39 | # JENKINS_USER=username 40 | # JENKINS_PASS=password 41 | 42 | # Twilio integration for SMS and telephone alerts 43 | # TWILIO_ACCOUNT_SID=your_account_sid 44 | # TWILIO_AUTH_TOKEN=your_auth_token 45 | # TWILIO_OUTGOING_NUMBER=+14155551234 46 | 47 | # Use for LDAP authentication 48 | # AUTH_LDAP=true 49 | # AUTH_LDAP_SERVER_URI=ldap://ldap.example.com 50 | # AUTH_LDAP_BIND_DN="cn=Manager,dc=example,dc=com" 51 | # AUTH_LDAP_BIND_PASSWORD="" 52 | # AUTH_LDAP_USER_SEARCH="ou=People,dc=example,dc=com" 53 | -------------------------------------------------------------------------------- /docker-compose-base.yml: -------------------------------------------------------------------------------- 1 | version: "2.1" 2 | 3 | services: 4 | base: 5 | image: cabotapp/cabot:${CABOT_VERSION} 6 | env_file: 7 | - conf/default.env 8 | - conf/${CABOT_ENVIRONMENT}.env 9 | restart: always 10 | -------------------------------------------------------------------------------- /docker-compose-caddy.yml: -------------------------------------------------------------------------------- 1 | version: "2.1" 2 | 3 | services: 4 | caddy: 5 | image: abiosoft/caddy 6 | ports: 7 | - '80:80' 8 | - '443:443' 9 | depends_on: 10 | - web 11 | volumes: 12 | - ./.caddy:/root/.caddy 13 | - ./conf/Caddyfile:/etc/Caddyfile 14 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2.1" 2 | 3 | services: 4 | web: 5 | extends: 6 | file: docker-compose-base.yml 7 | service: base 8 | command: sh -c "cabot migrate && gunicorn cabot.wsgi:application -b 0.0.0.0:5000 --workers=5" 9 | ports: 10 | - '127.0.0.1:5000:5000' 11 | depends_on: 12 | - postgres 13 | - rabbitmq 14 | restart: always 15 | 16 | worker: 17 | extends: 18 | file: docker-compose-base.yml 19 | service: base 20 | command: celery worker -A cabot 21 | depends_on: 22 | - web 23 | - postgres 24 | - rabbitmq 25 | restart: always 26 | 27 | beat: 28 | extends: 29 | file: docker-compose-base.yml 30 | service: base 31 | command: celery beat -A cabot 32 | depends_on: 33 | - web 34 | - postgres 35 | - rabbitmq 36 | restart: always 37 | 38 | postgres: 39 | image: postgres:9.6-alpine 40 | volumes: 41 | - data:/var/lib/postgresql/data 42 | environment: 43 | - POSTGRES_PASSWORD=postgres_password 44 | restart: always 45 | 46 | rabbitmq: 47 | image: rabbitmq:3.6-alpine 48 | restart: always 49 | 50 | volumes: 51 | data: 52 | -------------------------------------------------------------------------------- /kubernetes/beat.yaml: -------------------------------------------------------------------------------- 1 | # kubetpl:syntax:$ 2 | apiVersion: extensions/v1beta1 3 | kind: Deployment 4 | metadata: 5 | name: beat 6 | namespace: cabot 7 | labels: 8 | service: beat 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | labels: 14 | service: beat 15 | spec: 16 | containers: 17 | - name: beat 18 | image: cabotapp/cabot:${CABOT_VERSION} 19 | args: 20 | - celery 21 | - beat 22 | - -A 23 | - cabot 24 | envFrom: 25 | - configMapRef: 26 | name: cabot-default-config 27 | - configMapRef: 28 | name: cabot-${CABOT_ENVIRONMENT}-config 29 | restartPolicy: Always 30 | -------------------------------------------------------------------------------- /kubernetes/config.yaml: -------------------------------------------------------------------------------- 1 | # kubetpl:syntax:$ 2 | apiVersion: v1 3 | kubetpl/data-from-env-file: 4 | - ../conf/${CABOT_ENVIRONMENT}.env 5 | kind: ConfigMap 6 | metadata: 7 | name: cabot-${CABOT_ENVIRONMENT}-config 8 | namespace: cabot 9 | --- 10 | apiVersion: v1 11 | kubetpl/data-from-env-file: 12 | - ../conf/default.env 13 | kind: ConfigMap 14 | metadata: 15 | name: cabot-default-config 16 | namespace: cabot 17 | -------------------------------------------------------------------------------- /kubernetes/ingress.yaml: -------------------------------------------------------------------------------- 1 | # kubetpl:syntax:$ 2 | apiVersion: extensions/v1beta1 3 | kind: Ingress 4 | metadata: 5 | name: cabot-ingress 6 | namespace: cabot 7 | annotations: 8 | ingress.kubernetes.io/force-ssl-redirect: "true" 9 | certmanager.k8s.io/cluster-issuer: "letsencrypt-prod" 10 | spec: 11 | tls: 12 | - hosts: 13 | - ${HOST} 14 | secretName: cabot-tls 15 | rules: 16 | - host: ${HOST} 17 | http: 18 | paths: 19 | - path: / 20 | backend: 21 | serviceName: web 22 | servicePort: 5000 23 | -------------------------------------------------------------------------------- /kubernetes/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: cabot 5 | -------------------------------------------------------------------------------- /kubernetes/postgres.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: postgres 5 | namespace: cabot 6 | labels: 7 | service: postgres 8 | spec: 9 | replicas: 1 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | service: postgres 16 | spec: 17 | containers: 18 | - image: postgres:9.6-alpine 19 | name: postgres 20 | volumeMounts: 21 | - mountPath: /var/lib/postgresql/data 22 | name: data 23 | env: 24 | - name: PGDATA 25 | value: /var/lib/postgresql/data/pgdata 26 | restartPolicy: Always 27 | volumes: 28 | - name: data 29 | persistentVolumeClaim: 30 | claimName: data 31 | --- 32 | apiVersion: v1 33 | kind: Service 34 | metadata: 35 | name: postgres 36 | namespace: cabot 37 | spec: 38 | ports: 39 | - name: http-cabot 40 | port: 5432 41 | selector: 42 | service: postgres 43 | --- 44 | apiVersion: v1 45 | kind: PersistentVolumeClaim 46 | metadata: 47 | name: data 48 | namespace: cabot 49 | spec: 50 | accessModes: 51 | - ReadWriteOnce 52 | resources: 53 | requests: 54 | storage: 2000Mi 55 | -------------------------------------------------------------------------------- /kubernetes/rabbitmq.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | service: rabbitmq 6 | name: rabbitmq 7 | namespace: cabot 8 | spec: 9 | replicas: 1 10 | template: 11 | metadata: 12 | labels: 13 | service: rabbitmq 14 | spec: 15 | containers: 16 | - image: rabbitmq:3.6-alpine 17 | name: rabbitmq 18 | restartPolicy: Always 19 | --- 20 | apiVersion: v1 21 | kind: Service 22 | metadata: 23 | name: rabbitmq 24 | namespace: cabot 25 | spec: 26 | ports: 27 | - port: 5672 28 | selector: 29 | service: rabbitmq 30 | -------------------------------------------------------------------------------- /kubernetes/web.yaml: -------------------------------------------------------------------------------- 1 | # kubetpl:syntax:$ 2 | apiVersion: extensions/v1beta1 3 | kind: Deployment 4 | metadata: 5 | name: web 6 | namespace: cabot 7 | labels: 8 | service: web 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | sidecar.istio.io/inject: "true" 15 | labels: 16 | service: web 17 | spec: 18 | containers: 19 | - name: web 20 | image: cabotapp/cabot:${CABOT_VERSION} 21 | args: 22 | - sh 23 | - -c 24 | - cabot migrate && gunicorn cabot.wsgi:application -b 0.0.0.0:5000 --workers=5 25 | envFrom: 26 | - configMapRef: 27 | name: cabot-default-config 28 | restartPolicy: Always 29 | status: {} 30 | --- 31 | apiVersion: v1 32 | kind: Service 33 | metadata: 34 | name: web 35 | namespace: cabot 36 | spec: 37 | ports: 38 | - name: http 39 | port: 5000 40 | selector: 41 | service: web 42 | -------------------------------------------------------------------------------- /kubernetes/worker.yaml: -------------------------------------------------------------------------------- 1 | # kubetpl:syntax:$ 2 | apiVersion: extensions/v1beta1 3 | kind: Deployment 4 | metadata: 5 | name: worker 6 | namespace: cabot 7 | labels: 8 | service: worker 9 | spec: 10 | replicas: 2 11 | template: 12 | metadata: 13 | labels: 14 | service: worker 15 | spec: 16 | containers: 17 | - name: worker 18 | image: cabotapp/cabot:${CABOT_VERSION} 19 | args: 20 | - celery 21 | - worker 22 | - -A 23 | - cabot 24 | envFrom: 25 | - configMapRef: 26 | name: cabot-default-config 27 | - configMapRef: 28 | name: cabot-${CABOT_ENVIRONMENT}-config 29 | restartPolicy: Always 30 | -------------------------------------------------------------------------------- /upload-to-pypi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | set -a 4 | source .env 5 | docker build --no-cache -t cabot-build:$CABOT_VERSION --build-arg CABOT_VERSION=$CABOT_VERSION -f Dockerfile.build . 6 | 7 | while true; do 8 | read -p "Are you sure you want to upload cabot version $CABOT_VERSION? (y/N) " yn 9 | case $yn in 10 | [Yy] ) break;; 11 | * ) exit;; 12 | esac 13 | done 14 | 15 | docker run --rm -v ~/.pypirc:/root/.pypirc cabot-build:$CABOT_VERSION "twine upload dist/*.whl dist/*.tar.gz" 16 | --------------------------------------------------------------------------------