From 0e979f34700add6304120bde467c3587ee4a51b4 Mon Sep 17 00:00:00 2001 From: Harry Date: Mon, 25 Apr 2016 15:47:13 +0100 Subject: [PATCH 1/5] First cut of pythonanywhere deployment instructions. need updating for mailgun. --- docs/deployment-on-pythonanywhere.rst | 174 ++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 docs/deployment-on-pythonanywhere.rst diff --git a/docs/deployment-on-pythonanywhere.rst b/docs/deployment-on-pythonanywhere.rst new file mode 100644 index 00000000..c0201438 --- /dev/null +++ b/docs/deployment-on-pythonanywhere.rst @@ -0,0 +1,174 @@ +Deployment on Heroku +==================== + +.. index:: PythonAnywhere + + +Overview +-------- + +* Push your code up to a code-sharing site like Bitbucket or Github + +* Pull your code down to PythonAnywhere using a *Bash console* and create a virtualenv + +* Set your config environment variables in the *postactivate* script + +* Run the *manage.py* ``migrate`` and ``collectstatic`` commands + +* Add an entry to the PythonAnywhere *Web tab* + +* Future deployments are just `git pull` and then hit the "Reload" button + + +Getting your code and dependencies installed on PythonAnywhere +-------------------------------------------------------------- + +Make sure your project is fully commited 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: + +.. code-block:: bash + + git clone # you can also use hg + cd my-project-name + mkvirtualenv --python=/usr/bin/python3.4 my-project-name # or python2.7, etc + 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: + +.. code-block:: bash + + python -c 'import random; print("".join(random.SystemRandom().choice("abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)") 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. + +Set environment variables via the virtualenv "postactivate" script (this will set them every time you use the virtualenv in a console): + +.. code-block:: bash + + vi $VIRTUAL_ENV/bin/postactivate + +**TIP:** If you don't like vi, you can also edit this file via the PythonAnywhere "Files" menu; look in the *.virtualenvs* folder. + +Add these exports + +.. code-block:: bash + + export DJANGO_SETTINGS_MODULE='config.settings.production' + export DJANGO_SECRET_KEY='' + export SENDGRID_USERNAME='' + export SENDGRID_PASSWORD='' + export DJANGO_AWS_ACCESS_KEY_ID= + export DJANGO_AWS_SECRET_ACCESS_KEY= + export DJANGO_AWS_STORAGE_BUCKET_NAME= + +TODO: replace sendgrid with mailgun + +**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 + + +Database setup: +--------------- + +Go to the PythonAnywhere databases tab and configure your database. + +* 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. + +* 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 + + vi $VIRTUAL_ENV/bin/postactivate + + +.. code-block:: bash + + export DATABASE_URL='postgres://:@:/' + # or + export DATABASE_URL='mysql://:@mysql.server/' + # or + export DATABASE_URL='sqlite:////absolute/path/to/db.sqlite' + +If you're using MySQL, you may need to run ``pip install MySQLdb``, and maybe add ``MySQLdb`` to *requirements/production.txt* too. + +Now run the migration, and collectstatic: + +.. code-block:: bash + + source $VIRTUAL_ENV/bin/postactivate + python manage.py migrate + python manage.py collectstatic + # and, optionally + python manage.py createsuperuser + + + +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. + +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. + +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 + + import os + import sys + path = '/home//' + if path not in sys.path: + sys.path.append(path) + + os.environ['DATABASE_URL'] = '' + os.environ['DJANGO_SETTINGS_MODULE'] = 'config.settings.production' + os.environ['DJANGO_SECRET_KEY'] = '' + os.environ['SENDGRID_PASSWORD'] = '' + os.environ['SENDGRID_USERNAME'] = '' + os.environ['DJANGO_AWS_ACCESS_KEY_ID'] = '' + os.environ['DJANGO_AWS_SECRET_ACCESS_KEY'] = '' + os.environ['DJANGO_AWS_STORAGE_BUCKET_NAME'] = '' + + from django.core.wsgi import get_wsgi_application + application = get_wsgi_application() + +TODO: sendgrid -> mailgun + +Back on the Web tab, hit **Reload**, and your app should be live! + +NB - you will see security warnings until you set up your SSL certificates. If you +want to supress them temporarily, set ``DJANGO_SECURE_SSL_REDIRECT`` to blank. Follow +the instructions here to get SSL set up: https://www.pythonanywhere.com/wiki/SSLOwnDomains + + +Optional: static files +---------------------- + +If you want to use the PythonAnywhere static files service instead of using whitenoise or S3, you'll find its configuration section on the Web tab. Essentially you'll need an entry to match your ``STATIC_URL`` and ``STATIC_ROOT`` settings. There's more info here: https://www.pythonanywhere.com/wiki/DjangoStaticFiles + + +Future deployments +------------------ + +For subsequent deployments, the procedure is much simpler. In a Bash console: + +.. code-block:: bash + + workon my-virtualenv-name + cd project-directory + git pull + python manage.py migrate + python manage.py collectstatic + +And then go to the Web tab and hit **Reload** + + From 55faf7fd2c533f158b37114c307d0c22acae94cc Mon Sep 17 00:00:00 2001 From: Harry Date: Mon, 25 Apr 2016 17:24:41 +0100 Subject: [PATCH 2/5] Update instructions for latest version of cookiecutter --- docs/deployment-on-pythonanywhere.rst | 72 +++++++++++++++------------ 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/docs/deployment-on-pythonanywhere.rst b/docs/deployment-on-pythonanywhere.rst index c0201438..45a75d7e 100644 --- a/docs/deployment-on-pythonanywhere.rst +++ b/docs/deployment-on-pythonanywhere.rst @@ -1,5 +1,5 @@ -Deployment on Heroku -==================== +Deployment on PythonAnywhere +============================ .. index:: PythonAnywhere @@ -7,17 +7,23 @@ Deployment on Heroku Overview -------- -* Push your code up to a code-sharing site like Bitbucket or Github +Full instructions follow, but here's a high-level view. -* Pull your code down to PythonAnywhere using a *Bash console* and create a virtualenv +**First time config**: -* Set your config environment variables in the *postactivate* script +1. Pull your code down to PythonAnywhere using a *Bash console* and setup a virtualenv -* Run the *manage.py* ``migrate`` and ``collectstatic`` commands +2. Set your config variables in the *postactivate* script -* Add an entry to the PythonAnywhere *Web tab* +3. Run the *manage.py* ``migrate`` and ``collectstatic`` commands + +4. Add an entry to the PythonAnywhere *Web tab* + +5. Set your config variables in the PythonAnywhere *WSGI config file* + + +Once you've been through this one-off config, future deployments are just `git pull` and then hit the "Reload" button :) -* Future deployments are just `git pull` and then hit the "Reload" button Getting your code and dependencies installed on PythonAnywhere @@ -29,7 +35,7 @@ Make sure your project is fully commited and pushed up to Bitbucket or Github or git clone # you can also use hg cd my-project-name - mkvirtualenv --python=/usr/bin/python3.4 my-project-name # or python2.7, etc + mkvirtualenv --python=/usr/bin/python3.5 my-project-name # or python2.7, etc pip install -r requirements/production.txt # may take a few minutes @@ -51,7 +57,7 @@ Set environment variables via the virtualenv "postactivate" script (this will se vi $VIRTUAL_ENV/bin/postactivate -**TIP:** If you don't like vi, you can also edit this file via the PythonAnywhere "Files" menu; look in the *.virtualenvs* folder. +**TIP:** *If you don't like vi, you can also edit this file via the PythonAnywhere **Files** menu; look in the ".virtualenvs" folder.* Add these exports @@ -59,21 +65,22 @@ Add these exports export DJANGO_SETTINGS_MODULE='config.settings.production' export DJANGO_SECRET_KEY='' - export SENDGRID_USERNAME='' - export SENDGRID_PASSWORD='' + export DJANGO_ALLOWED_HOSTS='' + export DJANGO_ADMIN_URL='' + export DJANGO_MAILGUN_API_KEY='' + export DJANGO_MAILGUN_SERVER_NAME='' export DJANGO_AWS_ACCESS_KEY_ID= export DJANGO_AWS_SECRET_ACCESS_KEY= export DJANGO_AWS_STORAGE_BUCKET_NAME= + export DATABASE_URL='' -TODO: replace sendgrid with mailgun - -**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.* Database setup: --------------- -Go to the PythonAnywhere databases tab and configure your database. +Go to the PythonAnywhere **Databases tab** and configure your database. * 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. @@ -84,20 +91,15 @@ Go to the PythonAnywhere databases tab and configure your database. Now go back to the *postactivate* script and set the ``DATABASE_URL`` environment variable: -.. code-block:: bash - - vi $VIRTUAL_ENV/bin/postactivate - - .. code-block:: bash export DATABASE_URL='postgres://:@:/' # or - export DATABASE_URL='mysql://:@mysql.server/' + export DATABASE_URL='mysql://:@/' # or - export DATABASE_URL='sqlite:////absolute/path/to/db.sqlite' + export DATABASE_URL='sqlite:////home/yourusername/path/to/db.sqlite' -If you're using MySQL, you may need to run ``pip install MySQLdb``, and maybe add ``MySQLdb`` to *requirements/production.txt* too. +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: @@ -114,9 +116,11 @@ Now run the migration, and collectstatic: 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 version of Python you used for your virtualenv. -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. +**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. 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: @@ -129,25 +133,27 @@ Click through to the **WSGI configuration file** link (near the top) and edit th if path not in sys.path: sys.path.append(path) - os.environ['DATABASE_URL'] = '' os.environ['DJANGO_SETTINGS_MODULE'] = 'config.settings.production' - os.environ['DJANGO_SECRET_KEY'] = '' - os.environ['SENDGRID_PASSWORD'] = '' - os.environ['SENDGRID_USERNAME'] = '' + os.environ['DJANGO_SECRET_KEY'] = '' + os.environ['DJANGO_ALLOWED_HOSTS'] = '' + os.environ['DJANGO_ADMIN_URL'] = '' + os.environ['DJANGO_MAILGUN_API_KEY'] = '' + os.environ['DJANGO_MAILGUN_SERVER_NAME'] = '' 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'] = '' from django.core.wsgi import get_wsgi_application application = get_wsgi_application() -TODO: sendgrid -> mailgun Back on the Web tab, hit **Reload**, and your app should be live! -NB - you will see security warnings until you set up your SSL certificates. If you + +**NOTE:** *you may see security warnings until you set up your SSL certificates. If you want to supress them temporarily, set ``DJANGO_SECURE_SSL_REDIRECT`` to blank. Follow -the instructions here to get SSL set up: https://www.pythonanywhere.com/wiki/SSLOwnDomains +the instructions here to get SSL set up: https://www.pythonanywhere.com/wiki/SSLOwnDomains* Optional: static files From 1224ae9e5bf377c9620400dc3a4b25f181f387e1 Mon Sep 17 00:00:00 2001 From: Harry Date: Mon, 25 Apr 2016 17:33:42 +0100 Subject: [PATCH 3/5] fix a few typos and syntax errors --- docs/deployment-on-pythonanywhere.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/deployment-on-pythonanywhere.rst b/docs/deployment-on-pythonanywhere.rst index 45a75d7e..f60bcb38 100644 --- a/docs/deployment-on-pythonanywhere.rst +++ b/docs/deployment-on-pythonanywhere.rst @@ -22,7 +22,7 @@ Full instructions follow, but here's a high-level view. 5. Set your config variables in the PythonAnywhere *WSGI config file* -Once you've been through this one-off config, future deployments are 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 :) @@ -57,7 +57,7 @@ Set environment variables via the virtualenv "postactivate" script (this will se vi $VIRTUAL_ENV/bin/postactivate -**TIP:** *If you don't like vi, you can also edit this file via the PythonAnywhere **Files** menu; look in the ".virtualenvs" folder.* +**TIP:** *If you don't like vi, you can also edit this file via the PythonAnywhere* **Files** *menu; look in the ".virtualenvs" folder. Add these exports @@ -152,14 +152,14 @@ 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 supress them temporarily, set ``DJANGO_SECURE_SSL_REDIRECT`` to blank. Follow -the instructions here to get SSL set up: https://www.pythonanywhere.com/wiki/SSLOwnDomains* +want to supress them temporarily, set DJANGO_SECURE_SSL_REDIRECT to blank. Follow +the instructions here to get SSL set up: https://help.pythonanywhere.com/pages/SSLOwnDomains/* Optional: static files ---------------------- -If you want to use the PythonAnywhere static files service instead of using whitenoise or S3, you'll find its configuration section on the Web tab. Essentially you'll need an entry to match your ``STATIC_URL`` and ``STATIC_ROOT`` settings. There's more info here: https://www.pythonanywhere.com/wiki/DjangoStaticFiles +If you want to use the PythonAnywhere static files service instead of using whitenoise or S3, you'll find its configuration section on the Web tab. Essentially you'll need an entry to match your ``STATIC_URL`` and ``STATIC_ROOT`` settings. There's more info here: https://help.pythonanywhere.com/pages/DjangoStaticFiles Future deployments @@ -177,4 +177,6 @@ For subsequent deployments, the procedure is much simpler. In a Bash console: And then go to the Web tab and hit **Reload** +**TIP:** *if you're really keen, you can set up git-push based deployments: https://blog.pythonanywhere.com/87/* + From 54503562f84331d4e34396b0e5f367245f3104dc Mon Sep 17 00:00:00 2001 From: Harry Date: Mon, 25 Apr 2016 17:36:38 +0100 Subject: [PATCH 4/5] formatting tweak --- docs/deployment-on-pythonanywhere.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment-on-pythonanywhere.rst b/docs/deployment-on-pythonanywhere.rst index f60bcb38..f02560a7 100644 --- a/docs/deployment-on-pythonanywhere.rst +++ b/docs/deployment-on-pythonanywhere.rst @@ -57,7 +57,7 @@ Set environment variables via the virtualenv "postactivate" script (this will se vi $VIRTUAL_ENV/bin/postactivate -**TIP:** *If you don't like vi, you can also edit this file via the PythonAnywhere* **Files** *menu; look in the ".virtualenvs" folder. +**TIP:** *If you don't like vi, you can also edit this file via the PythonAnywhere* Files *menu; look in the ".virtualenvs" folder. Add these exports From fee825e889d94cfe2256af59af84c0ce3e6c7cae Mon Sep 17 00:00:00 2001 From: Harry Date: Mon, 25 Apr 2016 17:38:45 +0100 Subject: [PATCH 5/5] another formatting tweak --- docs/deployment-on-pythonanywhere.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment-on-pythonanywhere.rst b/docs/deployment-on-pythonanywhere.rst index f02560a7..6aacba15 100644 --- a/docs/deployment-on-pythonanywhere.rst +++ b/docs/deployment-on-pythonanywhere.rst @@ -57,7 +57,7 @@ Set environment variables via the virtualenv "postactivate" script (this will se vi $VIRTUAL_ENV/bin/postactivate -**TIP:** *If you don't like vi, you can also edit this file via the PythonAnywhere* Files *menu; look in the ".virtualenvs" folder. +**TIP:** *If you don't like vi, you can also edit this file via the PythonAnywhere "Files" menu; look in the ".virtualenvs" folder*. Add these exports