Skip to content

Commit 5882c8a

Browse files
committed
add devcontainer, make app more generic so people can build off it, add command to create superuser, run migrations and superuser in compose dev
1 parent 2231843 commit 5882c8a

File tree

12 files changed

+282
-20
lines changed

12 files changed

+282
-20
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FROM mcr.microsoft.com/devcontainers/python:3.12-bookworm
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"build": {
3+
"dockerfile": "Dockerfile",
4+
"context": ".."
5+
},
6+
"features": {
7+
"ghcr.io/defanglabs/devcontainer-feature/defang-cli:1.0.4": {},
8+
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
9+
"ghcr.io/devcontainers/features/aws-cli:1": {}
10+
}
11+
}

samples/django-postgres/app/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ COPY . /code/
2424
RUN python manage.py collectstatic --noinput
2525

2626
# Start server
27-
CMD python manage.py migrate && python manage.py createsuperuser && gunicorn crm_platform.wsgi:application --bind 0.0.0.0:8000
27+
CMD python manage.py migrate && python manage.py createsuperauto && gunicorn app.wsgi:application --bind 0.0.0.0:8000

samples/django-postgres/app/app/__init__.py

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
ASGI config for app 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/5.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', 'app.settings')
15+
16+
application = get_asgi_application()
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
"""
2+
Django settings for app project.
3+
4+
Generated by 'django-admin startproject' using Django 5.0.4.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/5.0/topics/settings/
8+
9+
For the full list of settings and their values, see
10+
https://docs.djangoproject.com/en/5.0/ref/settings/
11+
"""
12+
13+
from pathlib import Path
14+
import os
15+
16+
# Build paths inside the project like this: BASE_DIR / 'subdir'.
17+
BASE_DIR = Path(__file__).resolve().parent.parent
18+
19+
20+
# Quick-start development settings - unsuitable for production
21+
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
22+
23+
# SECURITY WARNING: keep the secret key used in production secret!
24+
SECRET_KEY = 'django-insecure-^0jq%7b(%aj$j@n0_$gk@#73&z#t%4o#klquddg1e1hdal^9!s'
25+
26+
# SECURITY WARNING: don't run with debug turned on in production!
27+
DEBUG = True
28+
29+
ALLOWED_HOSTS = ['*']
30+
31+
CSRF_TRUSTED_ORIGINS = [
32+
'https://*.defang.dev',
33+
'http://localhost:8000',
34+
]
35+
36+
# Application definition
37+
38+
INSTALLED_APPS = [
39+
'django.contrib.admin',
40+
'django.contrib.auth',
41+
'django.contrib.contenttypes',
42+
'django.contrib.sessions',
43+
'django.contrib.messages',
44+
'django.contrib.staticfiles',
45+
'website',
46+
]
47+
48+
MIDDLEWARE = [
49+
'django.middleware.security.SecurityMiddleware',
50+
'django.contrib.sessions.middleware.SessionMiddleware',
51+
'django.middleware.common.CommonMiddleware',
52+
'django.middleware.csrf.CsrfViewMiddleware',
53+
'django.contrib.auth.middleware.AuthenticationMiddleware',
54+
'django.contrib.messages.middleware.MessageMiddleware',
55+
'django.middleware.clickjacking.XFrameOptionsMiddleware',
56+
'whitenoise.middleware.WhiteNoiseMiddleware',
57+
]
58+
59+
ROOT_URLCONF = 'app.urls'
60+
61+
TEMPLATES = [
62+
{
63+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
64+
'DIRS': [],
65+
'APP_DIRS': True,
66+
'OPTIONS': {
67+
'context_processors': [
68+
'django.template.context_processors.debug',
69+
'django.template.context_processors.request',
70+
'django.contrib.auth.context_processors.auth',
71+
'django.contrib.messages.context_processors.messages',
72+
],
73+
},
74+
},
75+
]
76+
77+
WSGI_APPLICATION = 'app.wsgi.application'
78+
79+
80+
# Database
81+
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
82+
83+
DATABASES = {
84+
"default": {
85+
"ENGINE": "django.db.backends.postgresql",
86+
"HOST": os.environ.get('DB_HOST', 'db'),
87+
# We put the host in an environment variable because Defang
88+
# detects hostnames that match service names and makes sure they
89+
# are properly configured to communicate when deployed
90+
"NAME": os.environ.get("POSTGRES_DB"),
91+
"USER": os.environ.get("POSTGRES_USER"),
92+
"PASSWORD": os.environ.get("POSTGRES_PASSWORD"),
93+
}
94+
}
95+
96+
97+
98+
# Password validation
99+
# https://docs.djangoproject.com/en/5.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/5.0/topics/i18n/
119+
120+
LANGUAGE_CODE = 'en-us'
121+
122+
TIME_ZONE = 'UTC'
123+
124+
USE_I18N = True
125+
126+
USE_TZ = True
127+
128+
129+
# Static files (CSS, JavaScript, Images)
130+
# https://docs.djangoproject.com/en/5.0/howto/static-files/
131+
132+
STATIC_URL = 'static/'
133+
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
134+
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
135+
136+
# Default primary key field type
137+
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
138+
139+
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""
2+
URL configuration for app project.
3+
4+
The `urlpatterns` list routes URLs to views. For more information please see:
5+
https://docs.djangoproject.com/en/5.0/topics/http/urls/
6+
Examples:
7+
Function views
8+
1. Add an import: from my_app import views
9+
2. Add a URL to urlpatterns: path('', views.home, name='home')
10+
Class-based views
11+
1. Add an import: from other_app.views import Home
12+
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
13+
Including another URLconf
14+
1. Import the include() function: from django.urls import include, path
15+
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
16+
"""
17+
from django.contrib import admin
18+
from django.urls import path, include
19+
20+
urlpatterns = [
21+
path('admin/', admin.site.urls),
22+
path('', include('website.urls')),
23+
]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
WSGI config for app 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/5.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', 'app.settings')
15+
16+
application = get_wsgi_application()

samples/django-postgres/app/manage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
def main():
88
"""Run administrative tasks."""
9-
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'crm_platform.settings')
9+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
1010
try:
1111
from django.core.management import execute_from_command_line
1212
except ImportError as exc:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from django.core.management.base import BaseCommand
2+
from django.contrib.auth import get_user_model
3+
import logging
4+
5+
class Command(BaseCommand):
6+
def handle(self, *args, **options):
7+
User = get_user_model()
8+
logger = logging.getLogger(__name__)
9+
if not User.objects.filter(username='admin').exists():
10+
User.objects.create_superuser('admin', '[email protected]', 'admin')
11+
logger.info("Superuser 'admin' created automatically")
12+
else:
13+
logger.info("Superuser 'admin' already exists")

0 commit comments

Comments
 (0)