Hosting GeoServer

Photo by Bhavya Pratap Singh on Unsplash

Photo by Bhavya Pratap Singh on Unsplash

Updated 13. December 2025

GeoServer is a great FOSS (Free and Open Source Software) that provides powerful mapping capabilities. You can run it locally on your Windows computer, or on your own VPS (Virtual Private Server) in the cloud.

In this article, I will guide you through setting up GeoServer on a Linux host to serve a WMS (Web Mapping Service), WFS (Web Feature Service), and more.

Overview

Serving GeoServer is quite complex. To appreciate it, it is helpful to have an overview of the components and their relationships. Below is an illustration of the building blocks that make up this installation.

Bilde / Image

GeoServer is a Java web "applet" that is served by the web server Jetty. To make the web app available on a host that already serves other web applications and to simplify TLS management using Certbot, we will use Nginx as a reverse proxy. GeoServer can serve WMS, WFS, and other services based on various data sources. One of the most efficient ways to store and serve spatial data is to use PostGIS, a spatial data extension for PostgreSQL.

All of these building blocks are great FOSS that can be used in production-ready applications at no cost.

GeoServer Installation

GeoServer is a Java applet. To run it, you need a Java Runtime Environment. The GeoServer version used in this article runs on Java 17 or 21. In this guide, we will use Java 21, as it's the latest version.

sudo apt update
sudo apt install openjdk-21-jre

Then download the latest stable release and unzip it into the /usr/share directory.

wget -O geoserver-2.28.1-bin.zip "https://downloads.sourceforge.net/project/geoserver/GeoServer/2.28.1/geoserver-2.28.1-bin.zip"
sudo unzip ./geoserver-2.28.1-bin.zip -d /usr/share/geoserver

That's how easy it is to install GeoServer! 

Once installed, you can run it manually in your terminal or as a daemon in the background. By running it as a daemon on a server, you can proxy it through Nginx to make it available on the internet.

GeoServer Setup

Making GeoServer production-ready

If you want GeoServer to be accessible on the internet, you need to take a few steps to secure/harden the installation. First, create a system user for GeoServer. This user will only be used to run GeoServer, and nothing else.

sudo useradd -r geoserver

This will create a system account that is locked from login and without a home directory.

Next, make the geoserver user the owner of the geoserver files.

sudo chown -R geoserver:geoserver /usr/share/geoserver

Now you must check what ports are already being used by other services on your server.

sudo netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      xxx/systemd-resolve 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      xxx/sshd: /usr/sbin 
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      xxx/nginx: maste 
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      xxx/mysqld          
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      xxx/nginx: maste

From the output above, we can see that the default GeoServer port, 8080, is not in use by any other service on this server. If port 8080 is in use by another service, you can simply use any other available port.

Now you can set up a daemon to start and stop GeoServer. I prefer to use "supervisor" for my daemons. I find the configuration files easier to understand than the systemctl configuration files. 

Make sure that "supervisor" is installed before continuing.

sudo apt update
sudo apt install supervisor

Once installed, the config file can be created.

sudo vim /etc/supervisor/conf.d/geoserver.haxor.no.conf
geoserver.haxor.no.conf
[program:geoserver_haxor]
user=geoserver
directory=/usr/share/geoserver/bin
command=sh startup.sh
autostart=true
autorestart=true
environment=GEOSERVER_HOME=/usr/share/geoserver,JETTY_OPTS='jetty.http.port=8080'

The config file above configures Supervisor to run GeoServer as the geoserver system user, to start it at OS boot automatically, and to restart it if it crashes. If you need to change the port on which GeoServer listens, set the "jetty.http.port" property to a different port number.

By running Geoserver as its own user and having that user own all the GeoServer files, we isolate the process and files, making it harder for a cybercriminal to harm other parts of the system if they exploit a GeoServer vulnerability and try to run commands on the server.

To start the daemon, run this command:

sudo supervisorctl update

If you get no errors, GeoServer has been started and is available at the port you defined in the config file.

Now you can control the daemon using the following commands:

sudo supervisorctl start geoserver_haxor
sudo supervisorctl stop geoserver_haxor
sudo supervisorctl restart geoserver_haxor
sudo supervisorctl status geoserver_haxor

Important! Before you open the firewall or make GeoServer accessible on the internet from your server, you absolutely MUST harden your GeoServer installation. 

The default GeoServer configuration is not production-ready, and unsafe!

To access GeoServer running on a server without exposing it to the internet, you can use an SSH port forwarding tunnel. Set it up in a terminal/command prompt like this:

ssh -N -L localhost:8080:localhost:8080 stanley@haxor.no

Press Ctrl+c to close the tunnel.

This will make it possible to access GeoServer running on the remote host by using a web browser and navigating to http://localhost:8080/geoserver on your own computer.

On the webpage, you can log in with the default credentials

Username: admin
Password: geoserver

Change the admin password by navigating to 

  1. "Users, Groups, and Roles" from the left-side menu
  2. "User/Groups" tab at the top of the page
  3. Click on the admin user
  4. Enter a new password in both fields
  5. Click on the "Save" button at the bottom of the page.

Change the keystore password by navigating to

  1. The frontpage (click on the GeoServer header logo)
  2. Click the "Change it" link on the warning about the keystore default password.
  3. Use geoserver as the current password, and enter a long, safe password in both fields below.
  4. Click on the "Change Password" button.

GeoServer frontpage with keystore warning

Setting new keystore password

Strengthen password-based encryption by navigating to

  1. Security -> Settings in the left-side menu
  2. Change Password encryption to "Strong PBE".
  3. Click the "Save" button
Bilde / Image

Using strong password-based encryption

By doing this, you have performed basic hardening of the GeoServer installation.

Bilde / Image

Nginx Reverse Proxy

To serve GeoServer on the web on a VPS hosting several other projects and services, Nginx can be used as a reverse proxy. The reverse proxy will simply route traffic from port 443 (HTTPS) to GeoServer running on port 8080 behind your firewall.

This process has these steps:

  1. Configure GeoServer.
  2. Configure CRSF.
  3. Set up your DNS.
  4. Configure the Nginx reverse proxy.
  5. Set up TLS on Nginx

 

Configure GeoServer:

Before setting up the Nginx reverse proxy, you must configure GeoServer to function behind it.

  1. Start an SSH port-forwarding tunnel, and use a browser to navigate to your GeoServer installation.
  2. Click on "Global settings" in the menu on the left side of the page.
  3. Fill in"Proxy Base URL" with "https://maps.haxor.no/geoserver".
  4. Enable "Use headers for Proxy URL" by checking the checkbox.
Bilde / Image

Unfortunately, I was unable to run the reverse proxy without the /geoserver path in the base URL due to the Jetty configuration. The only way I was able to make the reverse proxy work was to include /geoserver in the Base URL, and the reverse proxy route.

Configure CRSF to work with the reverse proxy

To allow the GeoServer admin pages to operate properly behind the reverse proxy, you must whitelist the reverse proxy hostname in the CSRF config. 

If you don't do this, you will not be able to perform most actions in GeoServer. If you review the response in Chrome DevTools or equivalent, you will see an HTTP 400 error with the message "Origin does not correspond to request", indicating a CSRF error.

I spent an entire evening researching how to fix this because of incorrect documentation.

Open the GeoServer webapp config file and insert the following block anywhere inside the web-app tag to whitelist your reverse proxy host.

sudo vim /usr/share/geoserver/webapps/geoserver/WEB-INF/web.xml
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        metadata-complete="false"
        version="3.1">
    <display-name>GeoServer</display-name>

    <!-- INSERT THIS !! -->
    <context-param>
        <param-name>GEOSERVER_CSRF_WHITELIST</param-name>
        <param-value>geoserver.haxor.no</param-value>
    </context-param>
    <!-- INSERT THIS !! -->

Apply the changes by restarting the GeoServer Daemon.

sudo supervisorctl restart geoserver_haxor

 

Set up your DNS.

Configure the hostname/subdomain to have an A record or CNAME that points to your VPS running GeoServer.

 

Configure the Nginx reverse proxy.

Now, you can create an Nginx host file for the reverse proxy.

sudo vim /etc/nginx/sites-available/geoserver.haxor.no.conf
geoserver.haxor.no.conf
server {
    server_name geoserver.haxor.no;
    listen 80;

    location / {
        return 301 /geoserver/;
    }

    location /geoserver/ {
        proxy_pass http://127.0.0.1:8080/geoserver/;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port 443;
    }
}

