More actions
| Line 81: | Line 81: | ||
=== Use .env files with Django === | === Use .env files with Django === | ||
Use a .env file. I'll use django-environ:<syntaxhighlight lang="python3"> | Use a .env file. I'll use django-environ: | ||
<syntaxhighlight lang="python3"> | |||
from pathlib import Path | |||
import os | |||
from environ import Env | from environ import Env | ||
... | ... | ||
Revision as of 14:31, 24 July 2025
THIS IS A WIP!
This (unofficial) guide was made by @twonum (feel free to DM me for help).
I'm using Hypercorn as it's an ASGI server (for WebSockets support). To use a different server, replace the hypercorn commands with the ones that your server uses.
- Tools this guide uses
- Hypercorn ASGI server
- Caddy reverse proxy and web server with automatic HTTPS
- PostgreSQL relational database for Django's ORM
- systemd "daemon" (as it's called in Unix) to manage services
I'll assume that orpheus is your username and this is your directory structure:
- ~ (/home/orpheus)
- project
- .venv
- manage.py
- ...
- static
- project
- static
- media
- project
- project.sh
- Caddyfile
- .config
- ...
- project
I'll use $THIS_VARIABLE_NOTATION. Make a mental note of exports and replace the pseudo-variables with actual values.
Getting ready
First, get a shell to Nest. Don't have a Nest account?
ssh orpheus@hackclub.appGet Nest resources
export PROJECT_NAME="your project directory name" # set this to your project's directory name (like "project" in /home/$USERNAME/project)
nest db create $PROJECT_NAMEhackclub.app or custom domain?
$PROJECT_NAME.$USERNAME.hackclub.app (free)
export PROJECT_DOMAIN=$PROJECT_NAME.$USERNAME.hackclub.app
nest caddy add $PROJECT_DOMAINCustom domain (looks better, but you need your own DNS)
Add a CNAME record to $USERNAME.hackclub.app.
If you use Cloudflare or another proxy, turn the proxy off.
Wait and run this to check your DNS record:
export PROJECT_DOMAIN="hello.example.com" # set this
dig $PROJECT_DOMAIN CNAMEThen:
nest caddy add $PROJECT_DOMAINGet your project's files on Nest
Copy the directory containing manage.py to /home/$USERNAME/$PROJECT_NAME. See Quickstart#Using_the_Account.
cd ~/$PROJECT_NAMESet up venv and dependencies
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtSet up Django settings
Use .env files with Django
Use a .env file. I'll use django-environ:
from pathlib import Path
import os
from environ import Env
...
env = Env(
DEBUG=(bool, False),
ALLOWED_HOSTS=(list, []),
)
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
BASE_DIR = Path(__file__).resolve().parent.parent
def _env_file(key: str) -> str:
env_ = env(key)
if env_[:2] == './':
return str(BASE_DIR / env_[2:])
return str(Path(env_))
...
DEBUG = env("DEBUG")
ALLOWED_HOSTS = env('ALLOWED_HOSTS')
SECRET_KEY = env("SECRET_KEY")
DATABASES = {
'default': env.db(),
}
STATIC_URL = env("STATIC_URL")
STATIC_ROOT = _env_file("STATIC_ROOT")
MEDIA_URL = env("MEDIA_URL")
MEDIA_ROOT = _env_file("MEDIA_ROOT")
... # Use the same format for other optionsWhat your .env file should look like
DEBUG=False
ALLOWED_HOSTS=$PROJECT_DOMAIN
SECRET_KEY=please-change-this
DATABASE_URL=psql://$USERNAME:$NEST_PASSWORD@127.0.0.1:5432/$USERNAME_$PROJECT_NAMESome other options to tweak
STATIC_ROOT=$HOME/static/$PROJECT_NAME/static
STATIC_URL=/static/
MEDIA_ROOT=$HOME/static/$PROJECT_NAME/media
MEDIA_URL=/media/Migration and static collection
source .env
python3 manage.py migrate
python3 manage.py collectstaticSet up Hypercorn
Get a port
nest get_portRemember this number and store it in the mental variable $PORT.
From my experience, the port might get taken quickly. In that case, just get a new port and change the old one in existing files.
This is the internal port (on Nest); the actual application uses port 443 (the standard HTTPS port).
Create the run script
~/$PROJECT_NAME.sh
#!/bin/bash
cd $PROJECT_NAME
source .venv/bin/activate
hypercorn -b 127.0.0.1:$PORT $PROJECT_NAME.asgi:applicationSet up systemd with the run script
~/.config/systemd/user/$PROJECT_NAME.service
[Unit]
Description=YOUR DESCRIPTION HERE
[Service]
WorkingDirectory=%h/$PROJECT_NAME
EnvironmentFile=%h/$PROJECT_NAME/.env
ExecStart=bash ../$PROJECT_NAME.sh
Restart=on-failure
[Install]
WantedBy=default.targetStart the service
systemctl --user daemon-reload
systemctl --user enable --now $PROJECT_NAME.service
systemctl --user status $PROJECT_NAME.serviceSet up the Caddy server
~/Caddyfile
Append this:
http://$PROJECT_DOMAIN {
bind unix/.$PROJECT_DOMAIN.webserver.sock|777
handle /static* {
root * $HOME/static/$PROJECT_NAME
file_server
}
handle /media* {
root * $HOME/static/$PROJECT_NAME
file_server
}
reverse_proxy :$PORT
}Restart Caddy service
systemctl --user restart caddy.serviceCheck it out
Go to $PROJECT_DOMAIN in your browser.
It should probably work. If not, please Dungeon Master @twonum who is at fault for writing this guide.
Avoiding hiccups
Make sure that it continues to work; if not, there's probably something wrong with the config.