Apache Jena Fuseki SPARQL Server on AWS User Guide
Overview
This image runs Apache Jena Fuseki, the SPARQL 1.1 server from the Apache Jena project. Fuseki serves a persistent RDF triplestore backed by TDB2 over HTTP, with a built in web query and admin UI, SPARQL 1.1 Query and Update, and the SPARQL Graph Store HTTP Protocol.
Fuseki is installed under /opt/fuseki (FUSEKI_HOME) and its runtime area is /var/lib/fuseki (FUSEKI_BASE), which is a dedicated, independently resizable EBS data volume holding the Shiro security configuration, the dataset definitions, the persistent TDB2 databases and the Fuseki system directory. The server runs as a dedicated unprivileged fuseki system account under a systemd service that starts it on boot and restarts it on failure.
The web UI is served on port 80 by an nginx reverse proxy in front of Fuseki on port 3030. A persistent TDB2 dataset named ds is pre-created, so you can load RDF and run SPARQL immediately after launch. Fuseki also listens directly on port 3030.
This image is secure by default. The upstream Fuseki default leaves every dataset endpoint open and the admin area reachable only from localhost, which is unsafe behind a reverse proxy. Instead, this image ships a hardened Apache Shiro policy: the health endpoints stay open, but the admin UI and API and every dataset write endpoint (SPARQL Update, Graph Store Protocol data and file upload) require HTTP basic authentication as the admin user. The administrator password is generated on the first boot of every deployed instance, so two instances launched from the same AMI never share a password. It is written to /root/apache-jena-fuseki-credentials.txt with mode 0600 so that only the root user can read it.

Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network, port 80 for the web UI, and optionally port 3030 for direct Fuseki access from the networks your applications use
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Step 1: Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Apache Jena Fuseki. Select the cloudimg listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger (Fuseki is a JVM workload; size it for your dataset and query concurrency). Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that opens port 22 from your management network and port 80 for the web UI. Leave the root volume at the default size or larger, and keep the attached data volume that holds the triplestore.
Select Launch instance. First boot initialisation takes approximately one minute after the instance state becomes Running and the status checks pass.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg Apache Jena Fuseki Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22 and 80 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=jena-fuseki}]'
When the instance reaches the Running state and its status checks pass, note its public IP address or DNS name from the EC2 console or with aws ec2 describe-instances.
Step 3: Connect to Your Instance
Connect over SSH using your key pair and the login user for your operating system variant.
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i <key-name>.pem ubuntu@<public-ip>
Step 4: Retrieve the Administrator Password
The Fuseki administrator password is unique to your instance and was generated on first boot. Read it as root:
sudo cat /root/apache-jena-fuseki-credentials.txt
The file lists the web UI URL, the administrator user (admin) and the generated password, and the SPARQL endpoints for the pre-created ds dataset. It is mode 0600 and owned by root, so only the root user can read it.
Step 5: Confirm the Services Are Running
Fuseki and nginx run as systemd services. Confirm both are active:
systemctl is-active fuseki.service nginx.service
Fuseki listens on port 3030 and nginx proxies port 80 to it. Confirm the health endpoint answers (this endpoint is public and is ideal for load-balancer health checks):
curl -fsS 'http://127.0.0.1:3030/$/ping'
Step 6: Open the Web Query and Admin UI
Browse to http://<public-ip>/ to open the Fuseki web UI. The datasets page lists the pre-created ds dataset with buttons to query, add data, edit and view info.
Open the query tab to run SPARQL against your dataset using the built-in editor.

The info tab lists the dataset endpoints and shows live per-endpoint request statistics.

Administrative functions, such as the manage page where you create, back up and remove datasets, require the administrator credentials from Step 4.