To make the reverse proxy available, you must create a symlink from the sites-enabled directory to the newly created host file.

sudo ln -s /etc/nginx/sites-available/geoserver.haxor.no.conf /etc/nginx/sites-enabled/geoserver.haxor.no.conf

Check for syntax errors in your config by running this command:

sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Finally, to make the reverse proxy operational, you need to restart nginx.

sudo systemctl restart nginx

Test the reverse proxy by navigating to its URL in a web browser. In this example, go to http://geoserver.haxor.no/geoserver

 

Set up TLS on Nginx

If you can successfully reach GeoServer via your reverse proxy, you can complete the setup by configuring TLS with certbot. 

sudo certbot --nginx -d geoserver.haxor.no

When prompted, choose 2, to make Certbot configure your reverse proxy to redirect from HTTP to HTTPS. Test the TLS setup by navigating to https://geoserver.haxor.no/geoserver in a web browser.

To get an overview of the capabilities of the WMS, navigate to https://geoserver.haxor.no/geoserver/wms?request=GetCapabilities 

Bilde / Image

PostGIS Installation

Database used for spatial data

PostGIS is a popular spatial data extension for the PostgreSQL RDBMS (relational database management system). To install it run the following commands:

sudo apt update
sudo apt install postgresql postgis

# OPTIONAL: PostGIS routing capabilities
# Search for available pgrouting version, and install the found version
sudo apt search pgrouting
sudo apt install postgresql-12-pgrouting 

# Install a tool to import OpenStreetMap data into the pgrouting extension
sudo apt install osm2pgrouting

To verify that PostgreSQL is running, run this command:

pg_lsclusters
Ver Cluster Port Status Owner    Data directory              Log file
12  main    5432 online postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log

PostGIS Setup

To enable PostGIS, and make the database available from QGIS and GeoServer, you must do the following.

  • Connect to PostgreSQL,
  • Create a Role (Used to access PostgreSQL / PostGIS)
  • Create a database.
  • Connect to the database.
  • Enable the extension(s).
  • Create a new schema for uploading and reading spatial data.

Connect to PostgreSQL by running this command:

sudo -u postgres psql

Run these commands, one line at a time, by replacing the strings in <brackets>

Add PostGIS database
CREATE ROLE <user_name> WITH LOGIN PASSWORD '<secret_password>';
CREATE DATABASE <database_name> WITH OWNER = <user_name>;

-- Connect to the new DB
\connect <database_name>;

-- Enable PostGIS extension on the DB
CREATE EXTENSION postgis;

-- Verify installation
SELECT postgis_full_version();
-- Press 'q' on your keyboard to exit.

-- Create a schema that will be used to store all the spatial data.
CREATE SCHEMA <schema_name> AUTHORIZATION <user_name>;

-- Exit from PostgreSQL
exit;

Optional: To enable all the most popular PostGIS features, enable these extensions as well.

Adding optional PostGIS extensions
-- Connect to the new DB
\connect <database_name>;

-- Advanded 3D support
CREATE EXTENSION postgis_sfcgal;

-- Raster support
CREATE EXTENSION postgis_raster; 

-- Maintain connected lines when editing vector data
CREATE EXTENSION postgis_topology; 

-- Routing capabilities
CREATE EXTENSION pgrouting;

-- Verify installation
SELECT postgis_full_version();
-- Press 'q' on your keyboard to exit.

-- Exit from PostgreSQL
exit;

Now the PostGIS setup is complete, and you can start adding data to PostGIS using QGIS.

PostGIS as a store

Connecting GeoServer to your PostGIS database is really simple.

  1. Navigate to "Data" --> "Stores" on the left-side menu
  2. Click on "Add new Store".
  3. Click on "PostGIS".
  4. Fill out the form.

The Stores page

Adding a new data source

Fill out connection details

Once connected, you can use QGIS or other tools to upload spatial data to your PostGIS database and schema, and add that data as a layer in GeoServer. Uploaded layers will be automatically listed in the store.

Congratulations! You now have a fully functional GeoServer installation running 🎉