├── .gitignore ├── .travis.yml ├── LICENSE ├── MyProject ├── Dockerfile ├── MyProject │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── myapp │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ ├── base.html │ │ └── index.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── requirements.txt └── static │ └── css │ └── main.css ├── README.md └── docker-compose.yml /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/macos,django,python 3 | # Edit at https://www.gitignore.io/?templates=macos,django,python 4 | 5 | ### Django ### 6 | *.log 7 | *.pot 8 | *.pyc 9 | __pycache__/ 10 | local_settings.py 11 | db.sqlite3 12 | db.sqlite3-journal 13 | media 14 | letsencrypt 15 | #Postgres 16 | database 17 | 18 | # If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ 19 | # in your Git repository. Update and uncomment the following line accordingly. 20 | # /staticfiles/ 21 | 22 | ### Django.Python Stack ### 23 | # Byte-compiled / optimized / DLL files 24 | *.py[cod] 25 | *$py.class 26 | 27 | # C extensions 28 | *.so 29 | 30 | # Distribution / packaging 31 | .Python 32 | build/ 33 | develop-eggs/ 34 | dist/ 35 | downloads/ 36 | eggs/ 37 | .eggs/ 38 | lib/ 39 | lib64/ 40 | parts/ 41 | sdist/ 42 | var/ 43 | wheels/ 44 | venv/ 45 | pip-wheel-metadata/ 46 | share/python-wheels/ 47 | *.egg-info/ 48 | .installed.cfg 49 | *.egg 50 | MANIFEST 51 | 52 | # PyInstaller 53 | # Usually these files are written by a python script from a template 54 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 55 | *.manifest 56 | *.spec 57 | 58 | # Installer logs 59 | pip-log.txt 60 | pip-delete-this-directory.txt 61 | 62 | # Unit test / coverage reports 63 | htmlcov/ 64 | .tox/ 65 | .nox/ 66 | .coverage 67 | .coverage.* 68 | .cache 69 | nosetests.xml 70 | coverage.xml 71 | *.cover 72 | .hypothesis/ 73 | .pytest_cache/ 74 | # Translations 75 | *.mo 76 | 77 | # Scrapy stuff: 78 | .scrapy 79 | 80 | # Sphinx documentation 81 | docs/_build/ 82 | 83 | # PyBuilder 84 | target/ 85 | 86 | # pyenv 87 | .python-version 88 | 89 | # pipenv 90 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 91 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 92 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 93 | # install all needed dependencies. 94 | #Pipfile.lock 95 | 96 | # celery beat schedule file 97 | celerybeat-schedule 98 | 99 | # SageMath parsed files 100 | *.sage.py 101 | 102 | # Spyder project settings 103 | .spyderproject 104 | .spyproject 105 | 106 | # Rope project settings 107 | .ropeproject 108 | 109 | # Mr Developer 110 | .mr.developer.cfg 111 | .project 112 | .pydevproject 113 | 114 | # mkdocs documentation 115 | /site 116 | 117 | # mypy 118 | .mypy_cache/ 119 | .dmypy.json 120 | dmypy.json 121 | 122 | # Pyre type checker 123 | .pyre/ 124 | 125 | ### macOS ### 126 | # General 127 | .DS_Store 128 | .AppleDouble 129 | .LSOverride 130 | 131 | # Icon must end with two \r 132 | Icon 133 | 134 | # Thumbnails 135 | ._* 136 | 137 | # Files that might appear in the root of a volume 138 | .DocumentRevisions-V100 139 | .fseventsd 140 | .Spotlight-V100 141 | .TemporaryItems 142 | .Trashes 143 | .VolumeIcon.icns 144 | .com.apple.timemachine.donotpresent 145 | 146 | # Directories potentially created on remote AFP share 147 | .AppleDB 148 | .AppleDesktop 149 | Network Trash Folder 150 | Temporary Items 151 | .apdisk 152 | MyProject/static/admin/* 153 | ### Python ### 154 | # Byte-compiled / optimized / DLL files 155 | 156 | # C extensions 157 | 158 | # Distribution / packaging 159 | 160 | # PyInstaller 161 | # Usually these files are written by a python script from a template 162 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 163 | 164 | # Installer logs 165 | 166 | # Unit test / coverage reports 167 | 168 | # Translations 169 | 170 | # Scrapy stuff: 171 | 172 | # Sphinx documentation 173 | 174 | # PyBuilder 175 | 176 | # pyenv 177 | 178 | # pipenv 179 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 180 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 181 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 182 | # install all needed dependencies. 183 | 184 | # celery beat schedule file 185 | 186 | # SageMath parsed files 187 | 188 | # Spyder project settings 189 | 190 | # Rope project settings 191 | 192 | # Mr Developer 193 | 194 | # mkdocs documentation 195 | 196 | # mypy 197 | 198 | # Pyre type checker 199 | 200 | # End of https://www.gitignore.io/api/macos,django,python 201 | 202 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | services: 4 | - docker 5 | 6 | env: 7 | DOCKER_COMPOSE_VERSION: 1.26.0 8 | 9 | before_install: 10 | - sudo rm /usr/local/bin/docker-compose 11 | - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose 12 | - chmod +x docker-compose 13 | - sudo mv docker-compose /usr/local/bin 14 | - sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose 15 | 16 | before_script: 17 | - docker-compose up -d --build 18 | 19 | script: 20 | - docker-compose ps 21 | 22 | after_script: 23 | - docker-compose down 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /MyProject/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:latest 2 | 3 | MAINTAINER Stef sstefin@bk.ru 4 | 5 | COPY requirements.txt /app/ 6 | 7 | WORKDIR ./app/ 8 | 9 | RUN pip install --upgrade pip 10 | 11 | RUN pip install -r requirements.txt 12 | 13 | COPY . . 14 | 15 | EXPOSE 8001 16 | -------------------------------------------------------------------------------- /MyProject/MyProject/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefins/dockerizing-django/d3f3f5efd9c4ab200860c111654319d3bc1573a2/MyProject/MyProject/__init__.py -------------------------------------------------------------------------------- /MyProject/MyProject/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for MyProject project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyProject.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /MyProject/MyProject/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for MyProject project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.0.6. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.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/3.0/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'zd_q1u(@64e5kdm*krbm-xlr)_ut4nu98ps1w^#pgizt#8@+u2' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = False 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 | 'django_probes', 41 | 'myapp', 42 | ] 43 | 44 | MIDDLEWARE = [ 45 | 'django.middleware.security.SecurityMiddleware', 46 | 'whitenoise.middleware.WhiteNoiseMiddleware', 47 | 'django.contrib.sessions.middleware.SessionMiddleware', 48 | 'django.middleware.common.CommonMiddleware', 49 | 'django.middleware.csrf.CsrfViewMiddleware', 50 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 51 | 'django.contrib.messages.middleware.MessageMiddleware', 52 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 53 | ] 54 | 55 | ROOT_URLCONF = 'MyProject.urls' 56 | 57 | TEMPLATES = [ 58 | { 59 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 60 | 'DIRS': [], 61 | 'APP_DIRS': True, 62 | 'OPTIONS': { 63 | 'context_processors': [ 64 | 'django.template.context_processors.debug', 65 | 'django.template.context_processors.request', 66 | 'django.contrib.auth.context_processors.auth', 67 | 'django.contrib.messages.context_processors.messages', 68 | ], 69 | }, 70 | }, 71 | ] 72 | 73 | WSGI_APPLICATION = 'MyProject.wsgi.application' 74 | 75 | 76 | # Database 77 | # https://docs.djangoproject.com/en/3.0/ref/settings/#databases 78 | 79 | DATABASES = { 80 | 'default': { 81 | 'ENGINE': 'django.db.backends.postgresql', 82 | 'NAME': 'postgres', 83 | 'USER': 'postgres', 84 | 'PASSWORD': 'postgres', 85 | 'HOST': 'db', 86 | 'PORT': 5432 87 | } 88 | } 89 | 90 | 91 | # Password validation 92 | # https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators 93 | 94 | AUTH_PASSWORD_VALIDATORS = [ 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 100 | }, 101 | { 102 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 103 | }, 104 | { 105 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 106 | }, 107 | ] 108 | 109 | 110 | # Internationalization 111 | # https://docs.djangoproject.com/en/3.0/topics/i18n/ 112 | 113 | LANGUAGE_CODE = 'en-us' 114 | 115 | TIME_ZONE = 'UTC' 116 | 117 | USE_I18N = True 118 | 119 | USE_L10N = True 120 | 121 | USE_TZ = True 122 | 123 | 124 | # Static files (CSS, JavaScript, Images) 125 | # https://docs.djangoproject.com/en/3.0/howto/static-files/ 126 | 127 | STATIC_URL = '/static/' 128 | STATIC_ROOT = os.path.join(BASE_DIR, 'static') 129 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 130 | MEDIA_URL = '/media/' -------------------------------------------------------------------------------- /MyProject/MyProject/urls.py: -------------------------------------------------------------------------------- 1 | """MyProject URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.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('',include('myapp.urls')), 21 | path('admin', admin.site.urls), 22 | ] 23 | -------------------------------------------------------------------------------- /MyProject/MyProject/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for MyProject 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/3.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', 'MyProject.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /MyProject/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyProject.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /MyProject/myapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefins/dockerizing-django/d3f3f5efd9c4ab200860c111654319d3bc1573a2/MyProject/myapp/__init__.py -------------------------------------------------------------------------------- /MyProject/myapp/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /MyProject/myapp/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class MyappConfig(AppConfig): 5 | name = 'myapp' 6 | -------------------------------------------------------------------------------- /MyProject/myapp/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefins/dockerizing-django/d3f3f5efd9c4ab200860c111654319d3bc1573a2/MyProject/myapp/migrations/__init__.py -------------------------------------------------------------------------------- /MyProject/myapp/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /MyProject/myapp/templates/base.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | 7 | Dockerize Django 8 | 9 | 10 | 11 | 12 |
13 | {% block content %}{% endblock %} 14 |
15 | 16 | -------------------------------------------------------------------------------- /MyProject/myapp/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 |

Dockerize Your Django Project

4 |

Check the README.md for more information!

5 | 6 | {% endblock content %} -------------------------------------------------------------------------------- /MyProject/myapp/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /MyProject/myapp/urls.py: -------------------------------------------------------------------------------- 1 | from myapp import views 2 | from django.urls import path 3 | 4 | urlpatterns = [ 5 | path('',views.index,name='index'), 6 | ] -------------------------------------------------------------------------------- /MyProject/myapp/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | 5 | def index(request): 6 | return render(request,'index.html') -------------------------------------------------------------------------------- /MyProject/requirements.txt: -------------------------------------------------------------------------------- 1 | asgiref==3.2.7 2 | django>=3.0.7 3 | django-probes==1.5.0 4 | gunicorn==20.0.4 5 | psycopg2-binary==2.8.5 6 | pytz==2020.1 7 | sqlparse==0.3.1 8 | whitenoise==5.1.0 9 | -------------------------------------------------------------------------------- /MyProject/static/css/main.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | body{ 7 | background-color: black; 8 | height: 100vh; 9 | } 10 | h1{ 11 | margin-top: 10px; 12 | color: aquamarine; 13 | text-align: center; 14 | } 15 | .sub-h{ 16 | font-size: 24px; 17 | text-align: center; 18 | } 19 | .container{ 20 | position: relative; 21 | top: 50%; 22 | transform: translateY(-50%); 23 | } 24 | .p-link{ 25 | text-align: center; 26 | font-size: 20px; 27 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dockerize Your Django Project 2 | [![Build Status](https://travis-ci.com/IamStefin/dockerizing-django.svg?branch=master)](https://travis-ci.com/IamStefin/dockerizing-django) 3 | [![GitHub license](https://img.shields.io/github/license/IamStefin/dockerizing-django)](https://github.com/IamStefin/dockerizing-django/blob/master/LICENSE) 4 | [![GitHub stars](https://img.shields.io/github/stars/IamStefin/dockerizing-django)](https://github.com/IamStefin/dockerizing-django/stargazers) 5 | [![GitHub issues](https://img.shields.io/github/issues/IamStefin/dockerizing-django)](https://github.com/IamStefin/dockerizing-django/issues) 6 | 7 | This repo will give you the basic configuration for setting docker for your django project 8 | 9 | # Setup 10 | 11 | Clone this repository in your working directory 12 | 13 | ```bash 14 | git clone https://github.com/stefins/dockerizing-django.git 15 | ``` 16 | 17 | Place your project in the **MyProject** directory 18 | 19 | Go to `settings.py` and change the `DATABASE` section matching your credentials in `docker-compose.yml` 20 | 21 | This project uses `WhiteNoise` to serve static files and `django-probes` for checking database connection 22 | 23 | ## traefik Setup 24 | 25 | Change the default values in `docker-compose.yml` 26 | 27 | ## SSL Certificate will be autogenerated by traefik 28 | 29 | ## Port Setup 30 | 31 | Open port 80 and 443 32 | 33 | ## Starting the server 34 | 35 | ```bash 36 | docker-compose build 37 | docker-compose up -d 38 | ``` 39 | 40 | ## Creating superuser 41 | 42 | ```bash 43 | docker exec -it dockerizing-django_website_1 bash 44 | python manage.py createsuperuser 45 | ``` 46 | 47 | ## Contributing 48 | 49 | Feel free to make this code better :) 50 | 51 | ## Contributors 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | db: 4 | image: postgres:latest 5 | environment: 6 | - POSTGRES_DB=postgres 7 | - POSTGRES_USER=postgres 8 | - POSTGRES_PASSWORD=postgres 9 | volumes: 10 | - ./database:/var/lib/postgresql/data 11 | website: 12 | build: ./MyProject 13 | volumes: 14 | - ./MyProject:/app 15 | command: > 16 | sh -c "python manage.py wait_for_database && 17 | python manage.py makemigrations && 18 | python manage.py migrate && 19 | python manage.py collectstatic --no-input && 20 | gunicorn MyProject.wsgi -b :8001" 21 | depends_on: 22 | - db 23 | labels: 24 | - "traefik.enable=true" 25 | - "traefik.http.routers.website.rule=Host(`example.com`)" 26 | - "traefik.http.routers.website.entrypoints=websecure" 27 | - "traefik.http.routers.website.tls.certresolver=myresolver" 28 | - "traefik.http.services.website.loadbalancer.server.port=8001" 29 | 30 | traefik: 31 | image: "traefik:v2.2" 32 | container_name: "traefik" 33 | command: 34 | #- "--log.level=DEBUG" 35 | - "--api.insecure=true" 36 | - "--providers.docker=true" 37 | - "--providers.docker.exposedbydefault=false" 38 | - "--entrypoints.websecure.address=:443" 39 | - "--certificatesresolvers.myresolver.acme.tlschallenge=true" 40 | #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" 41 | - "--certificatesresolvers.myresolver.acme.email=yourmail@mail.com" 42 | - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" 43 | ports: 44 | - "443:443" 45 | - "8080:8080" 46 | volumes: 47 | - "./letsencrypt:/letsencrypt" 48 | - "/var/run/docker.sock:/var/run/docker.sock:ro" 49 | --------------------------------------------------------------------------------