I use Dreamhost shared hosting and everytime I wanto to setup a python website/api/whatever, I struggle crawling over a number of pages for installation instructions and troubleshooting, so I decided to compile myself a guide to get it done properly from scratch.
This manual is in development. I will write it as I go through issues.
https://help.dreamhost.com/hc/en-us/articles/216385637-How-do-I-enable-Passenger-on-my-domain-
Set this option to something like applicationname/public
.
- The files on the
public
folder will be served by the webserver as assets (Images, JS, CSS, even PHP files). - If no file is found, the request will be routes to the python application.
- Passenger (Dreamhost's webserver) will look for a file
passenger_wsgi.py
on the parent folderapplicationname
Enable this option.
We will need to download build some stuff from the source code, so we will need directories to organise them the right way:
# Directory for source code (where binaries will be compiled from)
mkdir ~/src
# Directory for binaries
mkdir ~/opt
We will work with a newer version of Python and it requires an updated openssl library.
cd ~/src
wget https://www.openssl.org/source/openssl-1.1.1b.tar.gz
tar zxvf openssl-1.1.1b.tar.gz
cd ~/src/openssl-1.1.1b
./config --prefix=$(readlink -m ~)/opt/openssl --openssldir=$(readlink -m ~)/opt/openssl no-ssl2
make
make test
Remember to check the openssl package integrity before installing it, by comparing the output of these commands:
curl https://www.openssl.org/source/openssl-1.1.1b.tar.gz.sha256
sha256sum openssl-1.1.1b.tar.gz
Ensure you got a result All tests successful from make test
before proceeding with the installation.
# install openssl to ~/opt/openssl
cd ~/src/openssl
make install
# add openssl flags and reference to .bash_openssl
cat <<EOF > ~/.bash_openssl
export PATH=$(readlink -m ~)/opt/openssl/bin:\$PATH
export LD_LIBRARY_PATH=$(readlink -m ~)/opt/openssl/lib
export LC_ALL="en_US.UTF-8"
export LDFLAGS="-L$(readlink -m ~)/opt/openssl/lib -Wl,-rpath,$(readlink -m ~)/opt/openssl/lib"
EOF
# source .bash_openssl into .bash_profile
echo -e "\n# enables the local installation of openssl from ~/opt/openssl\n# (comment the line below to disable)\nsource ~/.bash_openssl\n" >> ~/.bash_profile
# enables the custom openssl in the current shell without require to log out and log back in
. ~/.bash_openssl
Check if openssl was correctly installed:
which openssl # expected: /home/USERNAME/opt/openssl/bin/openssl
openssl version # expected: OpenSSL 1.1.1b 26 Feb 2019
If failed and your shell session started before the installation, run . ~/.bash_openssl
and check again
https://help.dreamhost.com/hc/en-us/articles/115000702772-Installing-a-custom-version-of-Python-3
cd ~/src
wget --no-check-certificate https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz
tar zxvf Python-3.8.1.tgz
cd ~/src/Python-3.8.1
Edit the file ~/src/Python-3.8.1/Modules/Setup
, uncomment and edit the following part (Line 205):
Remember to replace USERNAME accordingly
# Socket module helper for socket(2)
_socket socketmodule.c
# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
SSL=/home/USERNAME/opt/openssl
_ssl _ssl.c \
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-L$(SSL)/lib -lssl -lcrypto
If you intend to use the config flag --enable-optimizations, check what the page https://help.dreamhost.com/hc/en-us/articles/115000702772-Installing-a-custom-version-of-Python-3 says about it (you have to contact support to disable some memory limits during the compilation and etc, so just go for it if you really need. The current ubuntu version can be retrieved with
lsb_release -a
cd ~/src/Python-3.8.1
./configure --prefix=$(readlink -m ~)/opt/python-3.8.1
make
# installs python to ~/opt/python-3.8.1
cd ~/src/Python-3.8.1
make install
# set python as default interpreter at .bash_python
cat <<EOF > ~/.bash_python
export PATH=$(readlink -m ~)/opt/python-3.8.1/bin:\$PATH
EOF
# source .bash_python into .bash_profile
echo -e "\n# enables the local installation of python from ~/opt/python-3.8.1\n# (comment the line below to disable)\nsource ~/.bash_python\n" >> ~/.bash_profile
# enables the custom openssl in the current shell without require to log out and log back in
. ~/.bash_python
Check if Python (and PIP) are correctly installed:
which python3 # expected: /home/USERNAME/opt/python-3.8.1/bin/python3
python3 --version # expected: Python 3.8.1
which pip3 # expected: /home/USERNAME/opt/python-3.8.1/bin/pip3"
If failed and your shell session started before the installation, run . ~/.bash_python
and check again
pip3 install --upgrade pip
https://help.dreamhost.com/hc/en-us/articles/115000695551
pip3 install virtualenv
which virtualenv # expected: /home/USERNAME/opt/python-3.8.1/bin/virtualenv
- Go to the project folder (one level above the public folder set in Dreamhost domain's option Web directory).
- Run
virtualenv --python=$(readlink -m ~)/opt/python-3.8.1/bin/python3.8 venv
venv
at the end is a folder that will be created to store binaries and libraries. You can use another name, as well as add it to.gitignore
to save space in the repository.
Run . venv/bin/activate
(replacing venv
with whatever you used for the virtualenv name.
- Your shell prompt should be prefixed with a (venv).
which python
andwhich pip
should point to binaries inside the venv folderpython --version
should return Python 3.8.1
All command below must be executed from the project application root folder, where the virtualenv folder is located. venv
here can be replaced with whatever you used for your virtualven name.
Action | Command |
---|---|
Activate | . venv/bin/activate |
Deactivate | deactivate |
Remember packages | pip freeze > requirements.txt |
Install packages | pip install -r requirements.txt |
It is handy to have a symlink to the activate command in the application root
# run in the project root directory
ln -s $(readlink -m venv/bin/activate) activate
Create a file passenger_wsgi.py
in the application root (one level about the public Web Directory) with the following:
import sys,os
app_root_dir = os.path.dirname(os.path.realpath(__file__))
INTERP = os.path.join(app_root_dir, 'venv/bin/python')
if sys.executable != INTERP:
os.execl(INTERP, INTERP, *sys.argv)
sys.path.insert(0,app_root_dir)
def application(environ, start_response):
start_response('200 OK', [('Content-type', 'text/plain')])
return ["Hello, world!"]
Also, create a file tmp/restart.txt
from the application root. Everytime you run touch tmp/restart.txt
, the application will restart. This have to be done to see changes.
Add the following to public/.htaccess:
PassengerFriendlyErrorPages on
Not ideal for production environments, use only for dev.
Thanks I am planning to purchase shared hosting in dreamhost. your tutorial gives me the hope