Skip to main content

Command Palette

Search for a command to run...

The Process Behind Using curl | bash for NexoralDNS One-Line Install

Updated
5 min read

As a software engineer, I strongly believe in one thing:

If your user has to read documentation before using your product, you already lost them.

That belief is the reason NexoralDNS can be installed using a single command:

curl -fsSL https://raw.githubusercontent.com/nexoral/NexoralDNS/main/Scripts/install.sh | bash

But this post is not marketing.

This is me explaining—as a developer—what actually happens when someone runs this command, why it’s safe (when done correctly), and how I designed the installer to make users do less work, not more.


Why I Even Chose curl | bash

Let’s be honest.

Most engineers are suspicious of curl | bash.
And they should be.

So why did I still choose it?

Because:

  • My target users are sysadmins, devs, and homelab users

  • NexoralDNS touches networking, DNS, ports, and resolvers

  • Manual setup would be painful and error-prone

  • Consistency matters more than purity

The goal wasn’t zero magic.
The goal was predictable automation.


Breaking Down the Command (No Myths)

Let’s split it:

curl -fsSL <url> | bash

What curl Does Here

  • -f → fail silently on HTTP errors

  • -s → silent mode (no progress spam)

  • -S → still show errors if something fails

  • -L → follow redirects (GitHub raw URLs need this)

So effectively:

“Download this script only if it succeeds, otherwise stop.”

No partial downloads. No HTML pages piped into bash.


What the Pipe (|) Actually Means

The pipe does not magically give root access.

It simply means:

  • curl outputs text (the script)

  • bash reads that text from STDIN

  • Bash executes it line by line

Equivalent to:

curl file.sh
bash file.sh

Just without creating a temporary file.


My Core Installer Philosophy

Before writing a single line of this script, I decided:

  1. Fail early

  2. Explain everything

  3. Never assume system state

  4. Undo changes on stop/remove

  5. Networking safety > convenience

That mindset shaped the entire installer.


Step 1: System Compatibility Checks (Before Touching Anything)

The script starts by answering one question:

“Should this system even be allowed to continue?”

It checks:

  • Linux only (no macOS, no WSL tricks)

  • Debian-based distros only (Ubuntu, Debian, Mint, Zorin)

  • Presence of apt

  • Minimum 2GB RAM

  • Minimum 10GB disk

Why?

Because DNS is infrastructure, not a toy.
Failing halfway through setup is worse than refusing early.


Step 2: Port Safety (DNS Is Special)

NexoralDNS needs:

  • 53 (UDP) → DNS

  • 4000 → Admin Web UI

  • 4773 → Internal broker

Before anything starts:

  • The script checks if these ports are already in use

  • Uses lsof or ss

  • Hard-fails if any are occupied

Why I’m strict here:

Binding to port 53 while another resolver is running will silently break DNS.

Silent failures in networking are deadly.


Step 3: systemd-resolved (The Most Dangerous Part)

This is the part most installers get wrong.

On modern Linux:

  • systemd-resolved already listens on port 53

  • /etc/resolv.conf is often a symlink

  • Blindly overwriting it breaks networking

So my script:

  • Detects if systemd-resolved is running

  • Stops and disables it only when required

  • Frees port 53 cleanly

  • Restores it on stop or remove

This is also why uninstalling NexoralDNS restores your DNS, not breaks it.

That took time to get right.


Step 4: Docker Before DNS (Very Intentional)

Here’s a subtle but important decision:

All Docker images are pulled before DNS is disabled.

Why?

Because Docker pulls need DNS.
If I disabled the resolver first, image pulls would fail.

So the flow is:

  1. Pull MongoDB, Redis, RabbitMQ, NexoralDNS image

  2. Then disable system resolver

  3. Then start containers

This small sequencing detail prevents a massive class of bugs.


Step 5: Why Docker at All?

I didn’t choose Docker because it’s trendy.

I chose it because:

  • DNS servers must be reproducible

  • Networking state must be controlled

  • Dependencies must be versioned

  • Updates must be reversible

Docker gives me:

  • Predictable runtime

  • Safe upgrades

  • Clean uninstall

  • Zero host pollution

For infra software, this matters.


Step 6: Version-Aware Updates (Not Blind Pulls)

The installer:

  • Fetches a remote VERSION file

  • Compares semantic versions

  • Updates only if remote > local

  • Avoids unnecessary restarts

This matters because:

  • DNS downtime is real downtime

  • Restarting unnecessarily is irresponsible


Step 7: DHCP Awareness (This Was Personal Curiosity)

DNS servers break when IPs change.

So the script:

  • Detects the machine’s active DHCP IP

  • Updates /etc/resolv.conf to point to itself

  • Warns the user to set a static IP

  • Uses internal messaging to rebind if IP changes

This came from my own experiments:

“What happens if the DNS server IP changes mid-run?”

Now I know. And I coded for it.


Step 8: start, stop, update, remove Are First-Class

This installer is not “run once and forget”.

It supports:

bash install.sh start
bash install.sh stop
bash install.sh update
bash install.sh remove

Each command:

  • Manages DNS safely

  • Restores system state

  • Never leaves the system half-configured

Uninstalling does not leave broken DNS behind.
That was non-negotiable.


Why I Built It This Way

As an engineer, I hate installers that:

  • Assume too much

  • Don’t clean up

  • Break networking

  • Require manual fixes after uninstall

So I built the opposite.

The one-liner exists so users:

  • Don’t read 10 pages of docs

  • Don’t debug port conflicts

  • Don’t fight DNS

  • Don’t understand Docker internals

They just get a working DNS server.


Final Thought

Yes, curl | bash can be dangerous.

But opaque scripts are dangerous, not the pattern itself.

That’s why NexoralDNS’s installer is:

  • Open source

  • Explicit

  • Defensive

  • Reversible

  • Designed with networking respect

Automation is not about hiding complexity.
It’s about absorbing it responsibly.

More from this blog

A

AnkanHub

16 posts