├── .dockerignore ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── db └── .keep ├── demoapp ├── __init__.py ├── admin.py ├── migrations │ └── __init__.py ├── models.py ├── tasks.py ├── tests.py └── views.py ├── docker-compose.yml ├── manage.py ├── media └── .keep ├── nginx ├── Dockerfile └── nginx.conf ├── proj ├── __init__.py ├── celery.py ├── settings │ ├── __init__.py │ ├── base.py │ ├── docker.py │ ├── local-dist.py │ └── test.py ├── urls.py └── wsgi.py ├── requirements.txt ├── requirements ├── compiled.txt ├── local.txt └── production.txt ├── secrets.env.sample └── static └── .keep /.dockerignore: -------------------------------------------------------------------------------- 1 | # Django stuff: 2 | *.log 3 | 4 | # PyBuilder 5 | target/ 6 | 7 | # local settings 8 | proj/settings/local.py 9 | secrets.env 10 | 11 | db/development.sqlite3 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | proj/settings/local.py 53 | db/development.sqlite3 54 | secrets.env 55 | 56 | # Sphinx documentation 57 | docs/_build/ 58 | 59 | # PyBuilder 60 | target/ 61 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5 2 | 3 | ENV PYTHONUNBUFFERED 1 4 | RUN mkdir /code 5 | WORKDIR /code 6 | 7 | # this section is very important to keep a separate layer for the dependencies 8 | RUN mkdir /code/requirements 9 | ADD requirements.txt /code/ 10 | ADD requirements/* /code/requirements/ 11 | RUN pip install -r requirements.txt 12 | 13 | ADD . /code/ 14 | 15 | # Docker specific config 16 | RUN mv proj/settings/docker.py proj/settings/local.py 17 | 18 | # build static assets 19 | RUN SECRET_KEY=temp_value python manage.py collectstatic -v 0 --clear --noinput 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Damien Dormal 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Django Docker Compose # 2 | A production oriented dockerized django app. explained in more details on [my blog](http://damdev.me/docker/2015/10/28/docker-compose-django.html) 3 | 4 | ## Architecture ## 5 | This app is using what one could call a standard django app. Including the followings : 6 | - Django running on gunicorn 7 | - Celery worker 8 | - Postgres database 9 | - RabbitMQ 10 | - Nginx frontend server 11 | 12 | ## Prerequisites ## 13 | This required *docker*, *docker-machine* and *docker-compose* installed on your local machine. More informations on [Docker's website](https://docs.docker.com/installation/mac/) 14 | 15 | ## Running locally ## 16 | ``` 17 | # creates a local host for docker containers, only do once 18 | docker-machine create -d virtualbox local 19 | 20 | # create your config secrets 21 | cp secrets.env.sample secrets.env 22 | 23 | # load the docker env 24 | eval "$(docker-machine env local)" 25 | 26 | # build web image 27 | docker-compose build 28 | 29 | docker-compose up -d 30 | 31 | # run commands inside the containers 32 | docker-compose run app python manage.py migrate 33 | ``` 34 | 35 | ### How can make sure it works ? ### 36 | 1. first you need to know your `local` docker machine ip, using `docker-machine ls`. 37 | 2. Visit http://LOCAL_IP 38 | 3. Check celery's worker logs `docker-compose logs worker` 39 | 40 | 41 | ### Consideration ### 42 | *docker compose* is not deemed production ready. There are some limitations, mainly related to scalability. But I think it is fine for small applications. It is obviously much better to understand how docker compose works. 43 | more info on [docker's website](https://docs.docker.com/compose/production/). 44 | 45 | ### Tutum ### 46 | The big news is [tutum](https://www.tutum.co/) has been [acquired by Docker](http://blog.docker.com/2015/10/docker-acquires-tutum/). Tutum is a could service to manage and deploy Docker applications. It uses a **stack** descriptor, which is compatible with docker-compose yaml format. So you can use my example project to deploy and mange your app with tutum. 47 | -------------------------------------------------------------------------------- /db/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/damsonn/django-docker-compose/8ca8ac95235e03391e1d5130bd2c61b62df9ce79/db/.keep -------------------------------------------------------------------------------- /demoapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/damsonn/django-docker-compose/8ca8ac95235e03391e1d5130bd2c61b62df9ce79/demoapp/__init__.py -------------------------------------------------------------------------------- /demoapp/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /demoapp/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/damsonn/django-docker-compose/8ca8ac95235e03391e1d5130bd2c61b62df9ce79/demoapp/migrations/__init__.py -------------------------------------------------------------------------------- /demoapp/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /demoapp/tasks.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from celery import shared_task 4 | 5 | @shared_task 6 | def hello(greeting): 7 | print('Task recived: {0}'.format(greeting)) 8 | -------------------------------------------------------------------------------- /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 | from django.http import HttpResponse 3 | from demoapp.tasks import hello 4 | 5 | def Hello(request): 6 | greeting = 'Hello, World!' 7 | hello.delay(greeting) 8 | return HttpResponse(greeting) 9 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | db: 2 | image: postgres 3 | env_file: secrets.env 4 | # TODO mount volume - PGDATA or /var/lib/postgresql/data 5 | rabbitmq: 6 | image: rabbitmq 7 | env_file: secrets.env 8 | worker: &app_base 9 | build: . 10 | restart: always 11 | command: celery -A proj worker -l info 12 | links: 13 | - db 14 | - rabbitmq 15 | env_file: secrets.env 16 | environment: 17 | - C_FORCE_ROOT=true 18 | app: 19 | <<: *app_base 20 | command: gunicorn -w 3 -b 0.0.0.0 proj.wsgi 21 | volumes: 22 | - /code/static 23 | ports: 24 | - "8000:8000" 25 | nginx: 26 | build: nginx 27 | ports: 28 | - "80:80" 29 | links: 30 | - app 31 | volumes_from: 32 | - app 33 | -------------------------------------------------------------------------------- /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", "proj.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /media/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/damsonn/django-docker-compose/8ca8ac95235e03391e1d5130bd2c61b62df9ce79/media/.keep -------------------------------------------------------------------------------- /nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | 3 | COPY nginx.conf /etc/nginx/nginx.conf 4 | -------------------------------------------------------------------------------- /nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes 4; 2 | 3 | events { worker_connections 1024; } 4 | 5 | http { 6 | include mime.types; 7 | # fallback in case we can't determine a type 8 | default_type application/octet-stream; 9 | upstream app_server { 10 | # linked by docker 11 | server app:8000 fail_timeout=0; 12 | } 13 | server { 14 | listen 80; 15 | client_max_body_size 4G; 16 | 17 | keepalive_timeout 5; 18 | 19 | root /code/static; 20 | 21 | location / { 22 | # checks for static file, if not found proxy to app 23 | try_files $uri @proxy_to_app; 24 | } 25 | 26 | location @proxy_to_app { 27 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 28 | # enable this if and only if you use HTTPS 29 | # proxy_set_header X-Forwarded-Proto https; 30 | proxy_set_header Host $http_host; 31 | # we don't want nginx trying to do something clever with 32 | # redirects, we set the Host: header above already. 33 | proxy_redirect off; 34 | proxy_pass http://app_server; 35 | } 36 | 37 | error_page 500 502 503 504 /500.html; 38 | location = /500.html { 39 | root /path/to/app/current/public; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /proj/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | # This will make sure the app is always imported when 4 | # Django starts so that shared_task will use this app. 5 | from .celery import app as celery_app 6 | 7 | __all__ = ['celery_app'] 8 | -------------------------------------------------------------------------------- /proj/celery.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | import os 4 | 5 | from celery import Celery 6 | 7 | # set the default Django settings module for the 'celery' program. 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings') 9 | 10 | from django.conf import settings 11 | 12 | app = Celery('proj') 13 | 14 | # Using a string here means the worker will not have to 15 | # pickle the object when using Windows. 16 | app.config_from_object('django.conf:settings') 17 | 18 | # load task modules from all registered Django app configs. 19 | app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 20 | 21 | 22 | @app.task(bind=True) 23 | def debug_task(self): 24 | print('Request: {0!r}'.format(self.request)) 25 | -------------------------------------------------------------------------------- /proj/settings/__init__.py: -------------------------------------------------------------------------------- 1 | """ Settings for proj """ 2 | 3 | from .base import * 4 | try: 5 | from .local import * 6 | except ImportError as exc: 7 | exc.args = tuple( 8 | ['%s (did you rename settings/local-dist.py?)' % exc.args[0]]) 9 | raise exc 10 | -------------------------------------------------------------------------------- /proj/settings/base.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is your project's main settings file that can be committed to your 3 | repo. If you need to override a setting locally, use local.py 4 | """ 5 | 6 | import os 7 | import logging 8 | 9 | # Normally you should not import ANYTHING from Django directly 10 | # into your settings, but ImproperlyConfigured is an exception. 11 | from django.core.exceptions import ImproperlyConfigured 12 | 13 | 14 | def get_env_setting(setting): 15 | """ Get the environment setting or return exception """ 16 | try: 17 | return os.environ[setting] 18 | except KeyError: 19 | error_msg = "Set the %s env variable" % setting 20 | raise ImproperlyConfigured(error_msg) 21 | 22 | 23 | # Your project root 24 | PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__) + "../../../") 25 | 26 | SUPPORTED_NONLOCALES = ['media', 'admin', 'static'] 27 | 28 | # Language code for this installation. All choices can be found here: 29 | # http://www.i18nguy.com/unicode/language-identifiers.html 30 | LANGUAGE_CODE = 'en-us' 31 | 32 | # Defines the views served for root URLs. 33 | ROOT_URLCONF = 'proj.urls' 34 | 35 | # Application definition 36 | INSTALLED_APPS = ( 37 | # Django contrib apps 38 | 'django.contrib.auth', 39 | 'django.contrib.contenttypes', 40 | 'django.contrib.sessions', 41 | 'django.contrib.messages', 42 | 'django.contrib.admin', 43 | 'django.contrib.humanize', 44 | 'django.contrib.syndication', 45 | 'django.contrib.staticfiles', 46 | 47 | # Third-party apps, patches, fixes 48 | 'djcelery', 49 | 'debug_toolbar', 50 | #'compressor', 51 | 52 | # Local apps, referenced via appname 53 | 'demoapp' 54 | ) 55 | 56 | # Place bcrypt first in the list, so it will be the default password hashing 57 | # mechanism 58 | PASSWORD_HASHERS = ( 59 | 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', 60 | 'django.contrib.auth.hashers.BCryptPasswordHasher', 61 | 'django.contrib.auth.hashers.PBKDF2PasswordHasher', 62 | 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', 63 | 'django.contrib.auth.hashers.SHA1PasswordHasher', 64 | 'django.contrib.auth.hashers.MD5PasswordHasher', 65 | 'django.contrib.auth.hashers.CryptPasswordHasher', 66 | ) 67 | 68 | # Sessions 69 | # 70 | # By default, be at least somewhat secure with our session cookies. 71 | SESSION_COOKIE_HTTPONLY = True 72 | 73 | # Set this to true if you are using https 74 | SESSION_COOKIE_SECURE = False 75 | 76 | # Absolute filesystem path to the directory that will hold user-uploaded files. 77 | # Example: "/home/media/media.example.com/media/" 78 | MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media') 79 | 80 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a 81 | # trailing slash. 82 | # Examples: "http://media.example.com/media/", "http://example.com/media/" 83 | MEDIA_URL = '/media/' 84 | 85 | # Absolute path to the directory static files should be collected to. 86 | # Don't put anything in this directory yourself; store your static files 87 | # in apps' "static/" subdirectories and in STATICFILES_DIRS. 88 | # Example: "/home/media/media.example.com/static/" 89 | STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static') 90 | 91 | # URL prefix for static files. 92 | # Example: "http://media.example.com/static/" 93 | STATIC_URL = '/static/' 94 | 95 | # Additional locations of static files 96 | STATICFILES_DIRS = ( 97 | # Put strings here, like "/home/html/static" or "C:/www/django/static". 98 | # Always use forward slashes, even on Windows. 99 | # Don't forget to use absolute paths, not relative paths. 100 | ) 101 | 102 | # If you set this to False, Django will make some optimizations so as not 103 | # to load the internationalization machinery. 104 | USE_I18N = True 105 | 106 | # If you set this to False, Django will not format dates, numbers and 107 | # calendars according to the current locale 108 | USE_L10N = True 109 | 110 | # If you set this to False, Django will not use timezone-aware datetimes. 111 | USE_TZ = True 112 | 113 | # Local time zone for this installation. Choices can be found here: 114 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 115 | # although not all choices may be available on all operating systems. 116 | # If running in a Windows environment this must be set to the same as your 117 | # system time zone. 118 | TIME_ZONE = 'America/Los_Angeles' 119 | 120 | # List of finder classes that know how to find static files in 121 | # various locations. 122 | STATICFILES_FINDERS = ( 123 | 'django.contrib.staticfiles.finders.FileSystemFinder', 124 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 125 | 'compressor.finders.CompressorFinder', 126 | ) 127 | 128 | MIDDLEWARE_CLASSES = [ 129 | 'django.contrib.sessions.middleware.SessionMiddleware', 130 | 'django.middleware.locale.LocaleMiddleware', 131 | 'django.middleware.common.CommonMiddleware', 132 | 'django.middleware.csrf.CsrfViewMiddleware', 133 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 134 | 'django.contrib.messages.middleware.MessageMiddleware', 135 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 136 | 'debug_toolbar.middleware.DebugToolbarMiddleware', 137 | ] 138 | 139 | TEMPLATE_CONTEXT_PROCESSORS = [ 140 | 'django.contrib.auth.context_processors.auth', 141 | 'django.core.context_processors.debug', 142 | 'django.core.context_processors.media', 143 | 'django.core.context_processors.request', 144 | 'django.core.context_processors.i18n', 145 | 'django.core.context_processors.static', 146 | 'django.core.context_processors.csrf', 147 | 'django.core.context_processors.tz', 148 | 'django.contrib.messages.context_processors.messages', 149 | ] 150 | 151 | TEMPLATE_DIRS = ( 152 | # Put strings here, like "/home/html/django_templates" or 153 | # "C:/www/django/templates". 154 | # Always use forward slashes, even on Windows. 155 | # Don't forget to use absolute paths, not relative paths. 156 | os.path.join(PROJECT_ROOT, 'templates'), 157 | ) 158 | 159 | # List of callables that know how to import templates from various sources. 160 | TEMPLATE_LOADERS = ( 161 | 'django.template.loaders.filesystem.Loader', 162 | 'django.template.loaders.app_directories.Loader', 163 | ) 164 | 165 | TEST_RUNNER = 'django.test.runner.DiscoverRunner' 166 | 167 | 168 | def custom_show_toolbar(request): 169 | """ Only show the debug toolbar to users with the superuser flag. """ 170 | return request.user.is_superuser 171 | 172 | 173 | DEBUG_TOOLBAR_CONFIG = { 174 | 'INTERCEPT_REDIRECTS': False, 175 | 'SHOW_TOOLBAR_CALLBACK': 'proj.settings.base.custom_show_toolbar', 176 | 'HIDE_DJANGO_SQL': True, 177 | 'TAG': 'body', 178 | 'SHOW_TEMPLATE_CONTEXT': True, 179 | 'ENABLE_STACKTRACES': True, 180 | } 181 | 182 | # Uncomment the following setting if you get an ImportError such as: 183 | # ImproperlyConfigured: The included urlconf projectname.urls doesn't have any patterns in it 184 | # See: 185 | # http://stackoverflow.com/questions/20963856/improperlyconfigured-the-included-urlconf-project-urls-doesnt-have-any-patte/21005346#21005346 186 | # http://django-debug-toolbar.readthedocs.org/en/1.0/installation.html#explicit-setup 187 | #DEBUG_TOOLBAR_PATCH_SETTINGS = False 188 | 189 | # DEBUG_TOOLBAR_PANELS = ( 190 | # #'debug_toolbar_user_panel.panels.UserPanel', 191 | # 'debug_toolbar.panels.version.VersionDebugPanel', 192 | # 'debug_toolbar.panels.timer.TimerDebugPanel', 193 | # 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel', 194 | # 'debug_toolbar.panels.headers.HeaderDebugPanel', 195 | # 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel', 196 | # 'debug_toolbar.panels.template.TemplateDebugPanel', 197 | # 'debug_toolbar.panels.sql.SQLDebugPanel', 198 | # 'debug_toolbar.panels.signals.SignalDebugPanel', 199 | # 'debug_toolbar.panels.logger.LoggingPanel', 200 | # ) 201 | 202 | # Specify a custom user model to use 203 | #AUTH_USER_MODEL = 'accounts.MyUser' 204 | 205 | FILE_UPLOAD_PERMISSIONS = 0o0664 206 | 207 | # The WSGI Application to use for runserver 208 | WSGI_APPLICATION = 'proj.wsgi.application' 209 | 210 | # Define your database connections 211 | DATABASES = { 212 | 'default': { 213 | 'ENGINE': 'django.db.backends.', 214 | 'NAME': '', 215 | 'USER': '', 216 | 'PASSWORD': '', 217 | 'HOST': '', 218 | 'PORT': '', 219 | #'OPTIONS': { 220 | # 'init_command': 'SET storage_engine=InnoDB', 221 | # 'charset' : 'utf8', 222 | # 'use_unicode' : True, 223 | #}, 224 | #'TEST_CHARSET': 'utf8', 225 | #'TEST_COLLATION': 'utf8_general_ci', 226 | }, 227 | # 'slave': { 228 | # ... 229 | # }, 230 | } 231 | 232 | # Uncomment this and set to all slave DBs in use on the site. 233 | # SLAVE_DATABASES = ['slave'] 234 | 235 | # Recipients of traceback emails and other notifications. 236 | ADMINS = ( 237 | # ('Your Name', 'your_email@domain.com'), 238 | ) 239 | MANAGERS = ADMINS 240 | 241 | # SECURITY WARNING: don't run with debug turned on in production! 242 | # Debugging displays nice error messages, but leaks memory. Set this to False 243 | # on all server instances and True only for development. 244 | DEBUG = TEMPLATE_DEBUG = False 245 | 246 | # Is this a development instance? Set this to True on development/master 247 | # instances and False on stage/prod. 248 | DEV = False 249 | 250 | # Hosts/domain names that are valid for this site; required if DEBUG is False 251 | # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts 252 | ALLOWED_HOSTS = [] 253 | 254 | # SECURITY WARNING: keep the secret key used in production secret! 255 | # Hardcoded values can leak through source control. 256 | # This is an example method of getting the value from an environment setting. 257 | # Uncomment to use, and then make sure you set the SECRET_KEY environment variable. 258 | # This is good to use in production, and on services that support it such as Heroku. 259 | #SECRET_KEY = get_env_setting('SECRET_KEY') 260 | 261 | INTERNAL_IPS = ('127.0.0.1') 262 | 263 | # Enable this option for memcached 264 | #CACHE_BACKEND= "memcached://127.0.0.1:11211/" 265 | 266 | # Set this to true if you use a proxy that sets X-Forwarded-Host 267 | #USE_X_FORWARDED_HOST = False 268 | 269 | SERVER_EMAIL = "webmaster@example.com" 270 | DEFAULT_FROM_EMAIL = "webmaster@example.com" 271 | SYSTEM_EMAIL_PREFIX = "[proj]" 272 | 273 | ## Log settings 274 | 275 | LOG_LEVEL = logging.INFO 276 | HAS_SYSLOG = True 277 | SYSLOG_TAG = "http_app_proj" # Make this unique to your project. 278 | # Remove this configuration variable to use your custom logging configuration 279 | LOGGING_CONFIG = None 280 | LOGGING = { 281 | 'version': 1, 282 | 'loggers': { 283 | 'proj': { 284 | 'level': "DEBUG" 285 | } 286 | } 287 | } 288 | 289 | # Common Event Format logging parameters 290 | #CEF_PRODUCT = 'proj' 291 | #CEF_VENDOR = 'Your Company' 292 | #CEF_VERSION = '0' 293 | #CEF_DEVICE_VERSION = '0' 294 | -------------------------------------------------------------------------------- /proj/settings/docker.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is the docker settings, it uses environment variables for sensitive/changable things 3 | """ 4 | 5 | from . import base 6 | 7 | import environ 8 | env = environ.Env( 9 | DEBUG=(bool, False), 10 | POSTGRES_USER=(str, 'proj'), 11 | POSTGRES_PASSWORD=(str, 'temp'), 12 | RABBITMQ_DEFAULT_USER=(str, 'proj'), 13 | RABBITMQ_DEFAULT_PASS=(str, 'temp'), 14 | ) 15 | 16 | # To extend any settings from settings/base.py here's an example. 17 | # If you don't need to extend any settings from base.py, you do not need 18 | # to import base above 19 | #INSTALLED_APPS = base.INSTALLED_APPS + ('somelib',) 20 | 21 | DATABASES = { 22 | 'default': { 23 | 'ENGINE': 'django.db.backends.postgresql_psycopg2', 24 | 'NAME': 'proj', 25 | 'USER': env('POSTGRES_USER'), 26 | 'PASSWORD': env('POSTGRES_PASSWORD'), 27 | 'HOST': 'db', # docker-compose linked 28 | 'PORT': '', 29 | #'OPTIONS': { 30 | # 'init_command': 'SET storage_engine=InnoDB', 31 | # 'charset' : 'utf8', 32 | # 'use_unicode' : True, 33 | #}, 34 | #'TEST_CHARSET': 'utf8', 35 | #'TEST_COLLATION': 'utf8_general_ci', 36 | }, 37 | # 'slave': { 38 | # ... 39 | # }, 40 | } 41 | 42 | # Recipients of traceback emails and other notifications. 43 | ADMINS = ( 44 | # ('Your Name', 'your_email@domain.com'), 45 | ) 46 | MANAGERS = ADMINS 47 | 48 | EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' 49 | 50 | CACHES = { 51 | 'default': { 52 | 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 53 | } 54 | } 55 | 56 | # SECURITY WARNING: don't run with debug turned on in production! 57 | # Debugging displays nice error messages, but leaks memory. Set this to False 58 | # on all server instances and True only for development. 59 | DEBUG = TEMPLATE_DEBUG = env('DEBUG') 60 | 61 | # Is this a development instance? Set this to True on development/master 62 | # instances and False on stage/prod. 63 | DEV = True 64 | 65 | # Hosts/domain names that are valid for this site; required if DEBUG is False 66 | # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts 67 | ALLOWED_HOSTS = ['*'] 68 | 69 | # SECURITY WARNING: keep the secret key used in production secret! 70 | # Hardcoded values can leak through source control. Consider loading 71 | # the secret key from an environment variable or a file instead. 72 | SECRET_KEY = env('SECRET_KEY') 73 | 74 | STATIC_URL = '/static/' 75 | 76 | # Uncomment these to activate and customize Celery: 77 | # CELERY_ALWAYS_EAGER = False # required to activate celeryd 78 | BROKER_URL = "amqp://{0}:{1}@rabbitmq:5672//".format(env('RABBITMQ_DEFAULT_USER'), env('RABBITMQ_DEFAULT_PASS')) 79 | #CELERY_RESULT_BACKEND = 'amqp' 80 | 81 | ## Log settings 82 | 83 | # Remove this configuration variable to use your custom logging configuration 84 | LOGGING_CONFIG = None 85 | LOGGING = { 86 | 'version': 1, 87 | 'loggers': { 88 | 'proj': { 89 | 'level': "INFO" 90 | } 91 | } 92 | } 93 | 94 | INTERNAL_IPS = ('127.0.0.1') 95 | -------------------------------------------------------------------------------- /proj/settings/local-dist.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is an example settings/local.py file. 3 | These settings overrides what's in settings/base.py 4 | """ 5 | 6 | from . import base 7 | 8 | 9 | # To extend any settings from settings/base.py here's an example. 10 | # If you don't need to extend any settings from base.py, you do not need 11 | # to import base above 12 | INSTALLED_APPS = base.INSTALLED_APPS + ('django_nose',) 13 | 14 | DATABASES = { 15 | 'default': { 16 | 'ENGINE': 'django.db.backends.sqlite3', 17 | 'NAME': 'db/development.sqlite3', 18 | 'USER': '', 19 | 'PASSWORD': '', 20 | 'HOST': '', 21 | 'PORT': '', 22 | #'OPTIONS': { 23 | # 'init_command': 'SET storage_engine=InnoDB', 24 | # 'charset' : 'utf8', 25 | # 'use_unicode' : True, 26 | #}, 27 | #'TEST_CHARSET': 'utf8', 28 | #'TEST_COLLATION': 'utf8_general_ci', 29 | }, 30 | # 'slave': { 31 | # ... 32 | # }, 33 | } 34 | 35 | # Recipients of traceback emails and other notifications. 36 | ADMINS = ( 37 | # ('Your Name', 'your_email@domain.com'), 38 | ) 39 | MANAGERS = ADMINS 40 | 41 | EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' 42 | 43 | CACHES = { 44 | 'default': { 45 | 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 46 | } 47 | } 48 | 49 | # SECURITY WARNING: don't run with debug turned on in production! 50 | # Debugging displays nice error messages, but leaks memory. Set this to False 51 | # on all server instances and True only for development. 52 | DEBUG = TEMPLATE_DEBUG = True 53 | 54 | # Is this a development instance? Set this to True on development/master 55 | # instances and False on stage/prod. 56 | DEV = True 57 | 58 | # Hosts/domain names that are valid for this site; required if DEBUG is False 59 | # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts 60 | ALLOWED_HOSTS = [] 61 | 62 | # SECURITY WARNING: keep the secret key used in production secret! 63 | # Hardcoded values can leak through source control. Consider loading 64 | # the secret key from an environment variable or a file instead. 65 | SECRET_KEY = '$k17=e6!-@5w2u@vm@dfgdyqwj2g-jq&++0hxov%#9nl=cc23=' 66 | 67 | # Uncomment these to activate and customize Celery: 68 | # CELERY_ALWAYS_EAGER = False # required to activate celeryd 69 | # BROKER_HOST = 'localhost' 70 | # BROKER_PORT = 5672 71 | # BROKER_USER = 'django' 72 | # BROKER_PASSWORD = 'django' 73 | # BROKER_VHOST = 'django' 74 | # CELERY_RESULT_BACKEND = 'amqp' 75 | 76 | ## Log settings 77 | 78 | # Remove this configuration variable to use your custom logging configuration 79 | LOGGING_CONFIG = None 80 | LOGGING = { 81 | 'version': 1, 82 | 'loggers': { 83 | 'proj': { 84 | 'level': "DEBUG" 85 | } 86 | } 87 | } 88 | 89 | INTERNAL_IPS = ('127.0.0.1') 90 | -------------------------------------------------------------------------------- /proj/settings/test.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is an example settings/test.py file. 3 | Use this settings file when running tests. 4 | These settings overrides what's in settings/base.py 5 | """ 6 | 7 | from .base import * 8 | 9 | 10 | DATABASES = { 11 | "default": { 12 | "ENGINE": "django.db.backends.sqlite3", 13 | "NAME": ":memory:", 14 | "USER": "", 15 | "PASSWORD": "", 16 | "HOST": "", 17 | "PORT": "", 18 | }, 19 | } 20 | 21 | SECRET_KEY = '$k17=e6!-@5w2u@vm@dfgdyqwj2g-jq&++0hxov%#9nl=cc23=' 22 | -------------------------------------------------------------------------------- /proj/urls.py: -------------------------------------------------------------------------------- 1 | """proj URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.8/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. Add an import: from blog import urls as blog_urls 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) 15 | """ 16 | from django.conf.urls import include, url 17 | from django.contrib import admin 18 | from demoapp.views import Hello 19 | 20 | urlpatterns = [ 21 | url(r'^$', Hello), 22 | url(r'^admin/', include(admin.site.urls)), 23 | ] 24 | -------------------------------------------------------------------------------- /proj/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for proj 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.8/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", "proj.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # This file is here because many Platforms as a Service look for 2 | # requirements.txt in the root directory of a project. 3 | -r requirements/production.txt 4 | -------------------------------------------------------------------------------- /requirements/compiled.txt: -------------------------------------------------------------------------------- 1 | # Database 2 | psycopg2 3 | 4 | # for bcrypt passwords 5 | bcrypt 6 | -------------------------------------------------------------------------------- /requirements/local.txt: -------------------------------------------------------------------------------- 1 | # This file pulls in everything a developer needs. If it's a basic package 2 | # needed to run the site, it belongs in requirements/production.txt. If it's a 3 | # package for developers (testing, docs, etc.), it goes in this file. 4 | -r production.txt 5 | 6 | # Testing 7 | nose 8 | mock 9 | django-nose 10 | coverage 11 | pep8 12 | pyflakes 13 | pylint 14 | -------------------------------------------------------------------------------- /requirements/production.txt: -------------------------------------------------------------------------------- 1 | # Install everything that needs to be compiled 2 | -r compiled.txt 3 | 4 | # Django stuff 5 | Django>=1.8 6 | 7 | # App server 8 | gunicorn 9 | 10 | # Security 11 | bleach 12 | 13 | # Templates 14 | django_compressor 15 | 16 | # Admin 17 | django-debug-toolbar 18 | 19 | # Celery: Message queue 20 | celery 21 | django-celery 22 | 23 | # environment 24 | django-environ 25 | -------------------------------------------------------------------------------- /secrets.env.sample: -------------------------------------------------------------------------------- 1 | SECRET_KEY=b8ff56a18ee8ce3500d59c083691499aba8f227dddff57c972e1f49a9eff396cc0c83bfa42a78c3cce9f379ef64e9d3c9957572d3af0fe1f432437ce3a1deb5c 2 | 3 | POSTGRES_USER=proj 4 | POSTGRES_PASSWORD=strongpassword 5 | 6 | RABBITMQ_DEFAULT_USER=proj 7 | RABBITMQ_DEFAULT_PASS=strongpassword 8 | -------------------------------------------------------------------------------- /static/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/damsonn/django-docker-compose/8ca8ac95235e03391e1d5130bd2c61b62df9ce79/static/.keep --------------------------------------------------------------------------------