Skip to content
This repository has been archived by the owner on Jun 7, 2024. It is now read-only.

Django Specific Enhancements #3

Open
kian99 opened this issue Sep 14, 2022 · 1 comment
Open

Django Specific Enhancements #3

kian99 opened this issue Sep 14, 2022 · 1 comment

Comments

@kian99
Copy link

kian99 commented Sep 14, 2022

Enhancement Proposal

Hi,

I've been following the dev of this Gunicorn charm and it is a really cool general charm. What I'm hoping for is the ability to use it with my Django application which I feel has a pretty common workflow (even across non Django applications). Before I can do that however there are 2 things missing. To mold it to my needs, I've lifted a lot of the charm logic and made a specific charm for my application but I'm hoping I can switch over to this charm again when/if it fits my use case (my attempt at that can be seen here).

1. Nginx Sidecar
In order to server static files for my Django app I need Nginx setup as a sidecar container with the static files in the container and a config file for Nginx. Currently I've emulated what's done in the Indico operator charm and I have an image that installs Nginx and populates the static files + config and I deploy that alongside my workload container.

I can think of some options to accomodate this,

  • Create an additional resource in metadata.yaml that would accept an nginx image we could use for serving up static files. The user then needs to create a separate image with the static files and Nginx config and supply that image when deploying the gunicorn charm.
  • Don't create an additional resource but instead add some logic to the charm to automatically fetch an Nginx image and populate it with resources from the workload container using pebble.

An additional setting could also be added to config.yaml like NGINX_ENABLED which could potentially enable/disable the Nginx functionality if an app doesn't require it?

Alternatively, and I'm not sure if this is the right approach,

  • Identify/create an Nginx charm that would relate to the gunicorn charm and request a config and a tar of static files? This wouldn't be a sidecar though and I'm not sure how scaling would work here.

2. Running schema migrations
For my application I require that schema migrations are run when the app is deployed. Currently I set my app not to startup automatically, only once Postgres is related and the schema migration is run does the app start. The flow is,
Deploy app (Blocked waiting for postgres) -> Postgres related -> Schema migration run (set a peer relation value so that we don't run the migration again) -> start Gunicorn server.

The challenge here is that to make it general, every app will have it's own command and set of pre-conditions. In my application/charm, the command resembles the following,

process = container.exec(
                command=[
                    "/usr/bin/python3",
                    "/code/manage.py",
                    "migrate",
                    "--noinput",
                ],
                environment={"DATABASE_URL": db_uri},
            )

where db_uri is obtained from

pg_data = self._stored.reldata.get("pg", {})
db_uri = pg_data.get("db_uri")

and the pre-condition is that the Postgres relation exists (i.e. db_uri is populated).

In a conversation with @mthaddon the idea came up that the entrypoint of the image could be used to define the command and the pre-condition can be verified by checking that the required environment variables are set. I imagine the environment variables would be templatted as is done in the config.yaml, so setting something like the following perhaps inside your dockerfile,
ENTRYPOINT DATABASE_URL={{pg.db_uri}} python3 /code/manage.py migrate --noinput

Those 2 issues are pretty much it. Happy to discuss or elaborate further on anything above. Really cool work going on here, thanks!

@mthaddon
Copy link
Contributor

Thanks for the input. There's a fair amount to digest there, and we'll need to draw up some design documents for each one (although the second point may end up being more about documenting recommended behaviour than anything else). We'll look into this and update this ticket once we have a path forward.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants