From afdb15d8974647e6a08633fa4b4f3e9d4a2f8ca8 Mon Sep 17 00:00:00 2001 From: gw3000 Date: Thu, 20 Jul 2023 21:24:27 +0200 Subject: [PATCH] deployment --- .env.example | 29 ++++++++++++++ app/core/settings.py | 83 +++++++++++++++++++++++++++++++++-------- docker-compose.prod.yml | 24 ++++++++---- docker-compose.yaml | 24 ++++++++---- 4 files changed, 128 insertions(+), 32 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..81ba47c --- /dev/null +++ b/.env.example @@ -0,0 +1,29 @@ +# APP URL +APP_URL='https://url.of.the.site' + +# Allowed Hosts +DJANGO_ALLOWED_HOSTS='django.localhost' + +# Database +DB_HOST='db' +DB_PORT='5432' +DB_PASSWORD='supersecret' +DB_USER='fbf' +DB_NAME='db_fbf' + +# DEBUG +DEBUG=0 + +# Secrets +SECRET_KEY='evenMoreSuperSecret' + +# CSRF +CSRF_TRUSTED_ORIGINS='http://django.localhost' + +# Email +EMAIL_HOST='' +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER='' +EMAIL_HOST_PASSWORD='' +DEFAULT_FROM_EMAIL='' diff --git a/app/core/settings.py b/app/core/settings.py index 6ee4a98..96168cf 100644 --- a/app/core/settings.py +++ b/app/core/settings.py @@ -9,20 +9,23 @@ env = environ.Env() # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent - # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = ")g-j2v+*dvjtnz)q-3+*y7*lq$el$im8p^wr@2v$g^u99quq50" +SECRET_KEY = env("SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! -# DEBUG = True DEBUG = env("DEBUG") -CSRF_TRUSTED_ORIGINS = ["https://*.nabu-jena.de", "https://*.127.0.0.1"] +# CSRF Stuff +CSRF_COOKIE_SECURE = True +CSRF_TRUSTED_ORIGINS = (env("CSRF_TRUSTED_ORIGINS"),) -# ALLOWED_HOSTS = [] +# Cookies +SESSION_COOKIE_SECURE = True + +# Allowed Hosts ALLOWED_HOSTS = env("DJANGO_ALLOWED_HOSTS", default=[]) # Application definition @@ -32,6 +35,9 @@ INSTALLED_APPS = [ # Jazzmin # ----------------------------------- "jazzmin", + # ----------------------------------- + # Django default + # ----------------------------------- "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", @@ -51,6 +57,11 @@ INSTALLED_APPS = [ "crispy_bootstrap5", "crispy_forms", # ----------------------------------- + # CKEditor + # ----------------------------------- + "ckeditor", + "ckeditor_uploader", + # ----------------------------------- # My Apps # ----------------------------------- "aviary", @@ -103,7 +114,14 @@ WSGI_APPLICATION = "core.wsgi.application" # https://docs.djangoproject.com/en/4.2/ref/settings/#databases DATABASES = { - "default": env.db(), + "default": { + "ENGINE": "django.db.backends.postgresql", + "HOST": env("DB_HOST"), + "NAME": env("DB_NAME"), + "PASSWORD": env("DB_PASSWORD"), + "PORT": env("DB_PORT"), + "USER": env("DB_USER"), + } } @@ -137,14 +155,25 @@ USE_I18N = True USE_TZ = True - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.2/howto/static-files/ +# STATIC_URL = "/static/" +# STATIC_ROOT = BASE_DIR / "static" +# STATICFILES_DIRS = [BASE_DIR / "static"] + +# STATIC_URL = "static/" +# STATICFILES_DIRS = [BASE_DIR / "static"] +# STATIC_ROOT = BASE_DIR / "staticfiles" +# STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.1/howto/static-files/ + STATIC_URL = "static/" STATICFILES_DIRS = [BASE_DIR / "static"] -STATIC_ROOT = BASE_DIR / "staticfiles" -STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" +STATIC_ROOT = BASE_DIR / 'staticfiles' +STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' # Default primary key field type # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field @@ -197,7 +226,13 @@ JAZZMIN_SETTINGS = { # "copyright": "Acme Library Ltd", # List of model admins to search from the search bar, search bar omitted if excluded # If you want to use a single search field you dont need to use a list, you can use a simple string - "search_model": ["auth.User", "auth.Group"], + # "search_model": ["bird.User", "auth.Group"], + "search_model": [ + "bird.User", + "bird.FallenBird", + "rescuer.Rescuer", + "aviary.Aviary", + ], # Field name on user model that contains avatar ImageField/URLField/Charfield or a callable that receives the user "user_avatar": None, ############ @@ -246,11 +281,18 @@ JAZZMIN_SETTINGS = { # }, # Custom icons for side menu apps/models See https://fontawesome.com/icons?d=gallery&m=free&v=5.0.0,5.0.1,5.0.10,5.0.11,5.0.12,5.0.13,5.0.2,5.0.3,5.0.4,5.0.5,5.0.6,5.0.7,5.0.8,5.0.9,5.1.0,5.1.1,5.2.0,5.3.0,5.3.1,5.4.0,5.4.1,5.4.2,5.13.0,5.12.0,5.11.2,5.11.1,5.10.0,5.9.0,5.8.2,5.8.1,5.7.2,5.7.1,5.7.0,5.6.3,5.5.0,5.4.2 # for the full list of 5.13.0 free icon classes - # "icons": { - # "auth": "fas fa-users-cog", - # "auth.user": "fas fa-user", - # "auth.Group": "fas fa-users", - # }, + "icons": { + "auth": "fas fa-users-cog", + "auth.user": "fas fa-user", + "auth.Group": "fas fa-users", + "aviary.Aviary": "fas fa-solid fa-house", + "bird.Bird": "fas fa-solid fa-dove", + "bird.BirdStatus": "fas fa-solid fa-thermometer", + "bird.Circumstance": "fas fa-solid fa-disease", + "bird.FallenBird": "fas fa-solid fa-bed", + "costs.Costs": "fas fa-solid fa-money-bill", + "rescuer.Rescuer": "fas fa-solid fa-user-shield", + }, # Icons that are used when one is not manually specified # "default_icon_parents": "fas fa-chevron-circle-right", # "default_icon_children": "fas fa-circle", @@ -268,7 +310,7 @@ JAZZMIN_SETTINGS = { # Whether to link font from fonts.googleapis.com (use custom_css to supply font otherwise) "use_google_fonts_cdn": True, # Whether to show the UI customizer on the sidebar - "show_ui_builder": True, + "show_ui_builder": False, ############### # Change view # ############### @@ -287,3 +329,12 @@ JAZZMIN_SETTINGS = { # Add a language dropdown into the admin # "language_chooser": True, } + +CKEDITOR_BASEPATH = "/staticfiles/ckeditor/ckeditor/" +CKEDITOR_UPLOAD_PATH = "media" + +# Local Settings +# try: +# from .opvars import * +# except ImportError: +# print('No Local Settings Found') diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 645f4be..756bcfe 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -9,26 +9,34 @@ services: expose: - 8000 environment: - - DEBUG=False - - DATABASE_URL=postgresql://django_traefik:django_traefik@db:5432/django_traefik - - DJANGO_ALLOWED_HOSTS=.nabu-jena.de + - "DEBUG=${DEBUG}" + - "ALLOWED_HOSTS=${ALLOWED_HOSTS}" + - "CSRF_TRUSTED_ORIGINS=${CSRF_TRUSTED_ORIGINS}" + - "DB_HOST=${DB_HOST}" + - "DB_NAME=${DB_NAME}" + - "DB_PASSWORD=${DB_PASSWORD}" + - "DB_PORT=${DB_PORT}" + - "DB_USER=${DB_USER}" + - "DEBUG=${DEBUG}" + - "DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS}" + - "SECRET_KEY=${SECRET_KEY}" depends_on: - db labels: - "traefik.enable=true" - - "traefik.http.routers.django.rule=Host(`fbf.nabu-jena.de`)" + - "traefik.http.routers.django.rule=Host(`${DJANGO_ALLOWED_HOSTS}`)" - "traefik.http.routers.django.tls=true" - "traefik.http.routers.django.tls.certresolver=letsencrypt" db: image: postgres:15-alpine volumes: - - postgres_data_prod:/var/lib/postgresql/data/ + - ./postgres_data:/var/lib/postgresql/data/ expose: - 5432 environment: - - POSTGRES_USER=django_traefik - - POSTGRES_PASSWORD=django_traefik - - POSTGRES_DB=django_traefik + - "POSTGRES_USER=${DB_USER}" + - "POSTGRES_PASSWORD=${DB_PASSWORD}" + - "POSTGRES_DB=${DB_NAME}" traefik: build: context: . diff --git a/docker-compose.yaml b/docker-compose.yaml index 4202b6f..6c06dd9 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -3,29 +3,37 @@ version: '3.8' services: web: build: ./app - command: bash -c 'while !