Installation
Install OSS Panel on a fresh Ubuntu server with one command, and understand every step it runs.
Installation is a single shell script. It is safe to re-run: every step checks whether its work is already done and skips it, so a failed install is fixed by fixing the cause and running the same command again.
Before you start, check Requirements.
1. Run the installer
SSH into the server as a user with sudo, then:
curl -fsSL https://raw.githubusercontent.com/DipaliRadadiya/open-source-sa/main/install.sh \
| sudo bash -s -- --stack=lemp--stack is required in this form. Piping into bash leaves no terminal
for the installer to ask on, so without the flag it silently defaults to
lemp.
If you would rather read the script first — a reasonable thing to do with something that runs as root:
curl -fsSL -O https://raw.githubusercontent.com/DipaliRadadiya/open-source-sa/main/install.sh
less install.sh
sudo bash install.shRun that way, with a terminal attached, it asks which stack to build instead of guessing.
2. Choosing a stack
The stack decides the web server, and the web server serves the panel itself — so it cannot be changed from inside the panel later without taking the panel down with it. Pick deliberately.
| Flag | Web server | Runtime | Use it for |
|---|---|---|---|
--stack=lemp | nginx | PHP 8.4 | The default. PHP applications — WordPress, Laravel, anything else. |
--stack=lamp | Apache | PHP 8.4 | PHP applications that need .htaccess or an Apache module. |
--stack=mern | nginx | Node 24 | Node applications, reverse-proxied. |
--stack=ols | OpenLiteSpeed | LSPHP 8.4 | PHP with LiteSpeed caching. |
--stack=docker | nginx | Docker | Containers, reached through a reverse proxy. |
On the OpenLiteSpeed stack
There is no per-site PHP isolation on ols — every site shares one PHP
build, with no per-site pools. The 8G firewall and the bot blocker both
work. The installer prints this at stack selection, not afterwards.
3. Options
--stack=lemp Which stack to build:
lemp nginx + PHP (default)
lamp Apache + PHP
mern nginx + Node
ols OpenLiteSpeed + PHP
docker nginx + Docker
Asked interactively when not given and a terminal
is available. Required for `curl | bash`, which
has no terminal to ask on.
--domain=panel.example.com Use your own domain instead of a nip.io name.
Point its A record at this server first.
--email=you@example.com Address for Let's Encrypt expiry warnings.
--branch=main Branch to install from.
--no-ssl Serve plain HTTP. Fine behind another proxy.
--dry-run Print the steps without touching anything.Using your own domain
sudo bash install.sh --stack=lemp \
--domain=panel.example.com \
--email=you@example.comPoint the A record at the server first. If the name does not resolve to
this server when the installer reaches the TLS step, Let's Encrypt cannot
validate it and you fall back to a self-signed certificate.
Without a domain
Leave --domain off and the panel gets a nip.io address
built from the server's public IP:
[03] Working out the address
✓ panel: https://panel.203-0-113-10.nip.io
✓ api: https://api.203-0-113-10.nip.ioTwo names, one shared parent. That is load-bearing: panel. and api. are
children of 203-0-113-10.nip.io, so a single session cookie can cover both.
A dash instead of that dot would make them unrelated siblings and logging in
would not work.
Behind another proxy
--no-ssl serves plain HTTP and skips certificate issuance. Use it only when
something in front of the server already terminates TLS.
Seeing what it would do
--dry-run prints every step and every command without touching the server.
Worth running once on a box you care about.
4. What it does
Roughly twenty numbered steps, in this order:
/var, systemd.--stack, your answer, or the lemp default.panel account./var/www/panel.panel-frontend, panel-fpm, panel-queue.sudoers rule.Progress looks like this:
[01] Checking this server
✓ Ubuntu 24.04.4 LTS
✓ architecture x86_64
✓ 82876 MB free on /var
✓ logging to /var/log/panel-install.log
[02] Choosing the stack
✓ lemp — nginx, PHP 8.4, Node 24
[03] Working out the address
✓ panel: https://panel.203-0-113-10.nip.io
✓ api: https://api.203-0-113-10.nip.io
[04] Checking memory
✓ 5925 MB RAM + 1023 MB swap, already enoughEverything is logged to /var/log/panel-install.log.
5. When it finishes
The control panel is installed
Panel: https://panel.203-0-113-10.nip.io
API: https://api.203-0-113-10.nip.io
Stack: lemp (nginx)
Log: /var/log/panel-install.log
Files: /var/www/panel
Open the panel and register — the first account becomes the
administrator, and registration closes behind it.
Do that now. Until you do, anyone who reaches this address can
claim the administrator account.
Then use the setup page to install a database engine and anything
else you need.Register immediately
Between the end of the install and your first registration, the panel is open: the first person to reach that URL becomes its administrator. Do not leave a freshly installed panel unregistered.
Continue to First login.
Troubleshooting
The install stopped. Read the cause it printed, fix it, and run the same command again — the installer skips work that is already done.
sudo cat /var/log/panel-install.logThe browser warns about the certificate. Let's Encrypt did not issue one — usually a DNS record that does not point here yet, or a rate limit. The panel is installed and working behind a self-signed certificate. Once the cause is fixed:
sudo certbot --nginx -d panel.example.comSome checks failed at step 19. The panel is installed, but parts of it will not work until those are fixed. The panel's own doctor screen reports the same checks from inside the interface.
A known cosmetic error at 'Installing services'
On v1.0.14 the installer prints line 3108: default: command not found and a
red "Install stopped (exit 127)" block during Installing services, then
carries on and completes normally. It is a quoting bug in a comment, not a
failed install. Check the final summary: if it printed "The control panel
is installed", it did.