DEV Community

Cover image for Web-GIS Deployment in Ubuntu server (Nginx + Tomcat + PostGIS)
Tek Bahadur Kshetri
Tek Bahadur Kshetri

Posted on • Updated on

Web-GIS Deployment in Ubuntu server (Nginx + Tomcat + PostGIS)

If you are looking for the web-GIS application deployment technique, read this full blog to get the overall idea about it. The table of content of this blog is as below,

1. Basic server setup
2. Installation of essential tools
3. PostGIS database setup
4. Geoserver installation
5. Django project implementation
6. Nginx and gunicorn configuration

1. Basic server setup

Updating and upgrading the ubuntu server

The apt update updates the package lists for upgrades for packages that need upgrading, as well as new packages that have just come to the repositories.

sudo apt update
sudo apt upgrade
Enter fullscreen mode Exit fullscreen mode
Download SSH

The SSH allows us to connect the server remotely. The ssh can be install by using sudo apt install openssh-server and by default, it will start on port 22.

sudo apt install openssh-server
Enter fullscreen mode Exit fullscreen mode

You can check the status of ssh by following command

sudo systemctl status ssh
Enter fullscreen mode Exit fullscreen mode
Setup firewall with UFW

UFW, or Uncomplicated Firewall, is an interface to iptables that is geared towards simplifying the process of configuring a firewall. The detailed documentation about UFW can be found here.

The main syntax for allow farewall is sudo ufw allow from <spacific ip/subnet> to any port <port number>.

Lets setup the required ports through ufw command;

sudo ufw enable
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow 8080
sudo ufw allow 8000
sudo ufw allow from any to any port 80
Enter fullscreen mode Exit fullscreen mode

To check the status of ufw, you can type,

sudo ufw status
Enter fullscreen mode Exit fullscreen mode

2. Installation of essential tools

In this section, we are going to install the some essential tools like gdal, virtualenv, git, vim, etc. Run the following code to install the required packages,

sudo apt update
sudo apt upgrade

# Installation of gdal
sudo apt install -y gdal-bin libgdal-dev libgeos-dev libproj-dev

# Installation of python and virtualenv
sudo apt install -y python3-pip python3-dev python3-virtualenv python3-venv virtualenvwrapper

# Other essential tools
sudo apt install -y software-properties-common build-essential
sudo apt install -y git unzip gcc zlib1g-dev libgeos-dev libproj-dev
sudo apt install -y vim

# Install Openjdk
sudo apt install openjdk-8-jdk-headless default-jdk-headless -y
sudo update-java-alternatives --jre-headless --jre --set java-1.8.0-openjdk-amd64
Enter fullscreen mode Exit fullscreen mode

During this installation, python, gdal, java are the essential components. So make sure these packages are installed successfully,

# Verify GDAL version
gdalinfo --version
  $> GDAL 3.0.4, released 2020/01/28

# Verify Python version
python3.8 --version
  $> Python 3.8.5

which python3.8
  $> /usr/bin/python3.8

# Verify Java version
java -version
  $> openjdk version "1.8.0_265"
  $> OpenJDK Runtime Environment (build 1.8.0_265-8u265-b01-0ubuntu2~20.04-b01)
  $> OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)
Enter fullscreen mode Exit fullscreen mode
Virtualenv Setup

Now let's create the python virtualenv and setup it properly. I am going to use virtualwrapper for this purpose.

# Create the Virtual Environment named as 'venv' (first time only)
source /usr/share/virtualenvwrapper/virtualenvwrapper.sh
mkvirtualenv --python=/usr/bin/python3 venv

# Activate virtual env
source /usr/share/virtualenvwrapper/virtualenvwrapper.sh
workon venv
Enter fullscreen mode Exit fullscreen mode

In order to save it permanently, edit the .bashrc file and following line of code at the bottom of the file,

nano ~/.bashrc

# Write to the bottom of the file the following lines
export WORKON_HOME=~/.virtualenvs
source /usr/share/virtualenvwrapper/virtualenvwrapper.sh
Enter fullscreen mode Exit fullscreen mode

