Skip to content

Commit 2a50a8d

Browse files
committed
Initial commit
0 parents  commit 2a50a8d

18 files changed

+509
-0
lines changed

.env-local

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
DATABASE_URL=postgres://postgres@database_default:5432/db
2+
DEFAULT_STORAGE_DSN=file:///data/media/?url=%2Fmedia%2F
3+
DJANGO_DEBUG=True
4+
DOMAIN_ALIASES=localhost, 127.0.0.1
5+
SECURE_SSL_REDIRECT=False

.gitignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Python
2+
*.pyc
3+
*.pyo
4+
db.sqlite3
5+
6+
# Django
7+
/staticfiles
8+
9+
# Divio
10+
.divio
11+
/data.tar.gz
12+
/data
13+
14+
15+
# OS-specific patterns - add your own here
16+
.DS_Store
17+
.DS_Store?
18+
._*
19+
.Spotlight-V100
20+
.Trashes

Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FROM python:3.8
2+
WORKDIR /app
3+
COPY . /app
4+
RUN pip install -r requirements.txt
5+
RUN python manage.py collectstatic --noinput
6+
CMD uwsgi --http=0.0.0.0:80 --module=quickstart.wsgi

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Divio
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.

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# django CMS Divio quickstart
2+
3+
A Dockerised django CMS project, ready to deploy on Divio or another Docker-based cloud platform, and run
4+
locally in Docker on your own machine. A Divio account is not required.
5+
6+
This version uses Python 3.8 running and the most up-to-date versions of Django 3.1 and django CMS 3.8.
7+
8+
For a complete how-to guide for this project, see [Deploy a new django CMS project using the Divio quickstart
9+
repository](https://docs.divio.com/en/latest/how-to/django-cms-deploy-quickstart/) in the [Divio Developer
10+
Handbook](https://docs.divio.com).
11+
12+
The guide shows you how to use this repository to deploy a Twelve-factor Django project including Postgres or MySQL,
13+
and cloud media storage using S3, with Docker. It also gives you a fully working local project for development,
14+
also running in Docker.
15+
16+
## Important
17+
18+
This project is ready-to-go, but also gives you some options. As-is, it will include a number of useful django CMS
19+
plugins and Bootstrap 4 for the frontend. You don't have to use these; they're optional. If you don't want to use them,
20+
read through the `settings.py` and `requirements.txt` files to see sections that can be removed - in each case, the
21+
section is noted with a comment containing the word 'optional'.

docker-compose.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
version: "2.4"
2+
services:
3+
web:
4+
# the application's web service (container) will use an image based on our Dockerfile
5+
build: "."
6+
# map the internal port 80 to port 8000 on the host
7+
ports:
8+
- "8000:80"
9+
# map the host directory to app (which allows us to see and edit files inside the container)
10+
volumes:
11+
- ".:/app:rw"
12+
- "./data:/data:rw"
13+
# the default command to run whenever the container is launched
14+
command: python manage.py runserver 0.0.0.0:80
15+
# the URL 'postgres' or 'mysql' will point to the application's db service
16+
links:
17+
- "database_default"
18+
env_file: .env-local
19+
20+
database_default:
21+
# Select one of the following db configurations for the database
22+
image: postgres:9.6-alpine
23+
environment:
24+
POSTGRES_DB: "db"
25+
POSTGRES_HOST_AUTH_METHOD: "trust"
26+
SERVICE_MANAGER: "fsm-postgres"
27+
volumes:
28+
- ".:/app:rw"

manage.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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+
"""Run administrative tasks."""
9+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'quickstart.settings')
10+
try:
11+
from django.core.management import execute_from_command_line
12+
except ImportError as exc:
13+
raise ImportError(
14+
"Couldn't import Django. Are you sure it's installed and "
15+
"available on your PYTHONPATH environment variable? Did you "
16+
"forget to activate a virtual environment?"
17+
) from exc
18+
execute_from_command_line(sys.argv)
19+
20+
21+
if __name__ == '__main__':
22+
main()

quickstart/__init__.py

Whitespace-only changes.

quickstart/asgi.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
ASGI config for quickstart 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.1/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', 'quickstart.settings')
15+
16+
application = get_asgi_application()

quickstart/settings.py

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
from pathlib import Path
2+
import os
3+
import dj_database_url
4+
from django_storage_url import dsn_configured_storage_class
5+
6+
# Build paths inside the project like this: BASE_DIR / 'subdir'.
7+
BASE_DIR = Path(__file__).resolve().parent.parent
8+
9+
10+
# SECURITY WARNING: keep the secret key used in production secret!
11+
SECRET_KEY = os.environ.get('SECRET_KEY', '<a string of random characters>')
12+
13+
# SECURITY WARNING: don't run with debug turned on in production!
14+
DEBUG = os.environ.get('DJANGO_DEBUG') == "True"
15+
16+
DIVIO_DOMAIN = os.environ.get('DOMAIN', '')
17+
DIVIO_DOMAIN_ALIASES = [
18+
d.strip()
19+
for d in os.environ.get('DOMAIN_ALIASES', '').split(',')
20+
if d.strip()
21+
]
22+
ALLOWED_HOSTS = [DIVIO_DOMAIN] + DIVIO_DOMAIN_ALIASES
23+
24+
# Redirect to HTTPS by default, unless explicitly disabled
25+
SECURE_SSL_REDIRECT = os.environ.get('SECURE_SSL_REDIRECT') != "False"
26+
27+
X_FRAME_OPTIONS = 'SAMEORIGIN'
28+
29+
30+
# Application definition
31+
32+
INSTALLED_APPS = [
33+
'quickstart',
34+
35+
# optional, but used in most projects
36+
'djangocms_admin_style',
37+
38+
'django.contrib.admin',
39+
'django.contrib.auth',
40+
'django.contrib.contenttypes',
41+
'django.contrib.sessions',
42+
'django.contrib.messages',
43+
'django.contrib.staticfiles',
44+
'django.contrib.sites',
45+
46+
# key django CMS modules
47+
'cms',
48+
'menus',
49+
'treebeard',
50+
'sekizai',
51+
52+
# Django Filer - optional, but used in most projects
53+
'filer',
54+
'easy_thumbnails',
55+
56+
# the default CKEditor - optional, but used in most projects
57+
'djangocms_text_ckeditor',
58+
59+
# some content plugins - optional, but used in most projects
60+
'djangocms_file',
61+
'djangocms_icon',
62+
'djangocms_link',
63+
'djangocms_picture',
64+
'djangocms_style',
65+
'djangocms_googlemap',
66+
'djangocms_video',
67+
68+
# optional django CMS Bootstrap 4 modules
69+
'djangocms_bootstrap4',
70+
'djangocms_bootstrap4.contrib.bootstrap4_alerts',
71+
'djangocms_bootstrap4.contrib.bootstrap4_badge',
72+
'djangocms_bootstrap4.contrib.bootstrap4_card',
73+
'djangocms_bootstrap4.contrib.bootstrap4_carousel',
74+
'djangocms_bootstrap4.contrib.bootstrap4_collapse',
75+
'djangocms_bootstrap4.contrib.bootstrap4_content',
76+
'djangocms_bootstrap4.contrib.bootstrap4_grid',
77+
'djangocms_bootstrap4.contrib.bootstrap4_jumbotron',
78+
'djangocms_bootstrap4.contrib.bootstrap4_link',
79+
'djangocms_bootstrap4.contrib.bootstrap4_listgroup',
80+
'djangocms_bootstrap4.contrib.bootstrap4_media',
81+
'djangocms_bootstrap4.contrib.bootstrap4_picture',
82+
'djangocms_bootstrap4.contrib.bootstrap4_tabs',
83+
'djangocms_bootstrap4.contrib.bootstrap4_utilities',
84+
]
85+
86+
MIDDLEWARE = [
87+
'django.middleware.security.SecurityMiddleware',
88+
'whitenoise.middleware.WhiteNoiseMiddleware',
89+
'django.contrib.sessions.middleware.SessionMiddleware',
90+
'django.middleware.common.CommonMiddleware',
91+
'django.middleware.csrf.CsrfViewMiddleware',
92+
'django.contrib.auth.middleware.AuthenticationMiddleware',
93+
'django.contrib.messages.middleware.MessageMiddleware',
94+
'django.middleware.clickjacking.XFrameOptionsMiddleware',
95+
'django.middleware.locale.LocaleMiddleware',
96+
97+
'cms.middleware.user.CurrentUserMiddleware',
98+
'cms.middleware.page.CurrentPageMiddleware',
99+
'cms.middleware.toolbar.ToolbarMiddleware',
100+
'cms.middleware.language.LanguageCookieMiddleware',
101+
]
102+
103+
ROOT_URLCONF = 'quickstart.urls'
104+
105+
TEMPLATES = [
106+
{
107+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
108+
'DIRS': [],
109+
'APP_DIRS': True,
110+
'OPTIONS': {
111+
'context_processors': [
112+
'django.template.context_processors.debug',
113+
'django.template.context_processors.request',
114+
'django.contrib.auth.context_processors.auth',
115+
'django.contrib.messages.context_processors.messages',
116+
'django.template.context_processors.media',
117+
'django.template.context_processors.csrf',
118+
'django.template.context_processors.tz',
119+
'django.template.context_processors.i18n',
120+
121+
'cms.context_processors.cms_settings',
122+
'sekizai.context_processors.sekizai',
123+
124+
],
125+
},
126+
},
127+
]
128+
129+
CMS_TEMPLATES = [
130+
# a minimal template to get started with
131+
('minimal.html', 'Minimal template'),
132+
133+
# optional templates that extend base.html, to be used with Bootstrap 4
134+
('page.html', 'Page'),
135+
('feature.html', 'Page with Feature')
136+
]
137+
138+
WSGI_APPLICATION = 'quickstart.wsgi.application'
139+
140+
141+
# Database
142+
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
143+
144+
# Configure database using DATABASE_URL; fall back to sqlite in memory when no
145+
# environment variable is available, e.g. during Docker build
146+
DATABASE_URL = os.environ.get('DATABASE_URL', 'sqlite://:memory:')
147+
148+
DATABASES = {'default': dj_database_url.parse(DATABASE_URL)}
149+
150+
151+
# Password validation
152+
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
153+
154+
AUTH_PASSWORD_VALIDATORS = [
155+
{
156+
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
157+
},
158+
{
159+
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
160+
},
161+
{
162+
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
163+
},
164+
{
165+
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
166+
},
167+
]
168+
169+
170+
# Internationalization
171+
# https://docs.djangoproject.com/en/3.1/topics/i18n/
172+
173+
LANGUAGE_CODE = 'en'
174+
175+
LANGUAGES = [
176+
('en', 'English'),
177+
]
178+
179+
TIME_ZONE = 'UTC'
180+
181+
USE_I18N = True
182+
183+
USE_L10N = True
184+
185+
USE_TZ = True
186+
187+
188+
# Static files (CSS, JavaScript, Images)
189+
# https://docs.djangoproject.com/en/3.1/howto/static-files/
190+
191+
STATIC_URL = '/static/'
192+
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
193+
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
194+
195+
# Media files
196+
# DEFAULT_FILE_STORAGE is configured using DEFAULT_STORAGE_DSN
197+
198+
# read the setting value from the environment variable
199+
DEFAULT_STORAGE_DSN = os.environ.get('DEFAULT_STORAGE_DSN')
200+
201+
# dsn_configured_storage_class() requires the name of the setting
202+
DefaultStorageClass = dsn_configured_storage_class('DEFAULT_STORAGE_DSN')
203+
204+
# Django's DEFAULT_FILE_STORAGE requires the class name
205+
DEFAULT_FILE_STORAGE = 'quickstart.settings.DefaultStorageClass'
206+
207+
# only required for local file storage and serving, in development
208+
MEDIA_URL = 'media/'
209+
MEDIA_ROOT = os.path.join('/data/media/')
210+
211+
212+
SITE_ID = 1

0 commit comments

Comments
 (0)