deegree on Ubuntu 24.04 on Azure User Guide
Overview
deegree is an open source framework of OGC compliant geospatial web services. It publishes spatial data as standards based Web Feature Service (WFS), Web Map Service (WMS), Web Map Tile Service (WMTS) and Catalogue Service (CSW) endpoints, and it ships a browser based services console for administering workspaces, data sources and services. It is an OSGeo project and it is the server tier of a spatial data infrastructure: desktop GIS, web map clients and other OGC applications connect to it to fetch maps and features.
This image runs deegree 3.6.11 from the official upstream release on Apache Tomcat 10.1 under OpenJDK 17, both taken from Ubuntu's own package archive so they keep receiving security updates on your VM. deegree's own documentation lets administrators bring a separate Java runtime; this image deliberately uses the distribution's own OpenJDK instead, because a hand unpacked runtime is never patched again. Tomcat is bound to the loopback connector and fronted by nginx on port 80.
The services work the moment the VM boots, with no external service involved. A stock deegree ships an empty workspace and answers nothing until an administrator loads one, and its example workspaces are fetched over the network on request. This image instead bundles deegree's own demo workspace for the US state of Utah and activates it, so a fresh VM answers real WFS, WMS and WMTS requests over local data straight away: municipalities, counties, roads, rivers, lakes and contour lines held as shapefiles, plus digital elevation and orthophoto rasters, all on the VM. The one remote layer the demo normally carries has been removed, so nothing in the boot path calls out to a third party.
A unique administrative password is generated on the first boot of every VM. deegree's OGC data endpoints are public, which is the point of a data service; what this image fences off is the administrative surface. The services console, the configuration REST API and the resource endpoints all sit behind a per VM password, and deegree's own console password is set to that same secret, so there is no open or default admin surface on any VM.
What is included:
- deegree 3.6.11 on Apache Tomcat 10.1 under OpenJDK 17, both from Ubuntu's archive so security updates keep flowing
- A working OGC workspace on first boot serving WFS 1.0.0/1.1.0/2.0.0, WMS 1.1.1/1.3.0 and WMTS over local Utah data
- Municipalities, counties, roads, rivers, lakes and contours as feature layers, plus DEM and orthophoto raster coverages
- Tomcat bound to loopback only and fronted by nginx on port 80, with unauthenticated
/healthzand/readyzprobes - The services console, the
/configREST API and/resourcesfenced behind a per VM administrative password - deegree's own console password set to that per VM secret, so the console is never at an empty or default state
- No remote or third party service in the boot or request path — the one cascaded demo layer is removed
- The workspace, its configuration and its data on a dedicated 32 GiB Azure data disk at
/var/lib/deegree - A JVM heap sized from the VM's own memory on every first boot, so one image is correct on any VM size
tomcat10.serviceandnginx.serviceas systemd units, enabled and active- 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2ms (2 vCPU / 8 GiB RAM) is the recommended size. deegree is a single JVM that renders maps from shapefiles and rasters and answers concurrent feature queries, and this image sets its heap to half of physical memory; 8 GiB gives the server real working room. The image runs correctly on Standard_B2s (4 GiB) — that is what it is smoke tested on — but a server holding a real workspace and serving concurrent map and feature requests deserves the extra headroom. NSG inbound: allow 22/tcp from your management network and 80/tcp (and 443/tcp if you add TLS). deegree is served over plain HTTP by default, so for production put your own domain and a trusted certificate in front of it (see Maintenance).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for deegree by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Review the dedicated data disk on the Disks tab, then Review + create then Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name deegree \
--image <marketplace-image-urn> \
--size Standard_B2ms \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
After the VM is created, open port 80 so you can reach the web interface:
az vm open-port --resource-group <your-rg> --name deegree --port 80 --priority 900
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
The first boot resolves the VM's public address, generates the per VM administrative password, writes it into the three places that gate the admin surface, and starts the server. It normally completes within a minute of the VM becoming reachable.
Step 4 - Confirm the services are running
deegree runs inside Tomcat behind nginx. Confirm both units are active, and confirm the first boot service completed:
systemctl is-active tomcat10.service nginx.service
systemctl is-active deegree-firstboot.service
test -f /var/lib/cloudimg/deegree-firstboot.done && echo "first boot completed"