3. PostGIS database setup

In this section, we are going to install the PostgreSQL with PostGIS extension for data storage.

# Ubuntu 20.04 (focal)
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'
sudo wget --no-check-certificate --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt update -y; sudo apt install -y postgresql-13 postgresql-13-postgis-3 postgresql-13-postgis-3-scripts postgresql-13 postgresql-client-13
Enter fullscreen mode Exit fullscreen mode

In the above code, the first and second line of code will add the PostgreSQL to the apt repository. After that, the third line of code will install the PostgreSQL 13 with PostGIS 3 version.

After successful installation of PostgreSQL, you can start the PostgreSQL server by following command,

sudo service postgresql start
Enter fullscreen mode Exit fullscreen mode

For checking the status of PostgreSQL server, you can run following command,

sudo service postgresql status
Enter fullscreen mode Exit fullscreen mode

Now let's create the database named as geoapp and create the PostGIS extension on it by running following command.

sudo -u postgres createdb -O geoapp 
sudo -u postgres psql -d geoapp -c 'CREATE EXTENSION postgis;'
Enter fullscreen mode Exit fullscreen mode

If you have the database backup file, you can restore it into the server database as well. I suppose you have a database backup file named as backup.sql. (This step is not necessary if you don't care about the development data)

psql -U postgres -h localhost -p 5432 -d geoapp -f backup.sql
Enter fullscreen mode Exit fullscreen mode

4. GeoServer installation

In computing, GeoServer is an open-source server written in Java that allows users to share, process and edit geospatial data. In this section, we are going to install the GeoServer in tomcat server.

Tomcat installation

Tomcat is an open-source implementation of the java servlet. Since we already installed the java in previous section, In this section we are going to install the tomcat server on open jdk.
First of all let's create the dedicated user tomcat and add it to the group www-data,

sudo useradd -m -U -d /opt/tomcat -s /bin/bash tomcat
sudo usermod -a -G www-data tomcat
Enter fullscreen mode Exit fullscreen mode

The first line of code creates the user named as tomcat.
-m, --create-home: Create the user's home directory if it does not exist.
-U, --user-group: Create a group with the same name as the user, and add the user to this group.
-d, --home HOME_DIR: The new user will be created using HOME_DIR as the value for the user's login directory (i.e. /opt/tomcat).
-s, --shell: The name of the user's login shell.
-a, --append: Add the user to the supplementary group(s). Use only with the -G option.
-G, --groups: A list of supplementary groups which the user is also a member of. Each group is separated from the next by a comma, with no intervening whitespace.

Now let's download the tomcat server. In this tutorial, I am using 9.0.41 version tomcat. The downloaded tomcat file has to unzip inside /opt/tomcat dir.

VERSION=9.0.41; wget https://www-eu.apache.org/dist/tomcat/tomcat-9/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz
sudo tar -xf apache-tomcat-${VERSION}.tar.gz -C /opt/tomcat/; rm apache-tomcat-${VERSION}.tar.gz
Enter fullscreen mode Exit fullscreen mode

Since the tomcat is updated regularly. So, to have more control over version and updates, we'll create the symbolic link as below:

sudo ln -s /opt/tomcat/apache-tomcat-${VERSION} /opt/tomcat/latest
Enter fullscreen mode Exit fullscreen mode

Now let's change the owner and mode of /opt/tomcat directory.

sudo chown -R tomcat:www-data /opt/tomcat/
sudo sh -c 'chmod +x /opt/tomcat/latest/bin/*.sh'
Enter fullscreen mode Exit fullscreen mode

Create the symbolic link for JRE (java) as well,

sudo ln -s /usr/lib/jvm/java-8-openjdk-amd64/jre/ /usr/lib/jvm/jre
Enter fullscreen mode Exit fullscreen mode

We want to be able to run Tomcat as a service, so we will set up systemd service file. Tomcat need to know where Java is installed.

Now we can create the system service file, which can control over the tomcat services (start, stop, restart, enable).

sudo vim /usr/lib/systemd/system/tomcat9.service
Enter fullscreen mode Exit fullscreen mode

And write the following line of code to the file,

[Unit]
Description=Apache Tomcat Server
After=syslog.target network.target

[Service]
Type=forking
User=tomcat
Group=tomcat

Environment=JAVA_HOME=/usr/lib/jvm/jre
Environment=JAVA_OPTS=-Djava.security.egd=file:///dev/urandom
Environment=CATALINA_PID=/opt/tomcat/latest/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat/latest
Environment=CATALINA_BASE=/opt/tomcat/latest

ExecStart=/opt/tomcat/latest/bin/startup.sh
ExecStop=/opt/tomcat/latest/bin/shutdown.sh

RestartSec=30
Restart=always

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

When you are finished, save and close the file.

Next, reload the systemd daemon so that it knows about our service file:

sudo systemctl daemon-reload
Enter fullscreen mode Exit fullscreen mode

Enable the tomcat server and start it,

sudo systemctl enable tomcat9.service
sudo systemctl start tomcat9.service
Enter fullscreen mode Exit fullscreen mode

To check status of the tomcat service,

sudo systemctl status tomcat9.service
Enter fullscreen mode Exit fullscreen mode
GeoServer Installation

Download the stable version of geoserver.war file and paste it into webapps dir of the tomcat. Here, we are going to download the geoserver.war file from geosolution.it.

cd /tmp
sudo wget --no-check-certificate https://build.geo-solutions.it/geonode/geoserver/latest/geoserver-2.17.2.war
sudo mv geoserver-2.17.2.war /opt/tomcat/latest/webapps/geoserver.war
Enter fullscreen mode Exit fullscreen mode

Now the geoserver will run in the port 8080 of you DNS (http://localhost:8080/geoserver)

This is the general installation guide of geoserver in ubuntu server. If you want to have a separated data dir for geoserver, check this guide.

5. Django project implementation

Here I am going to deploy the simple GeoDjango project from GitHub repo.

sudo mkdir /opt/geoProject

# Change owner and user of this folder
sudo chown -Rf $USER:www-data /opt/geoProject/
sudo chmod -Rf 775 /opt/geoProject/

cd /opt/geoProject
git clone https://github.com/iamtekson/geodjango-app.git /opt/geoProject
Enter fullscreen mode Exit fullscreen mode

Before starting the installation of dependencies, we can activate the virtualenv,

workon venv
Enter fullscreen mode Exit fullscreen mode

Now, we can install the dependencies.

pip install -r requirements.txt
pip install gunicorn
pip install pygdal=="`gdal-config --version`.*"
Enter fullscreen mode Exit fullscreen mode
Update on settings.py file

Since our setting on development and production mode may be different, we need to update the settings.py file,

nano /opt/geoPorject/settings.py
Enter fullscreen mode Exit fullscreen mode

Make changes on the ALLOWED_HOSTS field,

# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . .]
Enter fullscreen mode Exit fullscreen mode

Changes on database connection parameters,

DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.postgis',
        'NAME': 'geoapp',
        'USER': 'postgres',
        'PASSWORD': 'admin',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, we can migrate the database and createsuperuser by typing following code,

python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic
python manage.py createsuperuser
Enter fullscreen mode Exit fullscreen mode

Now you can test the Django server,

python manage.py runserver 0.0.0.0:8000
Enter fullscreen mode Exit fullscreen mode

6. Nginx and gunicorn configuration

Gunicorn Configuration

Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy. Now we can test the gunicorn's ability to serve the project by following command,

cd /opt/geoProject
gunicorn --bind 0.0.0.0:8000 geoProject.wsgi
Enter fullscreen mode Exit fullscreen mode

This will start Gunicorn on the same interface that the Django development server was running on. You can go back and test the app again.

Now we can deactivate the virtualenv by typing:

deactivate
Enter fullscreen mode Exit fullscreen mode
Create a Gunicorn systemd Service File

We have tested the Gunicorn can interact with our Django application, but we should implement a more robust way of starting and stopping the application server. To accomplish this, we’ll make a systemd service file.

Create and open the systemd file for gunicorn,

sudo nano /etc/systemd/system/gunicorn.service
Enter fullscreen mode Exit fullscreen mode

For this demo, my django project name is geoProject and my virtualenv name is venv as we created in first section.
Add the following line of code inside gunicorn.service file.

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=$USER
Group=www-data
WorkingDirectory=/opt/geoProject
ExecStart=/home/$USER/.virtualenvs/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/opt/geoProject/geoProject/geoProject.sock myproject.wsgi:application

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

We can now start the Gunicorn service we created and enable it so that it starts at boot:

sudo systemctl daemon-reload
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
Enter fullscreen mode Exit fullscreen mode
Nginx setup

Nginx is a web server that can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache. The Nginx can be installed using the following command,

sudo apt install -y nginx
Enter fullscreen mode Exit fullscreen mode

Now lets create and open the file myproject inside /etc/nginx/sites-available/geoproject,

sudo nano /etc/nginx/sites-available/geoproject
Enter fullscreen mode Exit fullscreen mode

Make sure, you change the server_domain_or_IP to your actual domain or IP, otherwise, it will only work on localhost.

upstream geoserver_proxy {
  server localhost:8080;
}

server {
    listen 80;
    server_name server_domain_or_IP;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /opt/geoProject;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/opt/geoProject/geoProject/geoProject.sock;
    }
    location /geoserver {
        proxy_pass http://geoserver_proxy;
        include proxy_params;
    }
}
Enter fullscreen mode Exit fullscreen mode

Save and close the file when you are finished.
We started by specifying that this block should listen on the normal port 80 and that it should respond to our server’s domain name or IP address.
Next, we tell Nginx to ignore any problems with finding a favicon. After that, we collected the static assets in /opt/geoPorject/static directory.
Next, we added the geoserver proxy so that we can access the geoserver through this URL: http://localhost/geoserver (without assigning the 8080 port in URL).
Finally, we created a location / {} block to match all other requests. Inside of this location, we’ll include the standard proxy_params file included with the Nginx installation and then we will pass the traffic to the socket that our Gunicorn process created.

Now we can enable the file by linking it to the sites-enabled directory (i.e. create a symbolic link to the site-available directory).

sudo ln -s /etc/nginx/sites-available/geoproject /etc/nginx/sites-enabled
Enter fullscreen mode Exit fullscreen mode

Delete the default Nginx file from site-enabled and site-available directory,

sudo rm -rf /etc/nginx/sites-available/default
sudo rm -rf /etc/nginx/sites-enabled/default
Enter fullscreen mode Exit fullscreen mode

Test the Nginx configuration for syntax error by typing;

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

If no error happens, restart the server by typing;

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

In case of error happen, check the nginx log file,

sudo tail -F -n 300 /var/log/nginx/error.log
Enter fullscreen mode Exit fullscreen mode

Finally, we need to open up our firewall to normal traffic on port 80. Since we no longer need 8000 port, we can remove it;

sudo ufw delete allow 8000
sudo ufw allow 'Nginx Full'
Enter fullscreen mode Exit fullscreen mode

Now you will be able to view your application on your server's domain or IP address. If your domain name is example.com, then your application will run on the following URL:

http://example.com

and the GeoServer will run on the following URL:
http://example.com/geoserver

Thank you for reading my blog. If you want to learn more about the web-Mapping and web-GIS things, please subscribe my youtube channel.

Discussion (1)

Collapse
ferchimi profile image
ferchimi

Hi, thanks for the tutorial
I could't finish the right installation, at this part:
python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic <---- fails
python manage.py createsuperuser

FileNotFoundError: [Errno 2] No such file or directory: '/opt/geoProject/geoProject/static'
I could not find the static content anywhere, please help me find what have gone wrong
Regards
Fernando