Update documentation for deploying on PythonAnywhere with uv (#6017)

This commit is contained in:
Bruno Alla 2025-09-14 14:09:47 +01:00 committed by GitHub
parent 6c389f6760
commit 38b1ba3fce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -11,7 +11,7 @@ Full instructions follow, but here's a high-level view.
**First time config**: **First time config**:
1. Pull your code down to PythonAnywhere using a *Bash console* and setup a virtualenv 1. Pull your code down to PythonAnywhere using a *Bash console* and install your dependencies
2. Set your config variables in the *postactivate* script 2. Set your config variables in the *postactivate* script
@ -21,57 +21,56 @@ Full instructions follow, but here's a high-level view.
5. Set your config variables in the PythonAnywhere *WSGI config file* 5. Set your config variables in the PythonAnywhere *WSGI config file*
Once you've been through this one-off config, future deployments are much simpler: just ``git pull`` and then hit the "Reload" button :) Once you've been through this one-off config, future deployments are much simpler: just ``git pull`` and then hit the "Reload" button :)
Getting your code and dependencies installed on PythonAnywhere Getting your code and dependencies installed on PythonAnywhere
-------------------------------------------------------------- --------------------------------------------------------------
Make sure your project is fully committed and pushed up to Bitbucket or Github or wherever it may be. Then, log into your PythonAnywhere account, open up a **Bash** console, clone your repo, and create a virtualenv: Make sure your project is fully committed and pushed up to Github, GitLab or wherever it may be. Then, log into your PythonAnywhere account, open up a **Bash** console, clone your repo, and install your project:
.. code-block:: bash .. code-block:: bash
git clone <my-repo-url> # you can also use hg git clone <my-repo-url>
cd my-project-name cd my-project-name
mkvirtualenv --python=/usr/bin/python3.12 my-project-name uv sync --locked --no-dev # may take a few minutes
pip install -r requirements/production.txt # may take a few minutes
Setting environment variables in the console
--------------------------------------------
Generate a secret key for yourself, eg like this: Setting environment variables
-----------------------------
Generate a secret key for yourself, e.g. like this:
.. code-block:: bash .. code-block:: bash
python -c 'import secrets;import string; print("".join(secrets.choice(string.digits + string.ascii_letters + string.punctuation) for _ in range(50)))' uv run python -c 'import secrets;import string; print("".join(secrets.choice(string.digits + string.ascii_letters + string.punctuation) for _ in range(50)))'
Make a note of it, since we'll need it here in the console and later on in the web app config tab. Make a note of it, since we'll need it here in the console and later on in the web app config tab.
Set environment variables via the virtualenv "postactivate" script (this will set them every time you use the virtualenv in a console): Set environment variables via the ``.env`` file:
.. code-block:: bash .. code-block:: bash
vi $VIRTUAL_ENV/bin/postactivate vi .env
.. note:: If you don't like vi, you can also edit this file via the PythonAnywhere "Files" menu; look in the ".virtualenvs" folder. .. note:: If you don't like vi, you can also edit this file via the PythonAnywhere "Files" menu.
Add these exports Add these env variables:
.. code-block:: bash .. code-block:: bash
export WEB_CONCURRENCY=4 WEB_CONCURRENCY=4
export DJANGO_SETTINGS_MODULE='config.settings.production' DJANGO_SETTINGS_MODULE='config.settings.production'
export DJANGO_SECRET_KEY='<secret key goes here>' DJANGO_SECRET_KEY='<secret key goes here>'
export DJANGO_ALLOWED_HOSTS='<www.your-domain.com>' DJANGO_ALLOWED_HOSTS='<www.your-domain.com>'
export DJANGO_ADMIN_URL='<not admin/>' DJANGO_ADMIN_URL='<not admin/>'
export MAILGUN_API_KEY='<mailgun key>' MAILGUN_API_KEY='<mailgun key>'
export MAILGUN_DOMAIN='<mailgun sender domain (e.g. mg.yourdomain.com)>' MAILGUN_DOMAIN='<mailgun sender domain (e.g. mg.yourdomain.com)>'
export DJANGO_AWS_ACCESS_KEY_ID= DJANGO_AWS_ACCESS_KEY_ID=
export DJANGO_AWS_SECRET_ACCESS_KEY= DJANGO_AWS_SECRET_ACCESS_KEY=
export DJANGO_AWS_STORAGE_BUCKET_NAME= DJANGO_AWS_STORAGE_BUCKET_NAME=
export DATABASE_URL='<see Database setup section below>' DATABASE_URL='<see Database setup section below>'
export REDIS_URL='<see Redis section below>' REDIS_URL='<see Redis section below>'
.. note:: The AWS details are not required if you're using whitenoise or the built-in PythonAnywhere static files service, but you do need to set them to blank, as above. .. note:: The AWS details are not required if you're using whitenoise or the built-in PythonAnywhere static files service, but you do need to set them to blank, as above.
@ -79,38 +78,25 @@ Add these exports
Database setup Database setup
-------------- --------------
Go to the PythonAnywhere **Databases tab** and configure your database. Go to the PythonAnywhere **Databases tab** and configure your database. Using Postgres, setup your superuser password, then open a Postgres console and run a ``CREATE DATABASE my-db-name``. You should probably also set up a specific role and permissions for your app, rather than using the superuser credentials. Make a note of the address and port of your postgres server.
* For Postgres, setup your superuser password, then open a Postgres console and run a ``CREATE DATABASE my-db-name``. You should probably also set up a specific role and permissions for your app, rather than using the superuser credentials. Make a note of the address and port of your postgres server. Now go back to the ``.env`` file and set the ``DATABASE_URL`` environment variable:
* For MySQL, set the password and create a database. More info here: https://help.pythonanywhere.com/pages/UsingMySQL
* You can also use sqlite if you like! Not recommended for anything beyond toy projects though.
Now go back to the *postactivate* script and set the ``DATABASE_URL`` environment variable:
.. code-block:: bash .. code-block:: bash
export DATABASE_URL='postgres://<postgres-username>:<postgres-password>@<postgres-address>:<postgres-port>/<database-name>' DATABASE_URL='postgres://<postgres-username>:<postgres-password>@<postgres-address>:<postgres-port>/<database-name>'
# or
export DATABASE_URL='mysql://<pythonanywhere-username>:<mysql-password>@<mysql-address>/<database-name>'
# or
export DATABASE_URL='sqlite:////home/yourusername/path/to/db.sqlite'
If you're using MySQL, you may need to run ``pip install mysqlclient``, and maybe add ``mysqlclient`` to *requirements/production.txt* too.
Now run the migration, and collectstatic: Now run the migration, and collectstatic:
.. code-block:: bash .. code-block:: bash
source $VIRTUAL_ENV/bin/postactivate export UV_ENV_FILE=.env
python manage.py migrate export UV_NO_DEV=1
python manage.py collectstatic uv run python manage.py migrate
# if using django-compressor: uv run python manage.py compress # optional, if using django-compressor
python manage.py compress uv run python manage.py collectstatic
# and, optionally # and, optionally
python manage.py createsuperuser uv run python manage.py createsuperuser
Redis Redis
@ -124,45 +110,33 @@ We recommend to signup to a separate service offering hosted Redis (e.g. `Redisl
Configure the PythonAnywhere Web Tab Configure the PythonAnywhere Web Tab
------------------------------------ ------------------------------------
Go to the PythonAnywhere **Web tab**, hit **Add new web app**, and choose **Manual Config**, and then the version of Python you used for your virtualenv. Go to the PythonAnywhere **Web tab**, hit **Add new web app**, and choose **Manual Config**, and then the Pthon 3.12.
.. note:: If you're using a custom domain (not on \*.pythonanywhere.com), then you'll need to set up a CNAME with your domain registrar. .. note:: If you're using a custom domain (not on \*.pythonanywhere.com), then you'll need to set up a CNAME with your domain registrar.
When you're redirected back to the web app config screen, set the **path to your virtualenv**. If you used virtualenvwrapper as above, you can just enter its name. When you're redirected back to the web app config screen, set the **path to your virtualenv**, which should be something like ``/home/<your-username>/<your-project-directory>/.venv``.
Click through to the **WSGI configuration file** link (near the top) and edit the wsgi file. Make it look something like this, repeating the environment variables you used earlier: Click through to the **WSGI configuration file** link (near the top) and edit the wsgi file. Make it look something like this, repeating the environment variables you used earlier:
.. code-block:: python .. code-block:: python
import os import os
import sys import sys
path = '/home/<your-username>/<your-project-directory>' PROJECT_PATH = '/home/<your-username>/<your-project-directory>'
if path not in sys.path: if PROJECT_PATH not in sys.path:
sys.path.append(path) sys.path.append(PROJECT_PATH)
os.environ['DJANGO_SETTINGS_MODULE'] = 'config.settings.production' os.environ['DJANGO_SETTINGS_MODULE='] = 'config.settings.production'
os.environ['DJANGO_SECRET_KEY'] = '<as above>' os.environ['DJANGO_READ_DOT_ENV_FILE'] = '1'
os.environ['DJANGO_ALLOWED_HOSTS'] = '<as above>'
os.environ['DJANGO_ADMIN_URL'] = '<as above>'
os.environ['MAILGUN_API_KEY'] = '<as above>'
os.environ['MAILGUN_DOMAIN'] = '<as above>'
os.environ['DJANGO_AWS_ACCESS_KEY_ID'] = ''
os.environ['DJANGO_AWS_SECRET_ACCESS_KEY'] = ''
os.environ['DJANGO_AWS_STORAGE_BUCKET_NAME'] = ''
os.environ['DATABASE_URL'] = '<as above>'
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
application = get_wsgi_application() application = get_wsgi_application()
Back on the Web tab, hit **Reload**, and your app should be live! Back on the Web tab, hit **Reload**, and your app should be live!
.. note:: You may see security warnings until you set up your SSL certificates. If you want to suppress them temporarily, set ``DJANGO_SECURE_SSL_REDIRECT`` to blank. Follow `these instructions <https://help.pythonanywhere.com/pages/HTTPSSetup>`_ to get SSL set up. .. note:: You may see security warnings until you set up your SSL certificates. If you want to suppress them temporarily, set ``DJANGO_SECURE_SSL_REDIRECT`` to blank. Follow `these instructions <https://help.pythonanywhere.com/pages/HTTPSSetup>`_ to get SSL set up.
Optional: static files Optional: static files
---------------------- ----------------------
@ -176,13 +150,11 @@ For subsequent deployments, the procedure is much simpler. In a Bash console:
.. code-block:: bash .. code-block:: bash
workon my-virtualenv-name
cd project-directory cd project-directory
git pull git pull
python manage.py migrate uv run python manage.py migrate
python manage.py collectstatic uv run python manage.py compress # optional, if using django-compressor
# if using django-compressor: uv run python manage.py collectstatic
python manage.py compress
And then go to the Web tab and hit **Reload** And then go to the Web tab and hit **Reload**