A plugin for deploying Django projects to PythonAnywhere, using django-simple-deploy.
For full documentation, see the documentation for django-simple-deploy.
Current status: In active development. Not yet recommended for actual deployments yet.
This plugin hopes to provide a deployment option for django-simple-deploy that
doesn't require a credit card to get started. PythonAnywhere offers a free tier
that allows users to deploy small Django apps and may be a helpful way to get
small Django apps online without financial commitment.
Deployment to PythonAnywhere with this plugin requires a few prerequisites:
- You must use Git to track your project and push your code to a remote repository (e.g. GitHub, GitLab, Bitbucket).
- You must track dependencies with a
requirements.txtfile. - Create a PythonAnywhere Beginner account, which is a limited account with one web app, but requires no credit card.
- Generate an API token
- Ideally, stay logged in to PythonAnywhere in your default browser to make the deployment smoother.
With those prerequisites met, you can install the plugin and deploy your app:
# TBDPythonAnywhere provides a
pa_autoconfigure_django.py
helper script, currently used in the Django Girls
tutorial. However, it's designed
to run directly on PythonAnywhere, which presents challenges: using a web-based
console, changes not being committed/pushed to version control, etc.
This plugin integrates with django-simple-deploy to provide a more familiar
local workflow, though with some caveats due to free tier limitations (primarily
lack of SSH access).
sequenceDiagram
participant User as Local Machine
participant GitHub
participant PA as PythonAnywhere
User->>GitHub: Commit & push changes
User->>PA: Bash Console API: clone repo
PA->>GitHub: git clone
PA->>PA: Install dependencies & create .env
User->>PA: Webapp API: create webapp
User->>PA: Bash Console API: copy wsgi.py
PA-->>User: 🎉 App deployed!
Note: Users should stay logged into PythonAnywhere in their default browser during deployment, as the console API may need to start a new console session.
To set up a development environment for working on this plugin alongside
django-simple-deploy, follow these steps. This will create a directory
structure that looks like this:
dsd-dev/
├── django-simple-deploy # ← parent project needed to run integration tests
├── dsd-pythonanywhere # ← our plugin development directory
└── dsd-dev-project_[random_string] # ← sample project for testing deployments- Create a parent directory to hold your development work:
mkdir dsd-dev
cd dsd-dev/- Clone
dsd-pythonanywherefor development:
# Clone dsd-pythonanywhere for development (and switch to branch being worked on)
git clone git@github.com:caktus/dsd-pythonanywhere.git- Clone
django-simple-deployand create the blog sample project
git clone git@github.com:django-simple-deploy/django-simple-deploy.git
cd django-simple-deploy/
# Builds a copy of the sample project in parent dir for testing (../dsd-dev-project_[random_string]/)
uv run python tests/e2e_tests/utils/build_dev_env.py- Setup the development environment:
cd ../
cd dsd-dev-project_[random_string]/
source .venv/bin/activate
# Install dsd-pythonanywhere plugin in editable mode
pip install -e "../dsd-pythonanywhere/[dev]"Your development environment is now configured to use your local copy of
django-simple-deploy and the dsd-pythonanywhere plugin in editable mode.
Verify with:
pip show django_simple_deploy dsd_pythonanywhere | grep Editable-
Create a new public repository on GitHub.
-
Push the sample project to your new repository:
git remote add origin git@github.com:[your_github_username]/[your_new_repo_name].git
git branch -M main
git push -u origin main- Configure environment variables for PythonAnywhere API access:
export API_USER=[your_pythonanywhere_username]
export API_TOKEN=[your_pythonanywhere_api_token]If desired, you can add these lines to a .env file in the parent directory to
more easily load them when working on the project:
source ../.env- You can now make changes to
dsd-pythonanywherein the cloned directory and test them by running deployments from the sample project:
python manage.py deploy
# To reset your sample project to a clean state between tests
python ./reset_project.py
# (**CAUTION**) If using --automate-all, you may need to force push to reset the remote changes
git push origin main --force- (Optional) Forward local ports for script debugging on PythonAnywhere:
To debug scripts/setup.sh that's run on PythonAnywhere during deployment, you
can use a service like ngrok to expose your local
dsd_pythonanywhere development code to the remote environment. First, start ngrok to
forward a local port (e.g., 8000):
# In a new terminal
ngrok http 8000 --url https://<your_ngrok_subdomain>.ngrok-free.appThen run a local HTTP server to serve your dsd_pythonanywhere code:
# In another terminal in the dsd-pythonanywhere directory
uv run python -m http.server 8000Finally, set the REMOTE_SETUP_SCRIPT_URL environment variable
in your sample project to point to the ngrok URL for scripts/setup.sh:
export REMOTE_SETUP_SCRIPT_URL="https://<your_ngrok_subdomain>.ngrok-free.app/scripts/setup.sh"To run the unit tests for this plugin, run:
cd dsd-pythonanywhere/
uv run pytestTo run the integration tests (and unit tests), which exercise the mechanics of
python manage.py deploy locally without actually deploying to PythonAnywhere,
run:
cd django-simple-deploy/
# Install dsd-pythonanywhere plugin in editable mode
uv add --editable "../dsd-pythonanywhere[dev]"
uv run pytest
# To skip platform_agnostic_tests for faster feedback during plugin development:
uv run pytest --ignore=tests/integration_tests/platform_agnostic_tests