Django Deployment - 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';
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';
Finally we can change the privileges for our new user:
GRANT ALL PRIVILEGES ON DATABASE djangodb TO djangouser;
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",
}
}
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).