Last active
November 14, 2025 01:12
-
-
Save marobo/e2f7789e3e83a4bcb23c10590bc393ef to your computer and use it in GitHub Desktop.
deploy_pythonanywhere.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Steps: | |
| # 1. Go to https://www.pythonanywhere.com/registration/register/beginner/ and sign up for a free account | |
| # 2. Go to your email and verify your email address | |
| # 3. Login to your PythonAnywhere account | |
| # 4. Go to the "Files" tab and upload this file (deploy_pythonanywhere.sh) | |
| # 5. Go to the "Consoles" tab and create a new console by clicking on the "Bash" button | |
| # 6. Open the "deploy_pythonanywhere.sh" file and edit the variables with your own values | |
| # 7. Make the "deploy_pythonanywhere.sh" file executable by running "chmod +x deploy_pythonanywhere.sh" | |
| # 8. Execute the "deploy_pythonanywhere.sh" file by running "source ~/deploy_pythonanywhere.sh" in the console | |
| # === CONFIGURATION === | |
| GIT_REPO="[git repository URL]" # [email protected]:username/repository.git | |
| GIT_BRANCH="[git branch name]" # master, main, etc. | |
| GIT_USERNAME="[git username]" # username | |
| PROJECT_FOLDER="[project folder name]" # Folder name after cloning | |
| PROJECT_NAME="[project name]" # Django project folder containing settings.py | |
| PYTHON_VERSION="[python version]" # 3.10, 3.11, etc. | |
| PA_USERNAME="[pythonanywhere username]" # PythonAnywhere username | |
| PA_EMAIL="[pythonanywhere email]" # PythonAnywhere email | |
| DOMAIN="[PA_USERNAME.pythonanywhere.com]" # username.pythonanywhere.com | |
| # === DEPLOY SCRIPT === | |
| echo "================================================" | |
| echo "π Starting deployment..." | |
| echo "================================================" | |
| echo "This script will:" | |
| echo " - Navigating to home directory" | |
| echo " - Generate SSH key if not present" | |
| echo " - Cloning the Git repo" | |
| echo " - Checking out to the branch specify in the script" | |
| echo " - Pulling latest changes from Git" | |
| echo " - Creating virtual environment and then activating it" | |
| echo " - Installing requirements" | |
| echo " - Running migrations" | |
| echo " - Collecting static files" | |
| echo " - Creating superuser account" | |
| echo " - Configure WSGI file" | |
| echo " - Reload web app" | |
| echo "================================================" | |
| echo "π Navigating to home directory..." | |
| cd ~ || exit | |
| # === Generate SSH key if not present === | |
| if [ ! -f ~/.ssh/id_rsa.pub ]; then | |
| ssh-keygen -t rsa -b 4096 -C "$PA_USERNAME@$DOMAIN" -N "" -f ~/.ssh/id_rsa | |
| echo "π Public key generated:" | |
| echo "================================================" | |
| cat ~/.ssh/id_rsa.pub | |
| echo "================================================" | |
| echo "π Copy and add public key above to your GitHub account at https://github.com/${GIT_USERNAME}/${PROJECT_FOLDER}/settings/keys/new" | |
| read -p "After adding the public key to GitHub, press ENTER to continue..." | |
| else | |
| echo "π SSH has been generated." | |
| echo "================================================" | |
| cat ~/.ssh/id_rsa.pub | |
| echo "================================================" | |
| echo "π Copy and add public key above to your GitHub account at https://github.com/${GIT_USERNAME}/${PROJECT_FOLDER}/settings/keys/new" | |
| echo "π If it has been added to your GitHub repository, you can skip the next step." | |
| read -p "Press ENTER to continue..." | |
| fi | |
| # === Git operations with proper branch handling === | |
| if [ ! -d "$PROJECT_FOLDER" ]; then | |
| echo "π Cloning the Git repo..." | |
| git clone "$GIT_REPO" | |
| cd "$PROJECT_FOLDER" || exit | |
| echo "π₯ Checking out branch $GIT_BRANCH..." | |
| git checkout $GIT_BRANCH | |
| else | |
| cd "$PROJECT_FOLDER" || exit | |
| # Fetch all remote branches first | |
| echo "π₯ Fetching latest changes from remote..." | |
| git fetch origin | |
| # Check if branch exists locally | |
| if git show-ref --verify --quiet refs/heads/$GIT_BRANCH; then | |
| echo "π₯ Checking out existing local branch $GIT_BRANCH..." | |
| git checkout $GIT_BRANCH | |
| # Reset to match remote exactly (prevents merge commits) | |
| # This ensures the local branch matches the remote branch exactly | |
| echo "π Resetting branch to match remote $GIT_BRANCH..." | |
| git reset --hard origin/$GIT_BRANCH | |
| else | |
| # Branch doesn't exist locally, check if it exists on remote | |
| if git show-ref --verify --quiet refs/remotes/origin/$GIT_BRANCH; then | |
| echo "π₯ Creating local branch $GIT_BRANCH from origin/$GIT_BRANCH..." | |
| git checkout -b $GIT_BRANCH origin/$GIT_BRANCH | |
| else | |
| echo "β Error: Branch '$GIT_BRANCH' does not exist on remote!" | |
| echo "Available branches:" | |
| git branch -r | |
| exit 1 | |
| fi | |
| fi | |
| fi | |
| # === Create and activate virtual environment outside of project folder === | |
| echo "π Navigating out of the project folder..." | |
| cd .. | |
| if [ ! -d "venv" ]; then | |
| echo "π Creating virtual environment..." | |
| python$PYTHON_VERSION -m venv venv | |
| fi | |
| echo "β Activating virtual environment..." | |
| source ~/venv/bin/activate | |
| # === Install requirements and run migrations === | |
| cd "$PROJECT_FOLDER" || exit | |
| if [ -f "requirements.txt" ]; then | |
| echo "π¦ Installing requirements..." | |
| pip install --upgrade pip | |
| pip install -r requirements.txt | |
| fi | |
| echo "π§± Running migrations..." | |
| python manage.py migrate | |
| echo "πΌοΈ Collecting static files..." | |
| python manage.py collectstatic --noinput | |
| echo "Compiling translations..." | |
| python manage.py compilemessages | |
| echo "π Running checks..." | |
| python manage.py check | |
| echo "π Running tests..." | |
| python manage.py test | |
| # === Create superuser === | |
| echo "π€ Creating superuser account..." | |
| echo "You'll be prompted to create a superuser account. You can skip this by pressing Ctrl+C." | |
| if python manage.py shell -c "from django.contrib.auth import get_user_model; | |
| User = get_user_model(); | |
| exit(0 if User.objects.filter(username='$PA_USERNAME').exists() else 1)"; then | |
| echo "β οΈ Superuser '$PA_USERNAME' already exists, skipping..." | |
| else | |
| python manage.py createsuperuser --noinput --username="$PA_USERNAME" --email="$PA_EMAIL" | |
| if [ $? -eq 0 ]; then | |
| echo "β Superuser '$PA_USERNAME' created!" | |
| else | |
| echo "β Failed to create superuser" | |
| fi | |
| fi | |
| # === Configure WSGI file === | |
| WSGI_FILE="/var/www/${PA_USERNAME}_pythonanywhere_com_wsgi.py" | |
| echo "βοΈ Updating WSGI file at $WSGI_FILE..." | |
| cat > "$WSGI_FILE" <<EOL | |
| import sys | |
| import os | |
| path = '/home/$PA_USERNAME/$PROJECT_FOLDER' | |
| if path not in sys.path: | |
| sys.path.append(path) | |
| os.environ['DJANGO_SETTINGS_MODULE'] = '$PROJECT_NAME.settings' | |
| from django.core.wsgi import get_wsgi_application | |
| application = get_wsgi_application() | |
| EOL | |
| # === Reload web app === | |
| echo "π Reloading web app..." | |
| touch /var/www/${PA_USERNAME}_pythonanywhere_com_wsgi.py | |
| echo "β Deployment complete!" | |
| echo "================================================" | |
| echo "π NEXT STEPS:" | |
| echo "1. Go to https://www.pythonanywhere.com/user/$PA_USERNAME/webapps/#tab_id_new_webapp_tab" | |
| echo "2. Tap on the 'Add a new web app' button and select 'Manual configuration'" | |
| echo "3. Select Python $PYTHON_VERSION" | |
| echo "4. Set the source code directory to: /home/$PA_USERNAME/$PROJECT_FOLDER" | |
| echo "5. Set the working directory to: /home/$PA_USERNAME/$PROJECT_FOLDER" | |
| echo "6. Set the virtual environment to: /home/$PA_USERNAME/venv" | |
| echo "7. Set the static files mapping to: URL: /static/ Directory: /home/$PA_USERNAME/$PROJECT_FOLDER/staticfiles" | |
| echo "8. Set the media files mapping to: URL: /media/ Directory: /home/$PA_USERNAME/$PROJECT_FOLDER/media" | |
| echo "9. Reload your web app by clicking the green 'Reload' button" | |
| echo "================================================" | |
| echo "π Your Django app should now be live at: https://$DOMAIN" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated