├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── demoapp ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── tasks.py ├── tests.py └── views.py ├── kubernetes ├── celery │ ├── beat-deployment.yaml │ └── worker-deployment.yaml ├── django │ ├── deployment.yaml │ ├── job-migration.yaml │ └── service.yaml ├── flower │ ├── deployment.yaml │ └── service.yaml ├── postgres │ ├── deployment.yaml │ ├── secrets.yaml │ ├── service.yaml │ ├── volume.yaml │ └── volume_claim.yaml └── redis │ ├── deployment.yaml │ └── service.yaml ├── kubernetes_django ├── __init__.py ├── celery.py ├── settings.py ├── urls.py └── wsgi.py ├── manage.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | .static_storage/ 56 | .media/ 57 | local_settings.py 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | # Custom 107 | .DS_Store 108 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6-slim 2 | MAINTAINER Anjaneyulu Batta 3 | RUN apt-get update 4 | ENV PROJECT_ROOT /app 5 | WORKDIR $PROJECT_ROOT 6 | 7 | COPY requirements.txt requirements.txt 8 | RUN pip3 install -r requirements.txt 9 | COPY . . 10 | CMD python manage.py runserver 0.0.0.0:8000 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Anjaneyulu Batta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Django application deployment in kubernetes 2 | 3 | To get started with kubernetes in local environment use Microk8s. Go through the microk8s setup documentation and setup it. 4 | 5 | ## Adding alias to "microk8s.kubectl" to "k8s" 6 | Open `~/.bashrc` and below line at the end of the file. 7 | ```bash 8 | alias k8s="microk8s.kubectl" 9 | ``` 10 | 11 | ## Now, clone this repo using below commands 12 | ``` 13 | git clone git@github.com:AnjaneyuluBatta505/kubernetes_django.git 14 | ``` 15 | 16 | ## Let's start the deployment of the django application and other apps like redis, postgres, flower, etc. 17 | 18 | ### Setting up postgres service 19 | In the postgres we have 4 `yaml` configuration files. 20 | 1. secrets.yaml - Useful when using secret env vaibles in the apps 21 | 2. volume.yaml - Persistent Volume for Postgres database 22 | 3. volume_claim.yaml - This claim lets our deployment application store its data in an external location, so that if one of the application’s containers fails, it can be replaced with a new container and continue accessing its data stored externally, as though an outage never occurred. 23 | 4. deployment.yaml - Deployment to start the application containers 24 | 5. service.yaml - Allows other apps to comminicate with it's related deployment(i.e pods/containers) 25 | 26 | Now, create above objects in kubernetes using below commands 27 | ``` 28 | k8s apply -f kubernetes/postgres/secrets.yaml 29 | k8s apply -f kubernetes/postgres/volume.yaml 30 | k8s apply -f kubernetes/postgres/volume_claim.yaml 31 | k8s apply -f kubernetes/postgres/deployment.yaml 32 | k8s apply -f kubernetes/postgres/service.yaml 33 | ``` 34 | We have successfully created the postgres service in k8s(i.e kubernetes cluster). 35 | 36 | ### Setting up redis service 37 | In the redis we have 2 `yaml` configuration files. 38 | To setup the redis service in k8s execute the below commands 39 | ``` 40 | k8s apply -f kubernetes/redis/deployment.yaml 41 | k8s apply -f kubernetes/redis/service.yaml 42 | ``` 43 | 44 | ### Setting up django app 45 | In django app we have 3 `yaml` configuration files. 46 | To setup the django app in k8s execute the below commands 47 | ``` 48 | k8s apply -f kubernetes/django/job-migration.yaml 49 | k8s apply -f kubernetes/django/deployment.yaml 50 | k8s apply -f kubernetes/django/service.yaml 51 | ``` 52 | 53 | ### Setting up celery app 54 | In celery app we have 2 `yaml` configuration files. 55 | To setup the django app in k8s execute the below commands 56 | ``` 57 | k8s apply -f kubernetes/celery/beat-deployment.yaml 58 | k8s apply -f kubernetes/celery/worker-deployment.yaml 59 | ``` 60 | 61 | ### Setting up flower app 62 | In flower app we have 2 `yaml` configuration files. 63 | To setup the django app in k8s execute the below commands 64 | ``` 65 | k8s apply -f kubernetes/flower/deployment.yaml 66 | k8s apply -f kubernetes/flower/service.yaml 67 | ``` 68 | ## How to debug the pods for errors if any failures occurs ? 69 | ``` 70 | $ k8s get po 71 | NAME READY STATUS RESTARTS AGE 72 | celery-beat-75b5f954-m2pzj 1/1 Running 0 64m 73 | celery-worker-56fc7b88f5-shd87 1/1 Running 0 61m 74 | django-688f76f576-kt4h6 1/1 Error 0 60m 75 | django-migrations-mhng7 0/1 Completed 0 59m 76 | flower-77bf99c799-9drnp 1/1 Running 87 20h 77 | postgres-76dc76ffbb-hzmdc 1/1 Running 2 23h 78 | redis-76f6f4857b-srxlw 1/1 Running 1 20h 79 | ``` 80 | We can debug the pod failure using command `k8s logs `. 81 | Sometimes `k8s describe ` 82 | 83 | ## To access the django app in our local browser 84 | ``` 85 | $ k8s get svc 86 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 87 | django-service NodePort 10.152.183.146 8000:32693/TCP 21h 88 | flower-service NodePort 10.152.183.170 5555:30675/TCP 21h 89 | kubernetes ClusterIP 10.152.183.1 443/TCP 25h 90 | postgres-service ClusterIP 10.152.183.151 5432/TCP 24h 91 | redis-service ClusterIP 10.152.183.89 6379/TCP 21h 92 | 93 | ``` 94 | Visit url "10.152.183.146:8000" (i.e `CLUSTER-IP:PORT`). It's just for testing. 95 | 96 | ## References: 97 | 98 | 1. https://microk8s.io/docs/ 99 | 2. https://kubernetes.io/docs/home/ 100 | 3. https://medium.com/edureka/what-is-kubernetes-container-orchestration-tool-d972741550f6 101 | -------------------------------------------------------------------------------- /demoapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnjaneyuluBatta505/kubernetes_django/7bfa6e6482b2a02899434290aa00e5d9286a3bc0/demoapp/__init__.py -------------------------------------------------------------------------------- /demoapp/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /demoapp/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class DemoappConfig(AppConfig): 5 | name = 'demoapp' 6 | -------------------------------------------------------------------------------- /demoapp/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0.1 on 2019-12-21 04:56 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | dependencies = [ 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='SimpleModel', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('name', models.CharField(max_length=100)), 19 | ], 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /demoapp/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnjaneyuluBatta505/kubernetes_django/7bfa6e6482b2a02899434290aa00e5d9286a3bc0/demoapp/migrations/__init__.py -------------------------------------------------------------------------------- /demoapp/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | class SimpleModel(models.Model): 5 | name = models.CharField(max_length=100) 6 | 7 | -------------------------------------------------------------------------------- /demoapp/tasks.py: -------------------------------------------------------------------------------- 1 | # Python 2 | from datetime import datetime 3 | 4 | # Celery 5 | from celery import shared_task 6 | 7 | 8 | @shared_task 9 | def display_time(): 10 | print("The time is %s :" % str(datetime.now())) 11 | return True 12 | -------------------------------------------------------------------------------- /demoapp/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /demoapp/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /kubernetes/celery/beat-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: celery-beat 5 | labels: 6 | app: celery-beat 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | pod: celery-beat 12 | template: 13 | metadata: 14 | labels: 15 | pod: celery-beat 16 | spec: 17 | containers: 18 | - name: celery-beat 19 | image: registry.hub.docker.com/anjaneyulubatta505/django_app:latest 20 | command: ['celery', '-A', 'kubernetes_django', 'beat', '-l', 'debug'] 21 | env: 22 | - name: POSTGRES_USER 23 | valueFrom: 24 | secretKeyRef: 25 | name: postgres-credentials 26 | key: user 27 | 28 | - name: POSTGRES_PASSWORD 29 | valueFrom: 30 | secretKeyRef: 31 | name: postgres-credentials 32 | key: password 33 | 34 | - name: POSTGRES_HOST 35 | value: postgres-service 36 | 37 | - name: REDIS_HOST 38 | value: redis-service 39 | -------------------------------------------------------------------------------- /kubernetes/celery/worker-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: celery-worker 5 | labels: 6 | deployment: celery-worker 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | pod: celery-worker 12 | template: 13 | metadata: 14 | labels: 15 | pod: celery-worker 16 | spec: 17 | containers: 18 | - name: celery-worker 19 | image: registry.hub.docker.com/anjaneyulubatta505/django_app:latest 20 | command: ['celery', '-A', 'kubernetes_django', 'worker', '-l', 'info'] 21 | env: 22 | - name: POSTGRES_USER 23 | valueFrom: 24 | secretKeyRef: 25 | name: postgres-credentials 26 | key: user 27 | 28 | - name: POSTGRES_PASSWORD 29 | valueFrom: 30 | secretKeyRef: 31 | name: postgres-credentials 32 | key: password 33 | 34 | - name: POSTGRES_HOST 35 | value: postgres-service 36 | 37 | - name: REDIS_HOST 38 | value: redis-service 39 | -------------------------------------------------------------------------------- /kubernetes/django/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: django 5 | labels: 6 | app: django 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | pod: django 12 | template: 13 | metadata: 14 | labels: 15 | pod: django 16 | spec: 17 | containers: 18 | - name: django 19 | image: registry.hub.docker.com/anjaneyulubatta505/django_app:latest 20 | ports: 21 | - containerPort: 8000 22 | env: 23 | - name: POSTGRES_USER 24 | valueFrom: 25 | secretKeyRef: 26 | name: postgres-credentials 27 | key: user 28 | 29 | - name: POSTGRES_PASSWORD 30 | valueFrom: 31 | secretKeyRef: 32 | name: postgres-credentials 33 | key: password 34 | 35 | - name: POSTGRES_HOST 36 | value: postgres-service 37 | 38 | - name: REDIS_HOST 39 | value: redis-service 40 | -------------------------------------------------------------------------------- /kubernetes/django/job-migration.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: django-migrations 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: django 10 | image: registry.hub.docker.com/anjaneyulubatta505/django_app:latest 11 | command: ['python', 'manage.py', 'migrate'] 12 | env: 13 | - name: POSTGRES_USER 14 | valueFrom: 15 | secretKeyRef: 16 | name: postgres-credentials 17 | key: user 18 | 19 | - name: POSTGRES_PASSWORD 20 | valueFrom: 21 | secretKeyRef: 22 | name: postgres-credentials 23 | key: password 24 | 25 | - name: POSTGRES_HOST 26 | value: postgres-service 27 | restartPolicy: Never 28 | backoffLimit: 5 29 | -------------------------------------------------------------------------------- /kubernetes/django/service.yaml: -------------------------------------------------------------------------------- 1 | kind: Service 2 | apiVersion: v1 3 | metadata: 4 | name: django-service 5 | spec: 6 | selector: 7 | pod: django 8 | ports: 9 | - protocol: TCP 10 | port: 8000 11 | targetPort: 8000 12 | type: NodePort 13 | -------------------------------------------------------------------------------- /kubernetes/flower/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: flower 5 | labels: 6 | deployment: flower 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | pod: celery-flower 12 | template: 13 | metadata: 14 | labels: 15 | pod: celery-flower 16 | spec: 17 | containers: 18 | - name: flower 19 | image: registry.hub.docker.com/anjaneyulubatta505/django_app:latest 20 | command: ['celery', 'flower', '-A', 'kubernetes_django' , 'flower'] 21 | ports: 22 | - containerPort: 5555 23 | env: 24 | - name: REDIS_HOST 25 | value: redis-service 26 | resources: 27 | limits: 28 | cpu: 100m 29 | -------------------------------------------------------------------------------- /kubernetes/flower/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: flower-service 5 | spec: 6 | selector: 7 | pod: celery-flower 8 | ports: 9 | - port: 5555 10 | type: NodePort 11 | -------------------------------------------------------------------------------- /kubernetes/postgres/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: postgres 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: postgres-container 10 | template: 11 | metadata: 12 | labels: 13 | app: postgres-container 14 | tier: backend 15 | spec: 16 | containers: 17 | - name: postgres-container 18 | image: postgres:latest 19 | env: 20 | - name: POSTGRES_USER 21 | valueFrom: 22 | secretKeyRef: 23 | name: postgres-credentials 24 | key: user 25 | 26 | - name: POSTGRES_PASSWORD 27 | valueFrom: 28 | secretKeyRef: 29 | name: postgres-credentials 30 | key: password 31 | 32 | - name: POSTGRES_DB 33 | value: kubernetes_django 34 | 35 | ports: 36 | - containerPort: 5432 37 | volumeMounts: 38 | - name: postgres-volume-mount 39 | mountPath: /var/lib/postgresql/data 40 | 41 | volumes: 42 | - name: postgres-volume-mount 43 | persistentVolumeClaim: 44 | claimName: postgres-pvc 45 | -------------------------------------------------------------------------------- /kubernetes/postgres/secrets.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: postgres-credentials 5 | type: Opaque 6 | data: 7 | user: ZGphbmdv 8 | password: MWEyNmQxZzI2ZDFnZXNiP2U3ZGVzYj9lN2Q= -------------------------------------------------------------------------------- /kubernetes/postgres/service.yaml: -------------------------------------------------------------------------------- 1 | kind: Service 2 | apiVersion: v1 3 | metadata: 4 | name: postgres-service 5 | spec: 6 | selector: 7 | app: postgres-container 8 | ports: 9 | - protocol: TCP 10 | port: 5432 11 | targetPort: 5432 12 | # type: NodePort 13 | -------------------------------------------------------------------------------- /kubernetes/postgres/volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: postgres-pv 5 | labels: 6 | type: local 7 | spec: 8 | capacity: 9 | storage: 1Gi 10 | accessModes: 11 | - ReadWriteMany 12 | hostPath: 13 | path: /data/postgres-pv 14 | -------------------------------------------------------------------------------- /kubernetes/postgres/volume_claim.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: postgres-pvc 5 | labels: 6 | type: local 7 | spec: 8 | accessModes: 9 | - ReadWriteMany 10 | resources: 11 | requests: 12 | storage: 1Gi 13 | volumeName: postgres-pv 14 | -------------------------------------------------------------------------------- /kubernetes/redis/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: redis 5 | spec: 6 | selector: 7 | matchLabels: 8 | pod: redis 9 | replicas: 1 10 | template: 11 | metadata: 12 | labels: 13 | pod: redis 14 | spec: 15 | containers: 16 | - name: master 17 | image: redis 18 | resources: 19 | requests: 20 | cpu: 100m 21 | memory: 100Mi 22 | ports: 23 | - containerPort: 6379 24 | -------------------------------------------------------------------------------- /kubernetes/redis/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: redis-service 5 | spec: 6 | selector: 7 | pod: redis 8 | ports: 9 | - protocol: TCP 10 | port: 6379 11 | targetPort: 6379 12 | -------------------------------------------------------------------------------- /kubernetes_django/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, unicode_literals 3 | 4 | # This will make sure the app is always imported when 5 | # Django starts so that shared_task will use this app. 6 | from .celery import app as celery_app 7 | 8 | __all__ = ['celery_app'] 9 | -------------------------------------------------------------------------------- /kubernetes_django/celery.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, unicode_literals 2 | import os 3 | from celery import Celery 4 | 5 | # set the default Django settings module for the 'celery' program. 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kubernetes_django.settings') 7 | 8 | app = Celery('kubernetes_django') 9 | 10 | # Using a string here means the worker doesn't have to serialize 11 | # the configuration object to child processes. 12 | # - namespace='CELERY' means all celery-related configuration keys 13 | # should have a `CELERY_` prefix. 14 | app.config_from_object('django.conf:settings') 15 | 16 | # Load task modules from all registered Django app configs. 17 | app.autodiscover_tasks() 18 | 19 | app.conf.beat_schedule = { 20 | 'display_time-20-seconds': { 21 | 'task': 'demoapp.tasks.display_time', 22 | 'schedule': 20.0 23 | }, 24 | } 25 | 26 | @app.task(bind=True) 27 | def debug_task(self): 28 | print('Request: {0!r}'.format(self.request)) 29 | -------------------------------------------------------------------------------- /kubernetes_django/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for kubernetes_django project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.0. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.0/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.0/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'k1u!rnmwq20#iult1df@u^v^pr!z5j%&q5*vw+c$qvq8ty4vs_' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = ["*"] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 41 | # Running Health Checks 42 | 'health_check', 43 | 'health_check.db', 44 | 'health_check.cache', 45 | 'health_check.contrib.celery', 46 | 47 | # Project 48 | 'demoapp' 49 | ] 50 | 51 | MIDDLEWARE = [ 52 | 'django.middleware.security.SecurityMiddleware', 53 | 'django.contrib.sessions.middleware.SessionMiddleware', 54 | 'django.middleware.common.CommonMiddleware', 55 | 'django.middleware.csrf.CsrfViewMiddleware', 56 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 57 | 'django.contrib.messages.middleware.MessageMiddleware', 58 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 59 | ] 60 | 61 | ROOT_URLCONF = 'kubernetes_django.urls' 62 | 63 | TEMPLATES = [ 64 | { 65 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 66 | 'DIRS': [], 67 | 'APP_DIRS': True, 68 | 'OPTIONS': { 69 | 'context_processors': [ 70 | 'django.template.context_processors.debug', 71 | 'django.template.context_processors.request', 72 | 'django.contrib.auth.context_processors.auth', 73 | 'django.contrib.messages.context_processors.messages', 74 | ], 75 | }, 76 | }, 77 | ] 78 | 79 | WSGI_APPLICATION = 'kubernetes_django.wsgi.application' 80 | 81 | 82 | # Database 83 | # https://docs.djangoproject.com/en/2.0/ref/settings/#databases 84 | 85 | 86 | DATABASES = { 87 | 'default': { 88 | 'ENGINE': 'django.db.backends.postgresql', 89 | 'NAME': 'kubernetes_django', 90 | 'USER': os.getenv('POSTGRES_USER', 'postgres'), 91 | 'PASSWORD': os.getenv('POSTGRES_PASSWORD', 'root'), 92 | 'HOST': os.getenv('POSTGRES_HOST', 'localhost'), 93 | 'PORT': os.getenv('POSTGRES_PORT', 5432) 94 | } 95 | } 96 | 97 | 98 | # Password validation 99 | # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators 100 | 101 | AUTH_PASSWORD_VALIDATORS = [ 102 | { 103 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 104 | }, 105 | { 106 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 107 | }, 108 | { 109 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 110 | }, 111 | { 112 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 113 | }, 114 | ] 115 | 116 | 117 | # Internationalization 118 | # https://docs.djangoproject.com/en/2.0/topics/i18n/ 119 | 120 | LANGUAGE_CODE = 'en-us' 121 | 122 | TIME_ZONE = 'UTC' 123 | 124 | USE_I18N = True 125 | 126 | USE_L10N = True 127 | 128 | USE_TZ = True 129 | 130 | 131 | # Static files (CSS, JavaScript, Images) 132 | # https://docs.djangoproject.com/en/2.0/howto/static-files/ 133 | 134 | STATIC_URL = '/static/' 135 | 136 | # REDIS 137 | REDIS_URL = "redis://{host}:{port}/1".format( 138 | host=os.getenv('REDIS_HOST', 'localhost'), 139 | port=os.getenv('REDIS_PORT', '6379') 140 | ) 141 | 142 | CACHES = { 143 | "default": { 144 | "BACKEND": "django_redis.cache.RedisCache", 145 | "LOCATION": REDIS_URL, 146 | "OPTIONS": { 147 | "CLIENT_CLASS": "django_redis.client.DefaultClient" 148 | }, 149 | "KEY_PREFIX": "example" 150 | } 151 | } 152 | 153 | # CELERY 154 | BROKER_URL = REDIS_URL 155 | CELERY_BROKER_URL = REDIS_URL 156 | CELERY_RESULT_BACKEND = CELERY_BROKER_URL 157 | 158 | -------------------------------------------------------------------------------- /kubernetes_django/urls.py: -------------------------------------------------------------------------------- 1 | """kubernetes_django URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | 19 | urlpatterns = [ 20 | path('admin/', admin.site.urls), 21 | 22 | # Creating the health check endpoint 23 | path(r'', include('health_check.urls')), 24 | ] 25 | -------------------------------------------------------------------------------- /kubernetes_django/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for kubernetes_django project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kubernetes_django.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kubernetes_django.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | celery==5.2.2 2 | Django==2.2.28 3 | django-health-check==3.0.0 4 | django-redis==4.8.0 5 | flower==1.2.0 6 | kombu==4.1.0 7 | psycopg2==2.7.5 8 | redis==2.10.6 9 | --------------------------------------------------------------------------------