DEV Community

Cover image for Django deployment with App Platform & S3 Space
rburkhardt
rburkhardt

Posted on • Edited on • Originally published at rburkhardt.com

2 1

Django deployment with App Platform & S3 Space

Preface

Recently i had to decide which hosting solution i want to use for my private blog. The blog was developed with the help of Dev-Case and is based on Django.

Since i have read a lot of good things about PaaS in connection with Django lately, the decision was made quickly.

The providers to choose from were:

  • DigitalOcean
  • Railway
  • Render

In the end, i decided to go with DigitalOcean because i have already had good experiences here (VPS, Space). Another plus for DO was that i didn't need another provider for the S3-Storage.

Preparation

To be able to host my Django project with the App-Platform, i have made the following preparations:

Environment variables

For this i use django-environ.
Here are a few basic settings:

import os
from pathlib import Path
from django.core.management.utils import get_random_secret_key
import environ

BASE_DIR = Path(__file__).resolve().parent.parent

env = environ.Env()
env_file = os.path.join(BASE_DIR, ".env")
if os.path.isfile(env_file):
    env.read_env(env_file)

SECRET_KEY = env.str("SECRET_KEY", default=get_random_secret_key())

DEBUG = env.bool("DEBUG", default=False)

ALLOWED_HOSTS = env.list(
    "ALLOWED_HOSTS",
    default=[
        "127.0.0.1",
    ],
)
Enter fullscreen mode Exit fullscreen mode

Database

Here i decided to use Postgres.

Thanks to django-environ i can use a DATABASE_URL here.
A possibility to use SQLite should still exist but is a matter of personal taste.

DATABASE_URL = env.str("DATABASE_URL", default=False)

if DATABASE_URL:
    DATABASES = {"default": env.db()}
else:
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.sqlite3",
            "NAME": BASE_DIR / "db.sqlite3",
        }
    }

Enter fullscreen mode Exit fullscreen mode

S3 Storage

To be able to use the S3 compatible storage later on (DO Space):

USE_S3_STORAGE = env.bool("USE_S3_STORAGE", default=False)
AWS_ACCESS_KEY_ID = env.str("AWS_ACCESS_KEY_ID", default="")
AWS_SECRET_ACCESS_KEY = env.str("AWS_SECRET_ACCESS_KEY", default="")
AWS_STORAGE_BUCKET_NAME = env.str("AWS_STORAGE_BUCKET_NAME", default="")
AWS_S3_REGION_NAME = env.str("AWS_S3_REGION_NAME", default="")
AWS_S3_ENDPOINT_URL = env.str("AWS_S3_ENDPOINT_URL", default="")
AWS_S3_CUSTOM_DOMAIN = env.str("AWS_S3_CUSTOM_DOMAIN", default="")
AWS_LOCATION = env.str("AWS_LOCATION", default="")
AWS_IS_GZIPPED = env.bool("AWS_IS_GZIPPED", default=False)
AWS_S3_FILE_OVERWRITE = env.bool("AWS_S3_FILE_OVERWRITE", default=True)
AWS_DEFAULT_ACL = env.str("AWS_DEFAULT_ACL", default="public-read")

STATICFILES_DIRS = (str(BASE_DIR.joinpath("static")),)
STATIC_ROOT = str(BASE_DIR.joinpath("staticfiles"))
MEDIA_ROOT = str(BASE_DIR.joinpath("media"))

if USE_S3_STORAGE:
    DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
    STATICFILES_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"

    STATIC_URL = f"https://{AWS_S3_ENDPOINT_URL}/{STATIC_ROOT}/"
    MEDIA_URL = f"https://{AWS_S3_ENDPOINT_URL}/{MEDIA_ROOT}/"

else:
    STATICFILES_STORAGE = "django.contrib.staticfiles.storage.StaticFilesStorage"
    STATIC_URL = "static/"
    MEDIA_URL = "/media/"

Enter fullscreen mode Exit fullscreen mode

SSL

A valid SSL certificate is supplied automatically:

SECURE_SSL_REDIRECT = env.bool("SECURE_SSL_REDIRECT", default=False)
SECURE_HSTS_SECONDS = env.int("SECURE_HSTS_SECONDS", default=0)
SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool(
    "SECURE_HSTS_INCLUDE_SUBDOMAINS", default=False
)
SECURE_HSTS_PRELOAD = env.bool("SECURE_HSTS_PRELOAD", default=False)

SESSION_COOKIE_SECURE = env.bool("SESSION_COOKIE_SECURE", default=False)
CSRF_COOKIE_SECURE = env.bool("CSRF_COOKIE_SECURE", default=False)
Enter fullscreen mode Exit fullscreen mode

PIP requirements

The following packages are required:

django
gunicorn
django-environ
psycopg2-binary
boto3
django-storages
Enter fullscreen mode Exit fullscreen mode

With the help of the requirements.txt file, the buildtool later also recognizes that this is a python project.

App Platform

Now that everything is ready, you can start creating the Django project on DO. A detailed instruction i save me at this point, because the docs and further post about it on the internet are very good.

Important settings are (example Dev-Case):

  • run_command: gunicorn dev_case.wsgi:application --bind 0.0.0.0:8080 --worker-tmp-dir /dev/shm
  • http_port: 8080

Depending on the project structure:

routes:
  - path: /
source_dir: /
Enter fullscreen mode Exit fullscreen mode

With a "dev" database a dynamic variable can be used as environment variable. Example: ${db.DATABASE_URL}. In this case the name of the database would be db.

When using a managed-databases from DO, you should create the database manually and not via the GUI. Otherwise, errors may occur with a redeploy. I will link a post about it here soon.

edited (2022-09-26): link to the post mentioned above.

After the build process completes:

Access your app’s console through the console tab and run the following commands:

  • python3 manage.py migrate for the initial database migrations
  • python3 manage.py createsuperuser to create an administrative user

S3 and CORS

To prevent later errors with CORS, make the following adjustment in your Space setting:

Your Space -> Settings -> CORS Configurations (Add):

  • Add your domain (with wildcard) in "Origin", examples:
    • *ondigitalocean.app
    • *example.com
  • Allow/Check:
    • GET, HEAD

This should solve the problems with fonts, scripts etc. (missing header, Access-Control-Allow-Origin).

Conclusion

I am very satisfied with DO's APP-Platform so far. The performance is good and i feel safe. Soon i will test the log forwarding. If there is something to write about it, i will link it here.


Thanks for reading.

Originally published at rburkhardt.com
Feel free to subscribe to my RSS and connect on Twitter or Github

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay