
Every sysadmin eventually hits the same wall: logs scattered across a dozen services, no single place to search them, and an incident that takes three hours to diagnose because nobody can correlate an Nginx 502 with a database timeout that happened four seconds earlier. That’s the exact problem Graylog was built to solve, and it’s still one of the most reliable open-source log management platforms available in 2026, even with newer contenders crowding the observability space.
Ubuntu 26.04 LTS, codenamed “Resolute Raccoon,” landed in April 2026 with a refreshed kernel line, GNOME 50 on the desktop side, and a hardened package base that carries through to the server edition. For anyone running production infrastructure, this release is the natural upgrade path once 22.04 and 24.04 start approaching their support horizons. Pairing it with Graylog gives you a centralized logging pipeline that can ingest syslog, GELF, Beats, and raw application logs, then let you search, alert, and visualize all of it from one dashboard.
This isn’t a copy-paste tutorial lifted from outdated documentation. Graylog’s backend requirements have shifted meaningfully over the last two years — MongoDB now needs to sit in the 7.x to 8.0.x range, and OpenSearch has replaced Elasticsearch as the default search backend for most fresh installs. If you’ve installed Graylog before on 20.04 or 22.04 using old Elasticsearch-based guides, several steps here will look different, and for good reason: those methods will either fail outright or leave you with a fragile, unsupported stack.
What follows is a full walkthrough — from provisioning the server through hardening it for production traffic — written the way you’d actually do it on a live box, including the parts that go wrong. Because they will go wrong at least once, and knowing why saves you an afternoon of blind troubleshooting.
What You’re Actually Installing
Graylog isn’t a single binary. It’s three components working together, and understanding the division of labor matters when something breaks:
- MongoDB — stores Graylog’s configuration metadata: dashboards, users, input definitions, alert rules. It does not store your log messages.
- OpenSearch — the search and indexing engine. This is where the actual log data lives, and it’s almost always the component that eats your RAM.
- Graylog Server — the application layer that ties everything together, exposes the REST API, and serves the web interface.
Knowing this split helps enormously during troubleshooting. If searches are slow, look at OpenSearch. If the UI won’t load users or dashboards, MongoDB is usually the culprit. If inputs aren’t receiving data at all, it’s almost always a Graylog Server configuration or firewall issue.
Prerequisites and Sizing Considerations
Don’t undersize this stack. It’s the single most common mistake teams make when standing up Graylog for the first time — they treat it like a lightweight syslog receiver and then wonder why the web UI hangs under load.
Minimum for a Small Production Environment
For environments processing fewer than 5GB of logs per day:
- 4 vCPUs
- 8GB RAM
- 50GB SSD storage, with more capacity if retention requirements are longer
- Ubuntu 26.04 LTS, fully updated
Recommended for Moderate Production Workloads
For environments ingesting approximately 10GB to 50GB of logs per day:
- 8 vCPUs
- 16GB to 32GB RAM
- 200GB or more of SSD storage, ideally NVMe for the OpenSearch data path
- Separate disks for the operating system and OpenSearch data when running bare metal
OpenSearch is JVM-based and will happily consume whatever heap you give it. As a rule of thumb, allocate no more than 50% of total system RAM to OpenSearch’s heap, leaving the rest for the OS page cache, MongoDB, and Graylog Server itself. On a 16GB box, that means roughly 6GB to 7GB for OpenSearch’s JVM heap, not the full 8GB you might be tempted to assign.
Step 1: Prepare Ubuntu 26.04 LTS
Start with a clean, fully patched system. Skipping this step is how you end up chasing dependency conflicts three steps later.
sudo apt update && sudo apt full-upgrade -y
sudo apt install -y curl gnupg2 apt-transport-https ca-certificates lsb-release software-properties-common uuid-runtime pwgen
sudo reboot
Reboot after the upgrade, especially if a new kernel got pulled in. Running an old kernel while installing services that touch networking and file I/O heavily is asking for subtle instability later.
Set the hostname properly — Graylog and OpenSearch both reference the system hostname in cluster configuration, and a generic ubuntu hostname across multiple nodes causes confusing conflicts if you ever scale horizontally.
sudo hostnamectl set-hostname graylog-prod-01
echo "127.0.0.1 graylog-prod-01" | sudo tee -a /etc/hosts
Install Java
Graylog Server and OpenSearch both run on the JVM. Ubuntu 26.04’s default repositories ship OpenJDK 21 as the LTS baseline, which is fully compatible with current Graylog releases.
sudo apt install -y openjdk-21-jre-headless
java -version
You should see output confirming OpenJDK 21.x. If you have multiple JDKs installed from other applications on the same box, use update-alternatives --config java to make sure the correct version is the default. Mismatched JVM versions between services on the same host are a classic source of “it worked yesterday” bug reports.
Step 2: Install and Configure MongoDB
Graylog 7.1.x requires MongoDB in the 7.x–8.0.x range. Ubuntu’s default repositories don’t ship a compatible version, so you’ll pull directly from MongoDB’s official repository.
curl -fsSL https://pgp.mongodb.com/server-8.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
sudo apt update
sudo apt install -y mongodb-org
A quick note that trips people up: MongoDB’s official repositories do not always have a dedicated resolute (26.04) package the moment a new Ubuntu release ships. If apt update throws a 404 on the repository line above, fall back to the noble (24.04) codename in the repository URL. The packages are binary-compatible, and this is the practical workaround used for newer Ubuntu releases before upstream packaging catches up.
Start and enable the service:
sudo systemctl daemon-reload
sudo systemctl enable --now mongod
sudo systemctl status mongod
Confirm that it is listening and responsive:
mongosh --eval "db.runCommand({ connectionStatus: 1 })"
If that returns a JSON blob with "ok" : 1, MongoDB is healthy. Don’t skip this verification. A MongoDB instance that silently fails to bind properly is one of the more annoying failure modes because Graylog Server’s error messages about it are often vague, such as “unable to connect to datastore,” rather than pointing directly at MongoDB.
Step 3: Install and Configure OpenSearch
OpenSearch is the resource-hungriest piece of this stack, and also the one most sensitive to kernel-level tuning.
curl -o- https://artifacts.opensearch.org/publickeys/opensearch.pgp | sudo gpg --dearmor --batch --yes -o /usr/share/keyrings/opensearch-keyring
echo "deb [signed-by=/usr/share/keyrings/opensearch-keyring] https://artifacts.opensearch.org/releases/bundle/opensearch/2.x/apt stable main" | sudo tee /etc/apt/sources.list.d/opensearch-2.x.list
sudo apt update
sudo apt install -y opensearch
The installer prompts for an admin password during setup on newer OpenSearch versions. Set a strong one and store it in your password manager immediately. If you’re scripting the installation, which you should be for anything beyond a one-off lab server, pass it through an environment variable instead:
sudo OPENSEARCH_INITIAL_ADMIN_PASSWORD='YourStrongPasswordHere123!' apt-get install -y opensearch
Tune the Kernel Before Starting OpenSearch
This step gets skipped constantly, and it is the number one cause of OpenSearch refusing to start on a fresh server.
sudo sysctl -w vm.max_map_count=262144
echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf
OpenSearch uses memory-mapped files extensively for its Lucene indices. The default Linux limit of 65530 mmap areas is nowhere near enough once you have multiple shards active. Without this setting, OpenSearch throws a max virtual memory areas vm.max_map_count is too low error on startup and refuses to boot.
Configure the JVM Heap
Edit the JVM options file and set heap size explicitly rather than relying on auto-detection:
sudo nano /etc/opensearch/jvm.options.d/heap.options
Add the following values, adjusting them for your available RAM. This example assumes a server with 16GB of total memory:
-Xms6g
-Xmx6g
Keep Xms and Xmx identical. Letting the JVM resize its heap dynamically causes garbage-collection pauses at unpredictable moments. That is exactly what you do not want during a traffic spike when log volume triples and everyone is staring at dashboards waiting for data to appear.
Configure and Start OpenSearch
For a single-node setup, edit /etc/opensearch/opensearch.yml to disable clustering assumptions:
cluster.name: graylog-cluster
node.name: graylog-node-1
network.host: 0.0.0.0
discovery.type: single-node
plugins.security.disabled: true
Setting plugins.security.disabled: true is acceptable for a single-node internal deployment where OpenSearch is reachable only from localhost or a private network segment. For anything internet-facing or multi-tenant, leave security enabled and configure TLS certificates properly. Do not cut this corner on a server that is reachable from outside your VPC.
sudo systemctl daemon-reload
sudo systemctl enable --now opensearch
sudo systemctl status opensearch
curl -X GET "localhost:9200"
A healthy response returns a JSON payload containing the OpenSearch version and cluster name. If curl times out or refuses the connection, check the service journal before changing anything else:
sudo journalctl -u opensearch -n 100 --no-pager
The logs almost always name the exact configuration line causing the failure.
Step 4: Install Graylog Server
With MongoDB and OpenSearch both healthy, install Graylog itself.
wget https://packages.graylog2.org/repo/packages/graylog-7.1-repository_latest.deb
sudo dpkg -i graylog-7.1-repository_latest.deb
sudo apt update
sudo apt install -y graylog-server
Generate Required Secrets
Graylog Server needs two values before it can start correctly: a password_secret and a SHA-256 hash of your administrator password.
pwgen -N 1 -s 96
Save that output securely. It becomes your password_secret. Then hash the administrator password you intend to use:
echo -n "YourAdminPassword" | sha256sum
Edit server.conf
sudo nano /etc/graylog/server/server.conf
Set the following key values:
is_master = true
password_secret = <paste the 96-character string here>
root_password_sha2 = <paste the sha256 hash here>
root_timezone = Asia/Jakarta
http_bind_address = 0.0.0.0:9000
http_external_uri = http://your-server-ip:9000/
elasticsearch_hosts = http://127.0.0.1:9200
mongodb_uri = mongodb://localhost:27017/graylog
That http_external_uri line matters more than people expect. If it does not match how you actually access the web UI, such as behind an Nginx reverse proxy on port 443 with a domain name, you can get a working login page followed by a broken dashboard because the frontend cannot resolve API calls correctly. Set it to match your real access URL from day one, not merely what is convenient during initial testing.
Start Graylog
sudo systemctl daemon-reload
sudo systemctl enable --now graylog-server
sudo systemctl status graylog-server
Give it 30 to 60 seconds on first boot. It is initializing indices in OpenSearch and setting up internal collections in MongoDB. Tail the logs while you wait:
sudo journalctl -u graylog-server -f
Once you see Graylog server up and running in the log stream, open http://your-server-ip:9000 in a browser and log in with the username admin and the plaintext password you hashed earlier.

Step 5: Firewall and Network Configuration
Ubuntu 26.04 ships with UFW available but not always enabled by default, depending on your provisioning template. Lock this down before exposing the server to any real traffic.
sudo ufw allow OpenSSH
sudo ufw allow 9000/tcp comment 'Graylog Web UI'
sudo ufw allow 1514/tcp comment 'Syslog TCP input'
sudo ufw allow 1514/udp comment 'Syslog UDP input'
sudo ufw allow 12201/udp comment 'GELF UDP input'
sudo ufw enable
Notice what is deliberately absent from that list: port 9200 for OpenSearch and port 27017 for MongoDB. Neither should be exposed beyond localhost or a private VPC network in a real deployment. Both store or index sensitive log data, and both have historically been popular targets for opportunistic scanning bots looking for unauthenticated instances on the public internet.
For anything customer-facing, put Graylog’s web UI behind Nginx with TLS termination rather than exposing port 9000 directly:
server {
listen 443 ssl;
server_name logs.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/logs.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/logs.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Remember to update http_external_uri in Graylog’s configuration to match this HTTPS domain once the reverse proxy is live, then restart graylog-server.
Real-World Use Cases Worth Planning For
A logging platform is only as useful as the inputs you configure and the alerts you build on top of them. A few patterns are worth setting up early:
- Nginx access-log correlation — feed Nginx logs through GELF or Filebeat, then build a dashboard that surfaces 5xx spikes alongside backend response times. This catches degraded upstream services before customers file tickets.
- SSH brute-force detection — send
auth.logthrough a syslog input and configure an alert for repeated failed logins from the same source IP during a short period. This is one of the highest-value quick wins for any new Graylog deployment. - Multi-server WordPress fleets — if you manage a cluster of WordPress sites, centralizing PHP-FPM and Nginx error logs in Graylog turns “which server threw that 500 error at 3am?” from a 20-minute grep session across multiple systems into a 10-second search.
Troubleshooting Common Installation Errors
OpenSearch Will Not Start
Symptom: The logs show max virtual memory areas vm.max_map_count is too low.
Cause: The kernel tuning step was missed, or the value did not persist after a reboot.
Fix: Run the following command and verify that the persistent setting exists in /etc/sysctl.conf:
sudo sysctl -w vm.max_map_count=262144
Graylog Cannot Reach OpenSearch
Symptom: The Graylog web interface loads but displays an “Elasticsearch cluster unreachable” error.
Cause: OpenSearch is not running, elasticsearch_hosts in server.conf points to the wrong location, or another service is already bound to port 9200.
Fix: Check OpenSearch status, validate the configured host, and ensure a leftover Docker container is not running a separate Elasticsearch or OpenSearch service.
sudo systemctl status opensearch
sudo ss -lntp | grep :9200
Graylog Cannot Connect to MongoDB
Symptom: Graylog Server fails to start with MongoException: Unable to connect.
Cause: MongoDB is not running, the listening interface is wrong, or MongoDB authentication has been enabled without matching credentials in mongodb_uri.
Fix: Confirm MongoDB service health, then test the connection directly:
sudo systemctl status mongod
mongosh mongodb://localhost:27017/graylog
Blank Dashboard After Login
Symptom: The login page loads, but authentication leads to a blank dashboard or browser-console CORS errors.
Cause: The http_external_uri value does not match the URL used to access Graylog.
Fix: Correct http_external_uri, restart Graylog Server, and clear the browser cache.
sudo systemctl restart graylog-server
High OpenSearch CPU During Ingest
Symptom: OpenSearch CPU stays high during heavy log ingestion, while searches become slow or delayed.
Cause: Too many shards, an aggressive one-second refresh interval, or insufficient memory and disk I/O capacity.
Fix: Review index configuration. Increasing the refresh interval to 5 or 10 seconds for busy indices can materially reduce CPU load without making logs meaningfully less useful for most operational work.
Disk Space Disappears Quickly
Symptom: The OpenSearch data volume fills within days.
Cause: Index retention is too generous for the actual ingest rate, or verbose low-value logs are being indexed without filtering.
Fix: Check index rotation and retention settings in System → Indices in the Graylog interface. Rotate indexes by size or time according to your real disk budget, not generic defaults.
Performance and Optimization Tips
- Monitor disk I/O on the OpenSearch data volume with
iostat -x 1during peak ingest hours. This quickly shows whether you are I/O-bound rather than CPU-bound. - Use size-based index rotation, such as 1GB per shard, instead of relying only on time-based rotation for unpredictable traffic patterns. It prevents a single shard from growing unwieldy during a sudden spike.
- Use Graylog pipeline rules to drop or downsample noisy low-value messages, such as routine health-check requests, before they reach OpenSearch.
- Review
_cat/indices?voutput periodically to identify indexes with disproportionate shard counts relative to stored data. Over-sharding is a subtle but real performance drag on smaller environments.
curl -s http://127.0.0.1:9200/_cat/indices?v
Security Hardening Checklist
- Keep MongoDB and OpenSearch bound to localhost or a private network interface. Never expose them directly to the public internet.
- Rotate the Graylog
password_secretonly during a planned maintenance window. Changing it invalidates existing sessions and encrypted credentials stored in the database. - Enable OpenSearch security with TLS for any environment handling logs that may contain PII, credentials, tokens, or customer information.
- Enable Ubuntu security updates with
unattended-upgrades, but pin Graylog, MongoDB, and OpenSearch packages so a routine upgrade does not silently introduce an incompatible major version. - Create dedicated log-forwarding credentials or access tokens with the minimum permissions needed. Do not reuse the Graylog administrator account for automated integrations.