gem version

Deploying a Python app on Digital Ocean production server

Relevant selections for this article:

Ruby Nginx

On this page you will learn how you can deploy your app to a server that is running Passenger. You can either follow these instructions with your own app, or you can use the sample Flask app we prepared.

Loading...

Table of contents

  1. Loading...

1 Transferring the app code to the server

1.1 Push your code to a Git repository

If you are using our sample app, you can skip to the next step.

We want to transfer our application's code to the server. The easiest way to do that is via Git.

If you have already setup a Git repository, push your application's code to that repository by running this on your local computer:

$ git push

If you have not already setup a Git repository, go to Github, create a repository and push your application's code there.

1.2 Login to your server, create a user for the app

Login to your server with SSH:

$ ssh adminuser@yourserver.com

Replace adminuser with the name of an account with administrator privileges or sudo privileges.

Starting from this point, unless stated otherwise, all commands that we instruct you to run should be run on the server, not on your local computer!

Now that you have logged in, you should create an operating system user account for your app. For security reasons, it is a good idea to run each app under its own user account, in order to limit the damage that security vulnerabilities in the app can do. Passenger will automatically run your app under this user account as part of its user account sandboxing feature.

You should give the user account the same name as your app. But for demonstration purposes, this tutorial names the user account myappuser.

$ sudo adduser myappuser

We also ensure that that user has your SSH key installed:

$ sudo mkdir -p ~myappuser/.ssh
$ touch $HOME/.ssh/authorized_keys
$ sudo sh -c "cat $HOME/.ssh/authorized_keys >> ~myappuser/.ssh/authorized_keys"
$ sudo chown -R myappuser: ~myappuser/.ssh
$ sudo chmod 700 ~myappuser/.ssh
$ sudo sh -c "chmod 600 ~myappuser/.ssh/*"

1.3 Install Git on the server

Debian, Ubuntu
sudo apt-get install -y git
Red Hat, CentOS, Rocky, Alma, Fedora, Scientific Linux, Amazon Linux
sudo yum install -y git
Other operating systems Please install Git from git-scm.com.

1.4 Pull code

You need to pick a location in which to permanently store your application's code. A good location is /var/www/APP_NAME. Let us create that directory.

$ sudo mkdir -p /var/www/myapp
$ sudo chown myappuser: /var/www/myapp

Replace myapp and myappuser with your app's name and your app user account's name.

Now let us pull the code from Git:

$ cd /var/www/myapp
$ sudo -u myappuser -H git clone git://github.com/username/myapp.git code

If you are using our sample app, use this Git clone command instead:

$ cd /var/www/myapp
$ sudo -u myappuser -H git clone --branch=end_result https://github.com/phusion/passenger-python-flask-demo.git code

Your app's code now lives on the server at /var/www/myapp/code.

2 Preparing the app's environment

2.1 Install app dependencies

Your application has various dependencies. They must be installed. Most of these dependencies are Python libraries. A common way to install Python libraries is through pip. For example, if your application depends on Flask:

$ sudo pip install flask

Your app may also depend on services, such as PostgreSQL, Redis, etc. Installing services that your app depends on is outside of this tutorial's scope.

3 Configuring Nginx and Passenger

Now that you are done with transferring your app's code to the server and setting up an environment for your app, it is time to configure Nginx so that Passenger knows how to serve your app.

3.1 Edit Nginx configuration file

We need to create an Nginx configuration file and setup a virtual host entry that points to your app. This virtual host entry tells Nginx (and Passenger) where your app is located.

$ sudo nano /etc/nginx/sites-enabled/myapp.conf
$ sudo nano /etc/nginx/conf.d/myapp.conf

Replace myapp with your app's name.

Put this inside the file:

We need to edit your Nginx configuration file and setup a virtual host entry that points to your app. This virtual host entry tells Nginx (and Passenger) where your app is located.

The location of the Nginx configuration file depends on the Nginx installation prefix you chose while installing Passenger. Assuming you installed Nginx to the default prefix /opt/nginx, you need to open /opt/nginx/conf/nginx.conf:

$ sudo nano /opt/nginx/conf/nginx.conf

Let us add a virtual host entry at the end of that file. At the end of the file, insert:

server {
    listen 80;
    server_name yourserver.com;

    # Tell Nginx and Passenger where your app's 'public' directory is
    root /var/www/myapp/code/public;

    # Tell Passenger that your app is a Python app
    passenger_app_type wsgi;
    passenger_startup_file passenger_wsgi.py;

    # Turn on Passenger
    passenger_enabled on;
    passenger_python /path-to-python;
}

Replace yourserver.com with your server's host name, replace passenger_wsgi.py with your app's WSGI entry point file and replace /var/www/myapp/code with your application's code directory path. However, make sure that Nginx is configured to point to the public subdirectory inside it!

Replace /path-to-python with the location of the Python executable for the version with which the app was built. This is likely to be the folder containing the virtual environment.

When you are done, restart Nginx:

$ sudo service nginx restart
$ sudo kill $(cat /opt/nginx/logs/nginx.pid)
$ sudo /opt/nginx/sbin/nginx

(Learn more about restarting Nginx)

3.2 Test drive

You should now be able to access your app through the server's host name! Try running this from your local computer. Replace yourserver.com with your server's hostname, exactly as it appears in the Nginx config file's server_name directive.

$ curl http://yourserver.com/
...your app's front page HTML...

If you do not see your app's front page HTML, then these are the most likely causes:

  1. You did not correctly configure your server_name directive. The server_name must exactly match the host name in the URL. For example, if you use the command curl http://45.55.91.235/ to access your app, then the server_name must be 45.55.91.235.
  2. You did not setup DNS records. Setting up DNS is outside the scope of this tutorial. In the mean time, we recommend that you use your server's IP address as the server name.

Next step: Deploying updates

Continue
light mode dark mode
Passenger 6 Passenger 6