├── .gitignore ├── .idea ├── dj_host_docker.iml ├── inspectionProfiles │ └── profiles_settings.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── Dockerfile ├── README.md ├── dj_host_docker ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py ├── docker-compose.yml ├── docker-entrypoint.sh ├── jobs ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── tasks.py ├── tests.py ├── urls.py └── views.py ├── manage.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | # User-specific stuff: 7 | .idea/workspace.xml 8 | .idea/tasks.xml 9 | 10 | # Sensitive or high-churn files: 11 | .idea/dataSources/ 12 | .idea/dataSources.ids 13 | .idea/dataSources.xml 14 | .idea/dataSources.local.xml 15 | .idea/sqlDataSources.xml 16 | .idea/dynamic.xml 17 | .idea/uiDesigner.xml 18 | 19 | # Gradle: 20 | .idea/gradle.xml 21 | .idea/libraries 22 | 23 | # Mongo Explorer plugin: 24 | .idea/mongoSettings.xml 25 | 26 | ## File-based project format: 27 | *.iws 28 | 29 | ## Plugin-specific files: 30 | 31 | # IntelliJ 32 | /out/ 33 | 34 | # mpeltonen/sbt-idea plugin 35 | .idea_modules/ 36 | 37 | # JIRA plugin 38 | atlassian-ide-plugin.xml 39 | 40 | # Crashlytics plugin (for Android Studio and IntelliJ) 41 | com_crashlytics_export_strings.xml 42 | crashlytics.properties 43 | crashlytics-build.properties 44 | fabric.properties 45 | ### Python template 46 | # Byte-compiled / optimized / DLL files 47 | __pycache__/ 48 | *.py[cod] 49 | *$py.class 50 | 51 | # C extensions 52 | *.so 53 | 54 | # Distribution / packaging 55 | .Python 56 | env/ 57 | build/ 58 | develop-eggs/ 59 | dist/ 60 | downloads/ 61 | eggs/ 62 | .eggs/ 63 | lib/ 64 | lib64/ 65 | parts/ 66 | sdist/ 67 | var/ 68 | *.egg-info/ 69 | .installed.cfg 70 | *.egg 71 | 72 | # PyInstaller 73 | # Usually these files are written by a python script from a template 74 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 75 | *.manifest 76 | *.spec 77 | 78 | # Installer logs 79 | pip-log.txt 80 | pip-delete-this-directory.txt 81 | 82 | # Unit test / coverage reports 83 | htmlcov/ 84 | .tox/ 85 | .coverage 86 | .coverage.* 87 | .cache 88 | nosetests.xml 89 | coverage.xml 90 | *,cover 91 | .hypothesis/ 92 | 93 | # Translations 94 | *.mo 95 | *.pot 96 | 97 | # Django stuff: 98 | *.log 99 | local_settings.py 100 | 101 | # Flask stuff: 102 | instance/ 103 | .webassets-cache 104 | 105 | # Scrapy stuff: 106 | .scrapy 107 | 108 | # Sphinx documentation 109 | docs/_build/ 110 | 111 | # PyBuilder 112 | target/ 113 | 114 | # Jupyter Notebook 115 | .ipynb_checkpoints 116 | 117 | # pyenv 118 | .python-version 119 | 120 | # celery beat schedule file 121 | celerybeat-schedule 122 | 123 | # dotenv 124 | .env 125 | 126 | # virtualenv 127 | .venv/ 128 | venv/ 129 | ENV/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | 134 | # Rope project settings 135 | .ropeproject 136 | ### macOS template 137 | *.DS_Store 138 | .AppleDouble 139 | .LSOverride 140 | 141 | # Icon must end with two \r 142 | Icon 143 | 144 | 145 | # Thumbnails 146 | ._* 147 | 148 | # Files that might appear in the root of a volume 149 | .DocumentRevisions-V100 150 | .fseventsd 151 | .Spotlight-V100 152 | .TemporaryItems 153 | .Trashes 154 | .VolumeIcon.icns 155 | .com.apple.timemachine.donotpresent 156 | 157 | # Directories potentially created on remote AFP share 158 | .AppleDB 159 | .AppleDesktop 160 | Network Trash Folder 161 | Temporary Items 162 | .apdisk 163 | -------------------------------------------------------------------------------- /.idea/dj_host_docker.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 25 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6 2 | ENV PYTHONUNBUFFERED 1 3 | RUN mkdir /code 4 | WORKDIR /code 5 | ADD requirements.txt /code/ 6 | RUN pip install -r requirements.txt 7 | ADD . /code/ 8 | RUN chmod +x /code/docker-entrypoint.sh 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # System in a Box 2 | A working sample project demonstrating Docker containers configured with `host` mode talking to `localhost` services running on Docker host. **Please note:** it only works on a Linux box and will **not** work on your macOS! 3 | 4 | ![system_in_a_box_-_google_slides](https://cloud.githubusercontent.com/assets/618729/22836568/8de8a2b0-efef-11e6-9a4c-253a1dca967d.png) 5 | Ref: https://docs.google.com/presentation/d/1wVE4h_mbSx0LsocRzoZPUpW3t0iQUyUapNeP3H6LphE/edit#slide=id.p 6 | -------------------------------------------------------------------------------- /dj_host_docker/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sivabudh/system-in-a-box/a9402dfcbe988c0ccdbe891817d60cd494e6b305/dj_host_docker/__init__.py -------------------------------------------------------------------------------- /dj_host_docker/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 4 | 5 | SECRET_KEY = '_4zaqw4w4hn_r5pn9-)0ase4)d57cz^&&zc1#^1b_g_9=^3x8o' 6 | 7 | DEBUG = True 8 | 9 | ALLOWED_HOSTS = ['*', ] 10 | 11 | # Application definition 12 | 13 | INSTALLED_APPS = [ 14 | 'django.contrib.admin', 15 | 'django.contrib.auth', 16 | 'django.contrib.contenttypes', 17 | 'django.contrib.sessions', 18 | 'django.contrib.messages', 19 | 'django.contrib.staticfiles', 20 | 'jobs', 21 | 'django_rq', 22 | ] 23 | 24 | MIDDLEWARE = [ 25 | 'django.middleware.security.SecurityMiddleware', 26 | 'django.contrib.sessions.middleware.SessionMiddleware', 27 | 'django.middleware.common.CommonMiddleware', 28 | 'django.middleware.csrf.CsrfViewMiddleware', 29 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 30 | 'django.contrib.messages.middleware.MessageMiddleware', 31 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 32 | ] 33 | 34 | ROOT_URLCONF = 'dj_host_docker.urls' 35 | 36 | TEMPLATES = [ 37 | { 38 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 39 | 'DIRS': [], 40 | 'APP_DIRS': True, 41 | 'OPTIONS': { 42 | 'context_processors': [ 43 | 'django.template.context_processors.debug', 44 | 'django.template.context_processors.request', 45 | 'django.contrib.auth.context_processors.auth', 46 | 'django.contrib.messages.context_processors.messages', 47 | ], 48 | }, 49 | }, 50 | ] 51 | 52 | WSGI_APPLICATION = 'dj_host_docker.wsgi.application' 53 | 54 | DATABASES = { 55 | 'default': { 56 | 'ENGINE': 'django.db.backends.postgresql_psycopg2', 57 | 'NAME': 'dj_host_docker', 58 | 'USER': 'postgres', 59 | 'PASSWORD': 'postgres', 60 | 'HOST': '127.0.0.1', 61 | 'PORT': 5432, 62 | } 63 | } 64 | 65 | RQ_QUEUES = { 66 | 'default': { 67 | 'HOST': 'localhost', 68 | 'PORT': 6379, 69 | 'DB': 8, 70 | }, 71 | } 72 | 73 | AUTH_PASSWORD_VALIDATORS = [ 74 | { 75 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 76 | }, 77 | { 78 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 79 | }, 80 | { 81 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 82 | }, 83 | { 84 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 85 | }, 86 | ] 87 | 88 | LANGUAGE_CODE = 'en-us' 89 | 90 | TIME_ZONE = 'UTC' 91 | 92 | USE_I18N = True 93 | 94 | USE_L10N = True 95 | 96 | USE_TZ = True 97 | 98 | STATIC_URL = '/static/' 99 | 100 | # 101 | # Session storage 102 | # 103 | SESSION_ENGINE = 'redis_sessions.session' 104 | -------------------------------------------------------------------------------- /dj_host_docker/urls.py: -------------------------------------------------------------------------------- 1 | """dj_host_docker URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.10/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: url(r'^$', 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: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url, include 17 | from django.contrib import admin 18 | 19 | urlpatterns = [ 20 | url(r'^admin/', admin.site.urls), 21 | url(r'^jobs/', include('jobs.urls')) 22 | ] 23 | -------------------------------------------------------------------------------- /dj_host_docker/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for dj_host_docker 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/1.10/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", "dj_host_docker.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | app: 5 | build: . 6 | entrypoint: ./docker-entrypoint.sh 7 | command: python manage.py runserver 0.0.0.0:8000 8 | ports: 9 | - "8000:8000" 10 | network_mode: host 11 | worker: 12 | build: . 13 | command: python manage.py rqworker default 14 | network_mode: host 15 | 16 | -------------------------------------------------------------------------------- /docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | python manage.py migrate 3 | exec "$@" -------------------------------------------------------------------------------- /jobs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sivabudh/system-in-a-box/a9402dfcbe988c0ccdbe891817d60cd494e6b305/jobs/__init__.py -------------------------------------------------------------------------------- /jobs/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from jobs.models import Job 4 | 5 | 6 | class JobsModelAdmin(admin.ModelAdmin): 7 | list_display = [ 8 | "name", 9 | 10 | ] 11 | 12 | class Meta: 13 | model = Job 14 | 15 | 16 | admin.site.register(Job, JobsModelAdmin) 17 | -------------------------------------------------------------------------------- /jobs/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class JobsConfig(AppConfig): 5 | name = 'jobs' 6 | -------------------------------------------------------------------------------- /jobs/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.5 on 2017-02-08 11:36 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='Job', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('name', models.CharField(max_length=30)), 21 | ], 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /jobs/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sivabudh/system-in-a-box/a9402dfcbe988c0ccdbe891817d60cd494e6b305/jobs/migrations/__init__.py -------------------------------------------------------------------------------- /jobs/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Job(models.Model): 5 | name = models.CharField(max_length=30) 6 | 7 | def __str__(self) -> str: 8 | return self.name 9 | -------------------------------------------------------------------------------- /jobs/tasks.py: -------------------------------------------------------------------------------- 1 | from jobs.models import Job 2 | 3 | 4 | def add(x: int, y: int) -> int: 5 | result: int = x + y 6 | print(f"{x} + {y} is {result}") 7 | print(Job.objects.all()) 8 | return result 9 | -------------------------------------------------------------------------------- /jobs/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /jobs/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | 3 | from . import views 4 | 5 | urlpatterns = [ 6 | url(r'^$', views.index, name='index'), 7 | ] -------------------------------------------------------------------------------- /jobs/views.py: -------------------------------------------------------------------------------- 1 | from secrets import randbelow 2 | 3 | import django_rq 4 | from django.http import HttpResponse 5 | 6 | from jobs import tasks 7 | 8 | 9 | def index(request): 10 | # 2 random numbers 11 | first_random_number: int = randbelow(10) 12 | second_random_number: int = randbelow(10) 13 | 14 | # Create a task 15 | queue = django_rq.get_queue('default') 16 | queue.enqueue(tasks.add, first_random_number, second_random_number) 17 | 18 | return HttpResponse(f"Adding {first_random_number} with {second_random_number} will yield which number? Find out in the RQ terminal!") 19 | -------------------------------------------------------------------------------- /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", "dj_host_docker.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | "Couldn't import Django. Are you sure it's installed and " 18 | "available on your PYTHONPATH environment variable? Did you " 19 | "forget to activate a virtual environment?" 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | psycopg2 2 | Django 3 | django-redis-sessions 4 | django-rq --------------------------------------------------------------------------------