Tomcat is bound to the loopback connector only, so deegree is reachable exclusively through the nginx front end. Confirm that from the kernel's socket table rather than from a configuration file:
if ss -ltnH | awk '{print $4}' | grep -qE '^(0\.0\.0\.0|\[::\]|\*):8080$'; then
echo "UNEXPECTED: Tomcat is bound to a wildcard address"; exit 1
fi
echo "Tomcat is not exposed directly - nginx on port 80 is the only front door"
Step 5 - Confirm deegree is answering
nginx serves an unauthenticated liveness probe, and a readiness probe that is proxied straight through to deegree's WFS GetCapabilities so it only succeeds once the workspace is actually being served:
code=$(curl -s -o /dev/null -w '%{http_code}' http://localhost/healthz)
echo "GET /healthz -> HTTP $code"
[ "$code" = "200" ] || { echo "FAILED: the appliance is not answering"; exit 1; }
code=$(curl -s -o /dev/null -w '%{http_code}' -m 60 http://localhost/readyz)
echo "GET /readyz -> HTTP $code"
[ "$code" = "200" ] || { echo "FAILED: deegree is not serving yet"; exit 1; }
Step 6 - Retrieve your administrative password
deegree's OGC data endpoints are public — that is what a data service is for. The services console and the configuration API are fenced off instead, using a password generated for this VM and written to a root only file at /root/deegree-credentials.txt (mode 0600):
sudo cat /root/deegree-credentials.txt

Confirm the administrative surface really is closed without that password, and really does open with it. This reads the per VM password straight from the credentials file so it works on any VM:
PW=$(sudo grep '^DEEGREE_ADMIN_PASSWORD=' /root/deegree-credentials.txt | cut -d= -f2-)
code=$(curl -s -o /dev/null -w '%{http_code}' -m 30 http://localhost/deegree-webservices/)
echo "console, anonymous -> HTTP $code"
[ "$code" = "401" ] || { echo "UNEXPECTED: the console was not protected"; exit 1; }
code=$(curl -s -o /dev/null -w '%{http_code}' -m 30 -u "deegreeadmin:$PW" http://localhost/deegree-webservices/)
echo "console, per-VM password -> HTTP $code"
[ "$code" = "200" ] || { echo "FAILED: the per VM password did not authenticate"; exit 1; }
When you open the console in a browser (Step 11), sign in with the user name deegreeadmin and the value of DEEGREE_ADMIN_PASSWORD from that file.
Step 7 - List the feature types over WFS
deegree's Web Feature Service publishes the workspace's vector data as OGC feature types. Ask it what it serves — a GetCapabilities request needs no authentication because the OGC endpoints are public:
curl -s 'http://localhost/deegree-webservices/services/wfs?service=WFS&version=2.0.0&request=GetCapabilities' \
| grep -oE 'app:[A-Za-z0-9_]+' | sort -u

Step 8 - Request real features over WFS
Ask the WFS for a couple of real features and confirm a feature collection with real content comes back — deegree returns an OGC exception report with HTTP 200 on a bad request, so check the payload rather than the status code:
curl -s -m 60 'http://localhost/deegree-webservices/services/wfs?service=WFS&version=2.0.0&request=GetFeature&typeNames=app:Airports&count=2' \
| python3 -c "
import sys
body = sys.stdin.read()
assert 'ExceptionReport' not in body and 'ServiceException' not in body, 'the WFS returned an exception'
n = body.count('<wfs:member') + body.count('<gml:featureMember') + body.lower().count('<member')
assert n >= 1, 'no feature members were returned'
print('%d feature member(s) returned from the local Airports layer' % n)
"

Step 9 - Draw a map over WMS
deegree renders maps server side through its Web Map Service. Ask it for a map of Utah as a PNG and confirm what comes back really is a drawn image — an error is served as an XML document from this same URL, so check the bytes:
curl -s -m 120 -o /tmp/deegree-map.png 'http://localhost/deegree-webservices/services/wms?service=WMS&version=1.3.0&request=GetMap&layers=administration&styles=&crs=EPSG:4326&bbox=36.9,-114.1,42.1,-108.9&width=600&height=600&format=image/png'
python3 -c "
import struct
b = open('/tmp/deegree-map.png','rb').read()
assert b[:8] == b'\x89PNG\r\n\x1a\n', 'the response is not a PNG - the WMS returned an error'
w, h = struct.unpack('>II', b[16:24])
assert w > 200 and h > 150, 'the image is too small to be a real map'
print('rendered a %dx%d PNG map, %d bytes' % (w, h, len(b)))
"
The layers parameter takes any layer name from the WMS GetCapabilities document; crs, bbox, width, height and format control the view and output. deegree also serves WMTS tiles and the workspace ships a tile matrix set for the orthophoto coverage.
Step 10 - Confirm your data lives on the dedicated disk
The whole workspace — its service and data source configuration, its styles and themes, and the shapefile and raster data it serves — sits on the dedicated Azure data disk, so it is decoupled from the OS disk and the disk can be resized or snapshotted independently:
df -h /var/lib/deegree | tail -1
echo "--- the active workspace ---"
ls -1 /var/lib/deegree/workspace_root/utah
Step 11 - Open the services console in your browser
Browse to http://<vm-public-ip>/. Your browser first asks for the administrative credentials (user deegreeadmin, the DEEGREE_ADMIN_PASSWORD from Step 6), then deegree's own console asks for the same password before it will show administrative options:

Step 12 - View a rendered map
The WMS renders maps from the local data. This is a map of Utah drawn by the server from the bundled shapefiles, with every county and its municipalities:

Step 13 - Explore the OGC services
The WFS GetCapabilities document is the machine readable description of everything the Web Feature Service offers — its versions, the feature types, their coordinate reference systems and the output formats — and is what a GIS client reads when you point it at the server:

A GetFeature request returns the features themselves. Here the Airports layer is returned as GML, with each feature's geometry and attributes:

Step 14 - Load your own data
The Utah workspace is there so the server is useful the moment it boots; the point of deegree is serving your data. Sign in to the services console (Step 11) to add feature stores, coverages, layers, styles and services through the browser, or edit the workspace on disk under /var/lib/deegree/workspace_root/utah — datasources/ for the data, services/ for the WFS, WMS and WMTS configuration, layers/, styles/ and themes/ for how it is drawn — and restart:
sudo -u tomcat -e /var/lib/deegree/workspace_root/utah/services/wfs.xml
sudo systemctl restart tomcat10
The full reference for every configuration type is in the deegree documentation. You can also keep several workspaces under /var/lib/deegree/workspace_root and select the active one in the console; the file WEB-INF/workspace_name inside the deployed web application records which workspace is active.
Maintenance
Add TLS. deegree is served over plain HTTP on port 80 by default. For production, point a DNS name at the VM and terminate TLS in nginx, for example with Certbot, so the interface is served over HTTPS on port 443. deegree builds the absolute URL of every OGC operation from the incoming Host header, which nginx passes through unchanged including any non standard port, so a correct proxy configuration needs no further change to advertise the right service URLs in its Capabilities documents.
Change the administrative password. The per VM password gates three things: the nginx Basic auth in front of the console and the /config API, deegree's own console password in /var/lib/deegree/workspace_root/console.pw, and the deegree role user in Tomcat's tomcat-users.xml. To rotate it, set a new console password from the console's own security page, update the htpasswd with sudo htpasswd -B /etc/nginx/deegree-admin.htpasswd deegreeadmin, and update tomcat-users.xml; then sudo systemctl reload nginx and sudo systemctl restart tomcat10.
Keep the public services public and the admin surface fenced. Everything under /deegree-webservices/services/ is the public OGC interface and is reachable without a password by design. Everything else — the console, /config, /resources — is behind the per VM password. If you expose the server to the internet, keep that split, and consider restricting the admin paths to your own network in nginx as well.
The configuration REST API. deegree's /config API can reconfigure the running server, read and write the workspace and fetch remote resources, so it is a powerful surface. It is fenced behind the per VM password here (both the container's deegree role and the nginx Basic auth). Leave it fenced, and only enable remote fetching deliberately.
Back up the data disk. Everything that matters lives on /var/lib/deegree: the whole workspace, its configuration and its data, and the console password. Snapshot the disk to preserve all of it.
Memory. The JVM heap is set to half of the VM's physical memory on every first boot, and is recorded as DEEGREE_HEAP_MB in the credentials file. If you resize the VM, the heap is not recalculated automatically — edit JAVA_OPTS in /etc/default/tomcat10 and restart tomcat10.service.
Updates. The image ships with unattended security upgrades enabled for the operating system, and both Tomcat and the JDK come from Ubuntu's archive so they are covered by it. deegree itself is upgraded by replacing the deployed web application with a newer deegree-webservices.war; your workspace and data on the data disk are untouched by that.
Support
Every cloudimg image is backed by 24/7 support. If you have any questions about deploying or operating deegree on Azure, contact the cloudimg team.