This page takes you through setting up instellar for a Django application. You will learn how to configure your application to run on your PaaS
We’ve created an example application in case you wish to skip right to the source code.
A note on INSTELLAR_ENDPOINT
The examples in the codebase we referenced the
.github/workflows/deployment.yml file will contain a value for
INSTELLAR_ENDPOINT this is only necessary in those repositories since they’re deploying to our staging environment. For our customers we recommend omitting this value.
In this example we build python into a zipapp using a tool called shiv. It adheres to the PEP 441
In our example application you will notice a file in the
monty directory. It looks something like this. You will need a variation of this in your app. In our example we’re running the app using gunicorn. We also enable the
import os import sys import django import gunicorn.app.wsgiapp as wsgi from django.core import management def run(): # setup django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "monty.settings.development") django.setup() match sys.argv: case "web": # This is just a simple way to supply args to gunicorn sys.argv = [".", "monty.wsgi", "--bind=0.0.0.0:8000", "-p server.pid"] wsgi.run() case "migrate": management.call_command("migrate") case _: sys.stdout.write("please pass in a valid command [web, migrate]") if __name__ == "__main__": run()
This file is used to describe to PAKman how to build your application. The following is taken from a Django based application. This configuration will change depending on your application. This file will work with a freshly generated django app.
Let’s begin with the
dependencies. You will also notice we’re enabling
trace: true in our dependencies. This will enable dependency tracing, which means even if we miss some dependency in our
runtime the build tool will trace the dependency and automatically include it in our package. That’s cool!
dependencies: trace: true build: - python3 - py3-pip runtime: - bash - curl - jq - s6 - python3 - py3-pip - monty-openrc - libpq - ca-certificates
Choosing a Stack
We’re using alpine as the base image for all the containers that run the applications. We recommend using
alpine/3.17 for all applications. However please check the alpine packages listing to see compatibility for your language and framework. In this case alpine/3.17 will run python
You can choose from the following:
The below section tells PAKman how to actually build your application. In this case we’re simply exporting the
$PATH so our pip based binaries can be called. We then install
shiv and then install our application dependencies into the
dist/ directory. We then copy the
manage.py script into the
dist/ directory. Now our
dist directory is ready for
We call shiv with the
--site-packages option set to
dist. We add the
--compressed flag so
shiv will compress the build. We set the
-p flag to define the shebag that shiv will use to locate python. The
-o flag stands for output, shiv will build our application into a single executable binary as
dist/bin/monty. Finally we add the
-e flag, this defines the entry point for our application. We reference the
run function in the
main.py that we created earlier.
build: destinations: - dist/bin command: | export PATH=$PATH:$HOME/.local/bin pip install shiv pip install -r requirements.txt --target dist/ cp -r monty polls manage.py dist/ shiv --site-packages dist --compressed -p '/usr/bin/env python3' -o dist/bin/monty -e monty.main:run
The below section explains how your application is run. You can see we have the ability to define
commands. These are commands you wish to run like migrations or seeds if you have them.
services section enables you to define how your application is run. How does it start? In this case we’re using the kill pid. In the above
main.py section we set the
-p flag to output the pid file in the same directory as our app, so we will use the same path for our
run: name: monty commands: - name: migrate binary: monty call: 'migrate' services: - name: web binary: monty start: call: web
These are the lifecycle of the alpine packages. You can define their behaviour. Generally we don’t expect this to change from app to app. However feel free to adjust as required.
In this case
rc-update add monty will add our
monty app to the default run. This will ensure our app automatically starts when the container is restarted (incase it needs to restart).
rc-service monty migrate will run the migration. In this case it will run after the package is installed and after the upgrade.
rc-service monty startwill start the application
rc-service monty stopwill simply stop the application
Your application will be built into openrc and supervised by the
s6 supervisor suite.
hook: post-install: | rc-update add monty rc-service monty migrate pre-upgrade: | rc-service monty stop post-upgrade: | rc-service monty migrate rc-service monty start post-deinstall: | rc-service monty stop rc-update del monty
Putting it together
The final file looks like the following:
dependencies: trace: true build: - python3 - py3-pip runtime: - bash - curl - jq - s6 - python3 - py3-pip - monty-openrc - libpq - ca-certificates stack: alpine/3.17 build: destinations: - dist/bin command: | export PATH=$PATH:$HOME/.local/bin pip install shiv pip install -r requirements.txt --target dist/ cp -r monty polls manage.py dist/ shiv --site-packages dist --compressed -p '/usr/bin/env python3' -o dist/bin/monty -e monty.main:run run: name: monty commands: - name: migrate binary: monty call: 'migrate' services: - name: web binary: monty start: call: web hook: post-install: | rc-update add monty rc-service monty migrate pre-upgrade: | rc-service monty stop post-upgrade: | rc-service monty migrate rc-service monty start post-deinstall: | rc-service monty stop rc-update del monty