Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/sesh/django-up

🚀 Zero configuration Django deployments
https://github.com/sesh/django-up

ansible deployment devops django letsencrypt python

Last synced: 7 days ago
JSON representation

🚀 Zero configuration Django deployments

Awesome Lists containing this project

README

        

# django-up

`django-up` is a tool to quickly deploy your Django application to a Ubuntu 22.04 server with almost zero configuration.

```shell
python manage.py up django-up.com --email=
```

Running `django-up` will deploy a production ready, SSL-enabled, Django application to a VPS using:

- Nginx
- Gunicorn
- PostgreSQL
- SSL with acme.sh (using Let's Encrypt)
- UFW
- OpenSMTPd

## Supporting this project

The easiest way to support the development of this project is to use [my Linode referal code][linode] if you need a hosting provider.
By using this link you will receive a $100, 60-day credit once a valid payment method is added.
If you spend $25 I will receive $25 credit in my account.

`django-up` costs around $7/month to host on Linode, referrals cover that cost, plus help to support my other projects hosted there. I've used various hosting providers over the years but Linode is the one that I like the most.

_This is the only place where referral codes are used. All other links in the documentation will take you to the services without my reference._

## Quick Start (with Pipenv)

Create a new VPS with your preferred provider and update your domain's DNS records to point at it.
Check that you can SSH to the new server as `root` before continuing.

Ensure that `ansible` is installed on the system your are deploying from.

Create a directory for your new project and `cd` into it:

```shell
mkdir testproj
cd testproj
```

Install Django, PyYAML and dj_database_url:

```shell
pipenv install Django pyyaml dj_database_url
```

Start a new Django project:

```shell
pipenv run django-admin startproject testproj .
```

Run `git init` to initialise the new project as a git repository:

```shell
git init
```

Add `django-up` as a git submodule:

```shell
git submodule add [email protected]:sesh/django-up.git up
```

Add `up` to your `INSTALLED_APPS` to enable the management command:

```python
INSTALLED_APPS = [
# ...
'up',
]
```

Add your target domain to the `ALLOWED_HOSTS` in your `settings.py`.

```python
ALLOWED_HOSTS = [
'djup-test.brntn.me',
'localhost'
]
```

Set the `SECURE_PROXY_SSL_HEADER` setting in your `settings.py` to ensure the connection is considered secure.

```python
SECURE_PROXY_SSL_HEADER = ('HTTP_X_SCHEME', 'https')
```

Set up your database to use `dj_database_url`:

```python
import dj_database_url
DATABASES = {
'default': dj_database_url.config(default=f'sqlite:///{BASE_DIR / "db.sqlite3"}')
}
```

Generate a new secret key (either manually, or with a [trusted tool](https://utils.brntn.me/django-secret/)), and configure your application to pull it out of the environment.

In `.env`:

```
DJANGO_SECRET_KEY=
```

And in your `settings.py` replace the existing `SECRET_KEY` line with this:

```
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
```

Create a requirements file from your environment if one doesn't exist:

```shell
pipenv lock -r > requirements.txt
```

Deploy with the `up` management command:

```shell
pipenv run python manage.py up yourdomain.example --email=
```

## Extra Configuration

### Setting environment variables

Add environment variables to a `.env` file alongside your `manage.py`. These will be exported into the environment before running your server (and management commands during deployment).

For example, to configure Django to load the `SECRET_KEY` from your environment, and add a secure secret key to your `.env` file:

`settings.py`:

```python
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
```

`.env`:

```
DJANGO_SECRET_KEY="dt(t9)7+&cm$nrq=p(pg--i)#+93dffwt!r05k-isd^8y1y0"
```

### Specifying a Python version

By default, `django-up` uses Python 3.8.
If your application targets a different version you can use the `UP_PYTHON_VERSION` environment variable.
Valid choices are:

- `python3.8`
- `python3.9`
- `python3.10` (default)
- `python3.11`

```python
UP_PYTHON_VERSION = "python3.11"
```

These are the Python version available in the deadsnakes PPA.
Versions older than Python 3.8 require older versions of OpenSSL so are not included in the PPA for Ubuntu 22.04.

### Deploying multiple applications to the same server

Your application will bind to an internal port on your server.
To deploy multiple applications to the same server you will need to manually specify this port.

In your `settings.py`, set `UP_GUNICORN_PORT` is set to a unique port for the server that you are deploying to:

```python
UP_GUNICORN_PORT = 8556
```

### Using manifest file storage

To minimise downtime, during the deployment `collectstatic` is executed while your previous deployment is still running.
In order make sure that the correct version of static files are used _during the deployment_ you can use the `ManifestStaticFilesStorage` storage backend that Django provides.

```python
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
```

For most projects using this backend will be a best practice, regardless of whether you are deploying with `django-up`.

### Supporting multiple domains

As long as all domains that you plan on supporting are pointing to your server, you can include them in your `ALLOWED_HOSTS`.
Certificates will be requested for each domain.

For example, so support both the apex and `www` subdomain for a project, your could configure your application with:

```python
ALLOWED_HOSTS = [
'django-up.com',
'www.django-up.com'
]
```

### Adding `django-up` directly to your project

If you are likely to customise the Ansible files then it's probably easier to just add the `django-up` files to your own git repository, rather than using a submodule.

You can use a shell one liner to download the repository from Github and extract it into an "up" directory in your project:

```shell
mkdir -p up && curl -L https://github.com/sesh/django-up/tarball/main | tar -xz --strip-components=1 -C up
```

[django]: https://www.djangoproject.com
[linode]: https://www.linode.com/lp/refer/?r=46340a230dfd33a24e40407c7ea938e31b295dec