Skip to content

Instantly share code, notes, and snippets.

@JanJakes
Last active July 27, 2023 11:32
Show Gist options
  • Save JanJakes/7124076 to your computer and use it in GitHub Desktop.
Save JanJakes/7124076 to your computer and use it in GitHub Desktop.
Ubuntu server with Nginx, uWSGI and Node.js installation & deployment setup

Ubuntu with Nginx, uWSGI & Node.js and it's deployment

This Gist contains instructions to setup Ubuntu server with Nginx, uWSGI & Node.js with that can serve for any Python apps (Django for instance) and will allow it's automatized deployment.

The content is as follows:

  • 01-ubuntu.md – A basic Ubuntu server setup.
  • 02-nginx-uwsgi-nodejs.md – Nginx, uWSGI and Node.js installation and setup.
  • 03-deployment.md – A server setup for automatized deployment.
  • 04-mariadb.md – Mariadb installation and setup.

Ubuntu server setup

1. Create a new user account

First of all you will probably want to create an account with sudo privileges:

# add a new user (-m to create home directory, -s to use bash instead of sh)
$ useradd -m <user-name> -s /bin/bash

# set the user a password (needed for use with 'sudo')
passwd <user-name>

# add the user to sudoers
adduser <user-name> sudo

Now add your public SSH key to /home/<user-name>/.ssh/authorized_keys to be able to login over SSH to this account.

2. Setup SSH daemon to accept certificates only

First of all try to connect to the server with your certificate. If everything is working open /etc/ssh/sshd_config and add/modify the following lines:

# authentication with certificate must be enabled
RSAAuthentication yes
PubkeyAuthentication yes

# password authentication must be disabled
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

Finally reload the SSH daemon configuration with service sshd reload.

3. Setup firewall to allow web and SSH only

To enable the firewall run the following commands:

$ ufw default deny incoming
$ ufw default deny outgoing
$ ufw allow ssh
$ ufw allow www
$ ufw enable

The firewall status can be checked as follows:

$ ufw status

Nginx, uWSGI and Node.js setup

1. Packages installation:

All the following commands must be run with root privileges:

# reload the packages lists
$ apt-get update

# install python, pip and virtualenv
$ apt-get install python python-dev python-pip
$ pip install virtualenv

# install nginx
$ apt-get install nginx-full

# install uWSGI
$ pip install uwsgi

# install Node.js and NPM
$ apt-get install nodejs npm
$ ln -s /usr/bin/nodejs /usr/bin/node

The ln -s /usr/bin/nodejs /usr/bin/node line is needed because node is renamed to nodejs on Ubuntu distributions but we need node when we will use the local Node modules.

2. Packages setup:

At this stage we don't need any special setup for Nginx or Node.js. For uWSGI we need to create a file /etc/init/uwsgi.conf with the following content:

# Emperor uWSGI script
description "uWSGI Emperor"
start on runlevel [2345]
stop on runlevel [06]
exec uwsgi --uid www-data --gid www-data --master --die-on-term --emperor var/www/*/current/server/uwsgi.ini

Now uWSGI will be automatically started on system boot and we will be able to run commands like initctl [start|reload|restart|stop] uwsgi.

3. Application structure:

Note the /var/www/*/current/server/uwsgi.ini on the last line of the init script in the previous section. It requires some structure for each application running on the server. The sctructure should be as follows:

/var/www/<application-name>/                           # application directory
/var/www/<application-name>/current/                   # application current version's root
/var/www/<application-name>/current/server/            # server configuration
/var/www/<application-name>/current/server/nginx.conf  # Nginx configuration file
/var/www/<application-name>/current/server/uwsgi.conf  # uWSGI configuration file

The current directory will be usually just a link to the current application version created by an automatized deployment script. The top-level /var/www/<application-name>/ directory can store more application versions and the files that need to be shared across the versions (media files, libraries, etc.).

Application deployment setup

1. Packages installation:

The only package we need to run the deployment is git:

$ apt-get install git-core

2. Deployment user

Lets create a new user and give him some privileges:

# create a user named 'deploy'
$ useradd -m deploy -s /bin/bash

# add the deploy user to the 'www-data' group which runs Nginx and uWSGI
$ adduser deploy www-data

# give the deploy user the ownership of the '/var/www' directory
$ chown -R deploy:deploy /var/www

To run the deployment script you need to be able to connect over SSH as the 'deploy' user. To allow this add you public SSH key to /home/deploy/.ssh/authorized_keys.

Now lets create a SSH key-pair for the deploy user so that he can connect to your repository during deployment:

$ su deploy
$ ssh-keygen

Now you can copy the public key to your computer with $ scp deploy@<server-name>:~/.ssh/id_rsa.pub <destination-directory>, add it to your repository (GitHub/Bitbucket/...) and give it only the read privileges for your repository.

Now try to login as the deploy user and clone the repository from which you want to deploy the application:

# connect to the server as the deploy user
$ ssh deploy@<server-name>

# try to clone your repository (in this example from Bitbucket)
$ git clone git@bitbucket.org:<user-name>/<repository-name>.git

# now you will probably be promted about storing the RSA fingerprint - answer 'yes'

# if everything works, you can remove the repository
$ rm -rf <repository-name>

This step is not only to check if the things work but also to add the RSA fingerprint for your repository to the list of known hosts.

3. Server reloading

After every successful deployment we need to reload the server so that it fetches the new application sources and configuration. To reload the server we need root privileges but at the same time we don't want to let the deploy user to use them anytime for security reasons.

The solution is to let the deploy user run only certain commands as root without promting for password. To achieve this we need to modify the /etc/passwd file. Open it with $ sudo visudo and add the following lines:

# add those lines to let deploy user reload Nginx and uWSGI
deploy ALL=NOPASSWD: /usr/sbin/nginx -s reload
deploy ALL=NOPASSWD: /sbin/initctl reload uwsgi

Now the deploy user will be able to run $ sudo nginx -s reload and initctl reload uwsgi without password.

MariaDB installation and setup

To add MariaDB sources run the following:

$ apt-get install software-properties-common
$ apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db
$ add-apt-repository 'deb http://mirror.jmu.edu/pub/mariadb/repo/10.0/ubuntu precise main'

Don't forget to replace precise with your current Ubuntu distribution. This one is for the 12.04 LTS.

Then we can install MariaDB:

$ apt-get update
$ apt-get install mariadb-server

To be able to compile Python's mysql-python package we'll need also:

$ apt-get install libmariadbclient-dev

Now secure the installation:

$ mysql_secure_installation

Change the root password? [Y/n] Y
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y
@darklow
Copy link

darklow commented Jul 27, 2023

Thanks for sharing. Can you please share contents of uwsgi.ini file? To see how exactly you run node & all the static files itself. Thanks

@JanJakes
Copy link
Author

@darklow Sorry, this is almost 10 years old and most likely very much outdated. I don't even remember what I used it for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment