DEV Community

Cover image for Django Deployment - Postgres DBaaS
rburkhardt
rburkhardt

Posted on • Originally published at rburkhardt.com

1

Django Deployment - Postgres DBaaS

During my last attempt to get a Postgres server up and running, I realized again how time consuming it actually is. In addition to the installation of the Postgres server, the whole server has to be secured. This can take a lot of time. With a small vps with many users there is also the limited perfomrnace.

The alternative: DBaaS (Database-as-a-Service).

The advantages of a DBaaS are simple:

  • Time saving (server management and installation)
  • Security ( reduced risk and best practice)
  • Data-Security (automatic backups)
  • Scalability (fast and easy to scale down and up)

Providers I can recommend are:

The service from fly.io Postgres on Fly also looks very promising.

Preparations

Postgres

  • login: psql -U doadmin -h host -p port -d database
  • database creation: CREATE DATABASE djangodb;
  • switch to the new db: \c djangodb;

After that we can create the new user with a secure password:

CREATE USER djangouser WITH PASSWORD 'securepassword';
Enter fullscreen mode Exit fullscreen mode

For everything to work smoothly django recommends the following paramenter (see django-docs):

ALTER ROLE djangouser SET client_encoding TO 'utf8';

ALTER ROLE djangouser SET default_transaction_isolation TO 'read committed';

ALTER ROLE djangouser SET timezone TO 'UTC';
Enter fullscreen mode Exit fullscreen mode

Finally we can change the privileges for our new user:

GRANT ALL PRIVILEGES ON DATABASE djangodb TO djangouser;
Enter fullscreen mode Exit fullscreen mode

Django

Here i decided to use django-environ's env.db() for the DATABASE_URL.


import os
from pathlib import Path
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)

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

Note about DigitalOcean's App Platform:

If we use DigitalOcean's App Platform, we can skip the dynamic variable ${dbname.DATABASE_URL} as DATABASE_URL. This has always led to an empty database for me with a redeploy. Even if I created a database via DO's GUI before, and changed the variable accordingly.

To ensure that our data is also available after a redeploy in the future, we can use the Postgres-String as variable (with encryption on).

Conclusion

(in connection with DO's Postgres DBaaS)

I am very happy with the performance so far. If I need connection pooling (via PgBouncer) later, I can add it quickly and easily via DO's GUI. The price is a bit expensive for a single and smaller project, but quickly pays off when another project is added. With DigitalOcean the fun starts at 15€ and 3 databases (1GB Memory, 1 vCPU, 15GB Disk).


Thanks for reading.

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

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

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