A simple Railway template project
- Bootstrap
- Dockerfile
- Docker Compose
- Django
- HTMX
For local development, docker compose up
will configure and launch all necessary services.
Additional packages can be added to the requirements/local.txt
. Rebuild image if necessary.
Local development depends on two settings
files. These are:
website/settings/base.py
website/settings/local.py
Modify base.py when you want those settings reflected on the local and production images, and local.py when you only want to see those settings locally.
Environment customization is made possible through the docker-compose.yaml
file, or through an .env
file at the
root. When a .env
file exists at the root, docker compose
will automatically load the variables.
Default variables are provided, but they can easily be overridden.
# docker-compose.yaml
# ...
local:
# ...
environment:
DATABASE_URL: postgresql://user:password@postgres/database
DJANGO_SUPERUSER_EMAIL: local@email.com
DJANGO_SUPERUSER_PASSWORD: password
DJANGO_SUPERUSER_USERNAME: local
# ...
By default, a DATABASE_URL
is configured that connects to the PostgreSQL
Docker
service.
To automate superuser
creation, the DJANGO_SUPERUSER_EMAIL
DJANGO_SUPERUSER_PASSWORD
and
DJANGO_SUPERUSER_USERNAME
environment variables are defined and will be used by the service on launch.
Additional environment variables can also be defined so that they override the defaults found
in website/settings/local.py
\
A few volumes
are also defined so that the server can restart itself when it detects changes in those directories.
Add and remove volumes as needed.
# ...
volumes:
- ./static:/railway/static
- ./templates:/railway/templates
- ./website:/railway/website
# ...
If Docker
is not an option, you can still run the project, but additional configuration will be necessary.
To begin, create and activate a virtual environment
# System dependent; will not work on every OS
python -m venv venv
source venv/bin/activate
Install local requirements
pip install -r requirements/local.txt
Migrate -- if DATABASE_URL
is not supplied as an environment variable, project will default to a SQLite DB
python manage.py migrate
Start server
python manage.py runserver_plus --nostatic
The simplest way is to deploy the project is to create a New Project
through the Railway Dashboard
, or CLI, and
selecting Deploy a Template
After a few brief dialogs, project should be fully configured and online.
You can also clone the GitHub repository and launch the project using the following steps:
railway link
railway up
Once the project has been deployed to Railway
, you can override many of the settings found in
website/settings/base.py
or website/settings/production.py
through the Railway
interface.
Simply define a new environment variable on Railway
and wait for the project to be redeployed.
For every deploy on Railway
, or docker compose up
, the Dockerfile
dynamically builds a sh
script that will
then be executed by the relevant service's Docker CMD
Locally, when this script is executed, it begins by executing manage.py migrate
, followed by
manage.py createsuperuser
, if the environment variables are defined, and ultimately manage.py runserver_plus
In production
, manage.py migrate
will be called first, followed by manage.py createsuperuser
and then
manage.py collecstatic
, manage.py check --deploy
, and lastly gunicorn website.wsgi
Locally, you have two options:
Execute a command inside a running Docker
service:
docker compose exec local ...
Or by modifying the railway.sh
script that is generated by the Dockerfile
build stages explained below
Since connecting to a running container on Railway
is not possible, you must alter the Dockerfile
For example:
If you wanted to add a command to output all the Django settings being used in deployment, then you could alter
the Dockerfile
's production
build stage RUN
command as so:
FROM base as production
# ...
RUN <<CAT cat >> ./railway.sh
python manage.py collectstatic --no-input
python manage.py check --deploy
# ---
python manage.py diffsettings --all
# ---
gunicorn website.wsgi
CAT
# ...
CMD ./railway.sh
The same change could also be performed on the Dockerfile
's base
build stage, but be aware that
python manage.py migrate --no-input
should generally be the first command that is executed since createsuperuser
, collectstatic
, etc... will
be dependent on it.
You could then execute railway up
or git add ... git commit ... git push
, to have Railway
redeploy the
project. If you wanted to see these changes locally, then rebuild the image and rerun docker compose up