Django + reverse proxy beginning

I have a colleague who has a non jujufied django development server running on and would like to start testing with just adding a reverse proxy on or via a juju charm to get started.

As a second step, trying to tie it up with juju-fying the django site.

Is there anyone that could provide the beginner level spells (charms etc.) to get him started?

I’ll see if I can get him in here to get some help.


@sssler-scania I think the idea is to snap the django process first. By doing this, you create an idempotent package (django process snap) that the the charm code can provision and facilitate lifecycle for. This allows for the charm to keep a sharper focus on coordinating information between units/applications, and provides and better way to deliver the django app by snapping it. I have an example flask snap that could serve as a starting point for you.

Hope this helps!

1 Like

@jamesbeedy - It does help alot with the second part of the challenge! Thanx, but it doesn’t quite help the problem that there is a fair bit of ground to cover to get a snap in place before my colleague can get a result.

By that time, he has already given up on jujuto solve this simple as-hands problem.

So, addressing the first problem (getting a reverse-proxy in front of the application) - would be of more value at this point where we can address the second problem in the way you propose.

I have two small example charms I have used for debugging relation events in the past.

To facilitate your use case of multiple web servers and a reverse proxy, you would need to have the units of your webserver application charm set the information they want to communicate to the reverse proxy on the relation data. In this simple use case, the webserver units would set their listening hostname and port on the relation data.

This example provides interface does what you would want your web server charm to do, it sets the hostname and port of the listening web server process on it’s unit data in the relation_created event.

The other side of the relation would acquire the data set by the webserver units when data changes on the relation by observing the relation_changed event. The reverse proxy charm would then want to iterate over the webserver units of the related application grabbing the hostname and port of each, and write out the reverse proxy config once it gets the webserver data out of the relation.

event cycle docs
best practice for using relations with operator
operator framework docs

Appreciate your help James!

However, the user do not have a juju-fied django. The reason for the reverse proxy in this case is to allow the user to have the webserver listening on a high-port running as a non privilegued user, and the reverse proxy binding to a low port number :80 and/or :443 which the non-privilegued user can’t (requires root).

So, consider you have no capability to relate to the django application but would like to deploy perhaps apache or something similar that can relay the traffic from port :80 or :443 ->


I am the one who need help with this. Your help is much appreciated.

1 Like

When we had some legacy or development code running somewhere that needed a reverse proxy and we didn’t want to commit time to create a charm yet. We used a small http-proxy charm.

You can set the host and port via the config and then relate to the ssl-termination-proxy as a subordinate charm.

Note: I havn’t used this charm in a long while so some stuff might not be working anymore since the last updates to the ssl-termination charm but I think the intent is clear here.

Edit: I’ve digged into some old code and found a charm modified to proxy the latest ssl-termination-proxy charm. I’ve pushed the code here.

1 Like

@sborny - Would you be able to provide an example deploy of this?

juju deploy xxxxx
juju config yyyyy

etc. @martinandersson is just taking his first steps and while this seems trivial - its of great help to have the commands outlined. Its the same for me really.

The proxy charm will need to be build locally and you need a domain for Lets Encrpyt.

So clone to your /charms/layers directory.

$ cd ~/charms/layers
$ git clone

Clone the ssl-termination interface.

$ cd ~/charms/interfaces
$ git clone

Build the proxy charm.

$ cd ~/charms/layers/ssl-termination-fqdn-proxy
$ charm build

This should give you a ready to deploy charm in your ~/charms/builds folder.
Deploy the proxy charm, I have given this the name django-app:

$ juju deploy ~/charms/builds/ssl-termination-fqdn-proxy django-app

Configure the django-app charm. If my app is running for example on a machine with ip on port 8080.

juju config django-app upstreams=""
juju config django-app fqdns=""

If you want basic auth:

juju config django-app basic_auth="username password"

Deploy the reverse proxy:

juju deploy cs:ssl-termination-proxy-5

Add the relation:

juju add-relation ssl-termination-proxy django-app

Your app should now be behind a NGINX with https.

1 Like