Sites and applications

Create and manage sites

Every site is its own Linux user with its own directory, nginx server block and, where the type needs one, its own runtime process. This page covers what all site types share.

Verified against auraPanel 1.21.3· Last updated 17 September 2026

Site types

Sites → Add site offers six kinds of site. The search box above them lists every application in the catalogue, marked Auto-Install (the panel installs it for you) or Assisted (the panel prepares the site and you complete the application's own installer).

TypeWhat runsDetails
PHP ApplicationsPHP-FPM pool per siteWordPress, Moodle, Drupal, Laravel or any PHP app. PHP and WordPress sites
Node.jsYour app as a systemd serviceNode.js sites
Pythongunicorn as a systemd servicePython sites
Static HTMLnginx serving filesA seeded index.html you replace with your build output.
Reverse Proxynginx proxying to an upstream URLFor services you run yourself. WebSockets are passed through.
Docker ComposeA container stack behind nginxAdministrators only. Docker Compose sites

Create a site

  1. Point the domain's DNS at the server first if you want HTTPS straight away: an A record (and AAAA for IPv6) for example.com. If Cloudflare proxies the domain, read HTTPS certificates before continuing.
  2. Open Sites → Add site, choose a type or search for an application.
  3. Enter the domain. It must contain a dot and may use letters, digits, hyphens and dots.
  4. Fill in the type-specific fields: PHP version for PHP; Node version, app port and supervisor (systemd or PM2) for Node.js; app port and module for Python; upstream URL for a reverse proxy; image or compose file for Docker. Auto-install applications also ask for a site title, database engine and administrator credentials.
  5. Check the site user. It is derived from the domain (every label except the last, joined with hyphens, 30 characters at most), and you can change it. A site password is generated for SFTP.
  6. Create. The panel provisions the site and then requests a certificate in the background.
Expected result

The site appears in the list as Online with a placeholder certificate. Within about a minute of DNS pointing at the server the padlock is real; the site's overview shows the certificate state and any issuance error.

What a site is on the server

Every site is its own Linux user, so one compromised application cannot read another's files. Creation happens in a fixed order: user, directories, log rotation, placeholder certificate, runtime (a PHP-FPM pool, or a port and a systemd unit), then the nginx server block, which is tested with nginx -t before it is enabled and reloaded once.

PathPurpose
/home/<user>/htdocs/<domain>/Document root (your files). Owned by the site user.
/home/<user>/logs/access.log, error.lognginx logs for this site, rotated. Logs and monitoring
/etc/nginx/sites-available/<domain>.confThe server block. Managed by the panel; hand edits are overwritten on the next render.
/etc/php/<ver>/fpm/pool.d/The site's PHP-FPM pool (PHP sites).
aurapanel-site-<domain>.serviceThe systemd unit (Node.js, Python and Docker sites).
/etc/aurapanel/ssl/<domain>.crt, .keyCertificate and key.

Every server block gets HSTS, X-Content-Type-Options, X-Frame-Options, hidden nginx version, an ACME challenge location, and a rule that denies access to any *.log file under the document root.

To serve from a subdirectory of the document root (Laravel's public/, Moodle 5's public/), set Settings → General → Document root. It must stay inside the site's home directory.

Upload files

  • File Browser tab: upload (large files are chunked), download, rename, move, copy, edit text files, change permissions, zip and unzip.
  • SSH/FTP Users tab: create accounts that are either SFTP only (jailed to the site's home) or SSH + SFTP (a real shell as the site user), with a password, public keys, or both. A generated password is shown once.
  • Anything else that writes as the site user works too: rsync, git, a CI job over SSH.

Per-site controls

Security tab

  • Force HTTPS redirect: on for new sites; it has no effect until a certificate exists.
  • Basic authentication: a username and password in front of the whole site. Stored bcrypt-hashed in /etc/aurapanel/htpasswd/<domain>. Leaving the password blank keeps the existing one.
  • Cloudflare: an API token for DNS-01 certificates and the edge shield. HTTPS certificates, Security and hardening.

Cron

Under Maintenance → Cron, add a schedule and a command. Jobs run as the site user, in the site's time zone, and are written to that user's crontab under a managed header. Schedule and command are both required; the schedule is validated as a cron expression.

Redirects

The Redirection screen redirects a hostname, or a path, to a site on this server with a 301 or 302. Each redirected hostname gets its own server block and certificate, so old-domain.com can redirect to a site over HTTPS. Redirects are removed with the site they point at.

From the command line

apcli site list
apcli site create example.com --type php --php 8.4
apcli site create api.example.com --type reverseproxy --upstream http://127.0.0.1:3001
apcli site upstream api.example.com            # show the upstream
apcli site delete example.com

The system user is derived the same way as in the form when --user is omitted. The full reference is on the documentation index.

Delete a site

Deleting a site removes its server block, runtime unit or pool, databases, redirects, Linux user and home directory. After teardown the panel runs any executable in /etc/aurapanel/hooks.d/site-delete/ with AURAPANEL_DOMAIN, AURAPANEL_SITE_USER and AURAPANEL_DOCROOT in the environment, which is how out-of-panel services clean up after themselves. Take a backup first if you may want the content back.

Common messages

"a site for … already exists — choose a different domain"

Each domain can be one site. Delete the old site or use a subdomain.

"port … is already used by … — choose a different port"

Node.js, Python and Docker sites each bind a loopback port. Pick a free one; the panel suggests the next free port by default.

"No PHP runtime is installed on this server" (or the Node.js / Python equivalent)

Install the runtime under Services first (PHP Runtimes, Node Versions, or Packages for Python 3), then create the site.

"upstream must be a public address; loopback, link-local and private ranges are not allowed"

Only administrators may point a reverse proxy at a loopback or private address. Sign in as an administrator, or expose the service on a public address.

Try the live demo

A real auraPanel on a real server, shared with everyone. Sign in with the demo account and click around.

Email
demo@goaura.one
Password
demo1234
Open the demo panel ↗

Shared public demo, so please don’t put anything personal in it. More about the demo →

Talk to us

Tell us what you need and how to reach you. A person reads this, not a queue.

We use these details only to reply to you. Privacy

Recent updates

What shipped in the last releases. With automatic updates on, each lands on your server the moment it is published.

  1. v1.21.3
    Framework sites were undetectable, and a restore could silently point the copy at the original's live database.

    DetectApp looked for each application's signature relative to the docroot — but every PHP framework in the registry serves from a subdirectory (DocrootSub: public, webroot, web, pub, docroot) and keeps the file that identifies it one level *above* that. So the Laravel signature searched <project>/public/artisan,…

  2. v1.21.2
    Restarting nginx now blocks the panel and reconnects, instead of showing a notice.

    v1.21.1 stopped the false "HTTP 520" but only put up a toast — and a toast is the wrong affordance when the panel itself is about to go away: the page sat there looking broken while every request failed underneath it.

  3. v1.21.1
    Restarting nginx from Services no longer reports a false failure.

    It showed "Restart failed — HTTP 520". The panel is reverse-proxied *by* nginx, so the request deadlocked against itself: the handler blocked waiting for the restart to finish, while nginx's graceful stop waited for that very request to drain. Neither could proceed until nginx's stop-retry timeout force-killed it,…

  4. v1.21.0
    Per-site X-Frame-Options, fixing page builders that couldn't load their preview.

    Elementor's editor failed with *"Multiple 'X-Frame-Options' headers with conflicting values ('DENY, SAMEORIGIN')"*. The cause is that nginx's add_header appends rather than replaces: when the application also sets the header — a WordPress security plugin, or a CDN transform — the browser received two values,…

  5. v1.20.6
    The multi-database restore refusal now says what is in the backup and what still works.

    It read only "Restoring a multi-database site isn't supported yet", which is a dead end: it named neither the databases involved, nor why one of them is the limit, nor any route forward.

  6. v1.20.5
    Services: cards in a row now match heights.

    Like the settings grid before it, the Services grid pinned each card to its own content height, so a row often showed one card noticeably shorter than the card beside it. Each row now takes the taller card's height and both fill it, and it re-balances as content changes — a runtime installed, a longer service list.

  7. v1.20.4
    Settings: paired cards now match heights.

    Organisation / Panel Domain and auraPanel Updates / Session timeout each sat at their own content height, so a row showed one card visibly shorter than its neighbour. Each row now takes the taller card's height and both fill it — driven by content, not a fixed value, so it still adapts as a card grows (a validation…

  8. v1.20.3
    Settings: Organisation and Panel Domain now share a row too.

    They were full-width blocks stacked above the rest of the page; they now sit side by side in the same two-column grid as the Updates / Session timeout pair, so the top of Settings reads as two tidy rows instead of four stacked bands. Both cards shrink cleanly — the logo drop zone is a fixed 44×44 and the name field…

All releases on GitHub ↗