Step 7: Run a Public SPARQL Query
SPARQL query and read endpoints are open by default so applications can read without credentials. Count the triples in the ds dataset:
curl -s 'http://127.0.0.1:3030/ds/sparql' --data-urlencode 'query=SELECT (COUNT(*) AS ?count) WHERE { ?s ?p ?o }' -H 'Accept: application/sparql-results+json'
You can point any SPARQL client or your application at http://<public-ip>/ds/query (or the equivalent http://<public-ip>/ds/sparql).
Step 8: Load RDF with an Authenticated Update
SPARQL Update and the other write endpoints require authentication. The following block reads the per-instance administrator password from the credentials file and inserts a triple into the ds dataset, then reads it back with a public query:
PASS=$(sudo grep '^fuseki.admin.pass=' /root/apache-jena-fuseki-credentials.txt | cut -d= -f2-)
curl -s -u "admin:${PASS}" -H 'Content-Type: application/sparql-update' \
--data 'INSERT DATA { <urn:cloudimg:example> <http://www.w3.org/2000/01/rdf-schema#label> "Hello from cloudimg" }' \
'http://127.0.0.1:3030/ds/update'
curl -s 'http://127.0.0.1:3030/ds/query' \
--data-urlencode 'query=SELECT ?label WHERE { <urn:cloudimg:example> <http://www.w3.org/2000/01/rdf-schema#label> ?label }' \
-H 'Accept: application/sparql-results+json'
You can also load an RDF file (Turtle, N-Triples, RDF/XML, JSON-LD and more) through the add data tab in the UI, or with the Graph Store Protocol endpoint http://<public-ip>/ds/data using the same administrator credentials.
Confirm that an anonymous write is correctly rejected (secure by default):
curl -s -o /dev/null -w '%{http_code}\n' -H 'Content-Type: application/sparql-update' \
--data 'INSERT DATA { <urn:x> <urn:p> "y" }' 'http://127.0.0.1:3030/ds/update'
This returns 401, confirming that dataset writes require authentication.
Step 9: The Dedicated Data Volume
The triplestore lives on a dedicated EBS data volume mounted at /var/lib/fuseki, separate from the operating system disk, so you can resize it independently for capacity and IOPS. Confirm the mount and its contents:
findmnt /var/lib/fuseki
ls /var/lib/fuseki
The configuration/ directory holds the ds.ttl dataset definition, databases/ holds the persistent TDB2 store, and shiro.ini holds the security policy.
Step 10: Adjust the Security Policy
The Shiro policy is at /var/lib/fuseki/shiro.ini. By default the SPARQL query and read endpoints are open and the admin plus write endpoints require the admin user. To require authentication for reads as well, change the final /** = anon rule and add a rule for the query endpoints, then restart Fuseki:
sudo systemctl restart fuseki.service
for i in $(seq 1 60); do curl -fsS -o /dev/null 'http://127.0.0.1:3030/$/ping' && break; sleep 1; done
echo "Fuseki restarted and ready"
To change the administrator password, edit the admin line under [users] in shiro.ini (keep the file mode 0640 and owner fuseki) and restart the service. To serve the UI over HTTPS, terminate TLS at the nginx reverse proxy with your own certificate.
Step 11: Back Up a Dataset
Use the admin API to trigger a backup of the ds dataset. Backups are written under /var/lib/fuseki/backups:
PASS=$(sudo grep '^fuseki.admin.pass=' /root/apache-jena-fuseki-credentials.txt | cut -d= -f2-)
curl -s -u "admin:${PASS}" -X POST 'http://127.0.0.1:3030/$/backup/ds'
You can also back up and restore datasets from the manage page in the UI.
Maintenance
- Service management:
sudo systemctl {status,restart,stop,start} fuseki.servicecontrols the server; nginx issudo systemctl restart nginx.service. - Logs:
sudo journalctl -u fuseki.serviceshows the server log. - JVM heap: the service sets
JVM_ARGS=-Xmx2Gin/etc/systemd/system/fuseki.service. Increase it for larger datasets and runsudo systemctl daemon-reloadthen restart. - Data volume: grow the EBS volume in the AWS console, then extend the filesystem on
/var/lib/fuseki.
Support
cloudimg provides 24/7 technical support for this image via email and live chat. Contact support@cloudimg.co.uk for deployment help, dataset and endpoint configuration, TDB2 tuning and backups, Shiro authentication and TLS setup, or any issues including refund requests.
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.