Looking to get started with Upsun and Python? The Upsun CLI contains a command called project:init
designed to get you started on Upsun with a number of frameworks—including Django—as quickly as possible.
Let’s start with a simple Django codebase, in this case using the popular Python templating utility cookiecutter:
cookiecutter https://github.com/cookiecutter/cookiecutter-django
The cookiecutter CLI will prompt you to answer a series of questions about email, CI tools, and IDE. Answer according to your preference, but be sure to:
After finishing the prompts, you’ll have a new skeleton project in whichever directory you passed as the name (in the examples below, new_project):
.
├── README.md
├── bin
├── compose
├── config
| ├── __init__.py
| ├── api_router.py
| ├── celery_app.py
| ├── settings
| | ├── __init__.py
| | ├── base.py
| | ├── local.py
| | ├── production.py
| | └── test.py
| ├── urls.py
| └── wsgi.py
├── docs
├── locale
├── manage.py
├── new_project
| ├── __init__.py
| ├── conftest.py
| ├── contrib
| ├── static
| ├── templates
| ├── users
| └── utils
├── package.json
├── requirements
├── requirements.txt
├── setup.cfg
├── tests
└── webpack
With the project in place, we can then generate a first draft of our Upsun configuration using the CLI:
cd new_project && upsun project:init
Follow the prompts to include configuration for both PostgreSQL and Redis. This command will automatically detect the Django project based on the presence of a manage.py
file, and generate two pieces of configuration: an environment file and a primary configuration YAML file.
The .environment
file at the root of the project which will be created, sets environment variables that the cookiecutter project needs. You can inspect this file yourself, but a few important pieces that become available include general Django project settings:
# .environment
export DJANGO_SETTINGS_MODULE=config.settings.production
export DJANGO_SECRET_KEY="$PLATFORM_PROJECT_ENTROPY"
export DJANGO_ALLOWED_HOSTS=".platformsh.site"
This section appends Django’s allowed hosts to include all URLs generated for Upsun preview environments, to update Django’s secret key to match the unique project hash, and to leverage production settings (in this case) across all Upsun environments.
Additional credentials are expanded from built-in environment variables to establish connections with managed services provided by Upsun:
# .environment
# Set database environment variables
export DB_HOST="$POSTGRESQL_HOST"
export DB_PORT="$POSTGRESQL_PORT"
export DB_PATH="$POSTGRESQL_PATH"
export DB_USERNAME="$POSTGRESQL_USERNAME"
export DB_PASSWORD="$POSTGRESQL_PASSWORD"
export DB_SCHEME="$POSTGRESQL_SCHEME"
export DATABASE_URL="${DB_SCHEME}://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_PATH}"
# Set Cache environment variables
export CACHE_HOST="$REDIS_HOST"
export CACHE_PORT="$REDIS_PORT"
export CACHE_SCHEME="$REDIS_SCHEME"
export CACHE_URL="${CACHE_SCHEME}://${CACHE_HOST}:${CACHE_PORT}"
# Set Redis environment variables
export REDIS_URL="$CACHE_URL"# Celery
export CELERY_BROKER_URL="$CACHE_URL"# General
An .upsun/config.yaml
file is also added that configures build, deploy, and available services for the project. It includes configuration for the services you selected via prompts:
# .upsun/config.yaml
services:
postgresql:
type: postgresql:15
redis:
type: redis:7.0
Application configuration is also added. It defines how Django is built and deployed via pip, how access is granted to the above services via relationships
, and how to run the server with Gunicorn:
# .upsun/config.yaml
applications:
new_project:
type: "python:3.11"
hooks:
build: |
set -eux
pip install --upgrade pip
pip install -r requirements.txt
npm install
npm run build
deploy: |
set -eux
python manage.py collectstatic --noinput
python manage.py migrate
web:
commands:
start: "gunicorn -b unix:$SOCKET config.wsgi"
upstream:
socket_family: unix
locations:
"/":
"passthru": true
"/static":
"allow": true
"expires": "1h"
"root": "static"
mounts:
"/staticfiles":
"source": "local"
"source_path": "static_assets"
relationships:
postgresql: "postgresql:postgresql"
redis: "redis:redis"
With these two pieces of configuration, we can create a new project and deploy Django on Upsun:
$ git add . && git commit -m “Prepare for Upsun!”
$ upsun project:create
$ upsun push
With this production environment deployed, we can now adjust the resources provided to that environment with the CLI command upsun resources:set
.
You may have noticed that the cookiecutter project expected credentials to configure connect to Redis to run Celery to manage tasks for the application. We included an environment variable to connect but didn’t specify how to actually run that service.
We can now create a new preview environment that can match production with respect to its build images, containers, data, and resources as much as we’d like.
$ upsun branch try-celery --type staging
From this environment we can once again commit and push, with some Celery workers defined:
# .upsun/config.yaml
applications:
new_project:
...
workers:
celery_worker:
commands:
start: "celery -A config.celery_app worker"
celery_beat:
commands:
start: "celery -A config.celery_app beat"
Test the connection and performance of the workers in the isolated environment, and then when you’re satisfied promote the new workers to production:
$ upsun merge try-celery
And just like that, your next Django project is up, running, and ready to go with Upsun's Django PaaS!