Change your Nginx docroot

Letting the platform manage it

The two methods above are yours to maintain. There is also a platform-native override that changes
the served folder and keeps the generated configuration in sync, so it survives platform updates
without you editing `50main.conf` by hand. That is the cleanest option when a framework serves from
a fixed subfolder such as `public` or `web`, and it is the one to ask
Support for if the symlink does not suit your deployment.


Change your Nginx docroot

Related

nginx docroot change document root change document root public_html symlink 50main.conf root deployer current releases

- Configure Nginx
- What is Nginx?
- TurboStack CLI - reload Nginx with `tscli nginx reload`


Configure Nginx on TurboStack

configure nginx turbostack nginx yaml webserver nginx nginx host configuration

# Configure Nginx on TurboStack

Selecting Nginx as the web server for a host takes a single setting; TurboStack
generates the per-application configuration from there.


Configure Nginx on TurboStack

Where to configure it

The web server is chosen at the **host** level:

1. Open the host.
2. Go to the **Services** tab.
3. Under **Webserver**, select **nginx**.

This applies to every application on the host. The per-application vhost (caching
headers, static-asset expiry, security denies and the PHP-FPM backend) is
generated automatically - there is no raw config to write by hand.


Configure Nginx on TurboStack

Required

| Key | Meaning |
|---|---|
| `webserver` | The host's web server. Set to `nginx` to select Nginx. |


Configure Nginx on TurboStack

Optional

Per-application virtual host tuning (caching, static-asset expiry, security denies
and the PHP-FPM backend) is **generated for you** by TurboStack - there are no
extra Nginx keys you need to set.

```yaml
# Host-level: select Nginx as the web server
webserver: nginx
```

> [!TIP]
> Only one web server runs per host. To switch to Apache, change `webserver` to
> `apache2` - see Configure Apache.


Configure Nginx on TurboStack

Custom Nginx configuration

The generated vhost covers most needs, but you can add your own Nginx configuration per system user
in the `~/nginx` directory (over SSH). Files load in **alphabetical
order**, so the numeric prefix sets the priority. Two files are present by default:

- `20rewrites.conf` - your redirects and rewrites.
- `50main.conf` - the main server block. A file with a prefix above `50` loads after it; below `50`,
  before it.

When Varnish is enabled it sits in front of Nginx, and the location decides when your rules run:

- Files in `~/nginx/` load **after** Varnish - app-level rewrites, headers and security rules.
- Files in `~/nginx/outside/main/` load **before** Varnish - edge rules and pre-cache allow-lists.

Custom config applies only to that system user's applications. Besides `.conf`, the `.runmaps` (Magento
routing) and `.http` (for example `backend.http`) file types are also supported.

Apply changes with the TurboStack CLI:

```bash
tscli nginx reload
```

> [!WARNING]
> Editing `50main.conf` needs Nginx knowledge - a mistake can take the site offline. `tscli nginx
> reload` validates the config and points to the error. If you are unsure, contact
> support first.


Configure Nginx on TurboStack

Common tasks

- Force HTTPS
- Redirect to/from www
- Block or allow IP addresses
- Add custom HTTP headers
- Restrict admin access
- Change the Nginx docroot


Configure Nginx on TurboStack

Related

- What is Nginx?
- Host Services tab
- Applications overview
- TurboStack CLI - reload or restart Nginx with `tscli nginx reload`


How to add custom HTTP headers

custom http headers security headers add header nginx hsts header

# How to add custom HTTP headers

Add your own HTTP response headers - most often security headers - with a small piece of custom
Nginx configuration.


How to add custom HTTP headers

Before you start

- **SSH access to the host** - see SSH access.
- Add the headers in `~/nginx/50main.conf` - see custom Nginx configuration.


How to add custom HTTP headers

Add security headers

In the server block (or a `location`), use `add_header` with the `always` flag so the header is sent
on error responses too:

```nginx
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
```

> [!IMPORTANT]
> If you add `add_header` inside a `location`, Nginx stops inheriting the headers set higher up - you
> must repeat the ones you still want in that location.


How to add custom HTTP headers

Restrict access to text and log files

A common hardening rule: allow `robots.txt`, but deny other `.txt` and `.log` files.

```nginx
location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}
location ~* \.(txt|log)$ {
    deny all;
}
```


How to add custom HTTP headers

Apply and verify

```bash
tscli nginx reload
```

Check the headers with:

```bash
curl -I https://example.com
```

> [!TIP]
> To make browsers always use HTTPS, add the `Strict-Transport-Security` (HSTS) header - but only
> once HTTPS works everywhere, because it is hard to undo. See Force HTTPS.


How to add custom HTTP headers

Related

- Configure Nginx
- Force HTTPS
- Security hardening


How to force HTTPS

force https redirect http to https https only ssl redirect

# How to force HTTPS

On TurboStack you do not need to write a redirect to force HTTPS - it is handled for you. Once a
application has an active certificate, the platform serves it over HTTPS and redirects HTTP to HTTPS
automatically.


How to force HTTPS

Make sure HTTPS is active

Give the application a certificate by setting `cert_type: letsencrypt` (the default for most
applications) and publishing - see
TLS certificates. Once the certificate is
issued, HTTP requests are redirected to HTTPS.

> [!NOTE]
> Because the redirect is done at the web-server layer, you do not need an application plugin for it
> (for example, remove the redundant `really-simple-ssl` plugin on WordPress). Do not add your own HTTP-to-HTTPS redirect
> in custom Nginx config - it would duplicate the platform's and can cause redirect loops.


How to force HTTPS

Point your application at HTTPS

So your app generates `https://` links and avoids mixed-content warnings, set its site or base URL to
the `https://` address (for example the WordPress Site Address, or the framework's `APP_URL`).


How to force HTTPS

Optional: enforce HTTPS in the browser with HSTS

To tell browsers to always use HTTPS for your domain, add the `Strict-Transport-Security` header -
see Add custom HTTP headers:

```nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
```

> [!WARNING]
> Enable HSTS only when HTTPS works on the domain and its subdomains. It is cached by browsers for a
> long time and is hard to undo.


How to force HTTPS

Verify

An HTTP request should answer with a `301` redirect to the `https://` URL:

```bash
curl -I http://example.com
```


How to force HTTPS

Related

- TLS certificates
- Add custom HTTP headers
- TLS certificate problems


How to redirect to or from www

redirect www non-www canonical domain www redirect

# How to redirect to or from www

Pick one canonical form of your domain - either `www.example.com` or `example.com` - and redirect the
other to it. This avoids duplicate content and keeps links and analytics consistent.


How to redirect to or from www

Before you start

- **SSH access to the host** - see SSH access.
- Both forms should point to your server and have a certificate (`cert_type: letsencrypt`) so HTTPS
  works after the redirect - see TLS certificates.
- Add the rule to `~/nginx/20rewrites.conf` - see custom Nginx configuration.


How to redirect to or from www

Redirect non-www to www

```nginx
if ($host ~ ^(?!www\.)(?<domain>.+)$) {
    return 301 $scheme://www.$domain$request_uri;
}
```


How to redirect to or from www

Redirect www to non-www

```nginx
if ($host ~* ^www\.(?<domain>.+)$) {
    return 301 $scheme://$domain$request_uri;
}
```


How to redirect to or from www

Redirect extra domains to your main domain (keeping the path)

```nginx
if ($http_host ~* "(old-one\.example\.net|old-two\.example\.org)$") {
    return 301 $scheme://www.example.com$request_uri;
}
```


How to redirect to or from www

Add a trailing slash to a path

Redirect a path without a trailing slash to its slashed form, so a single canonical URL
is served:

```nginx
location /blog {
    rewrite ^/blog$ /blog/ permanent;
}
```


How to redirect to or from www

Redirect a domain to a specific page

Send every request for one domain to a fixed page on another, rather than keeping the
requested path:

```nginx
if ($http_host ~* "^.*your-domain\.be$") {
    rewrite ^/$ https://your-domain/page/ redirect;
}
```


How to redirect to or from www

Apply and verify

```bash
tscli nginx reload
```

Check the redirect (look for `301` and the `Location` header):

```bash
curl -I https://example.com
```


How to redirect to or from www

Related

- Configure Nginx
- TLS certificates
- Connecting your domain


restrict admin access protect admin basic auth password protect ip restrict admin

# How to restrict access to your admin area

Lock an admin area (for example `/wp-admin`) or a whole staging site so only you can reach it. There
are two approaches, which you can combine: an **IP allow-list**, and **HTTP basic authentication**.


Before you start

- **SSH access to the host** - see SSH access.
- See custom Nginx configuration for how `~/nginx` works.


Option 1: IP allow-list

Restrict a path to known addresses in `~/nginx/50main.conf`:

```nginx
location /admin/ {
    allow 203.0.113.10;
    deny all;
}
```

For allow/deny rules that cover a whole site rather than one path, see
Block or allow IP addresses.


Option 2: HTTP basic authentication

Ask for a username and password, optionally letting trusted IPs skip the prompt.

1. Install the `apache2-utils` package (it provides `htpasswd`) by adding it to
   `os_extra_packages` and publishing:
   ```yaml
   os_extra_packages:
     - apache2-utils
   ```
2. Generate a password file over SSH:
   ```bash
   htpasswd -c /var/www/prod/.secrets/htpasswd prod
   ```
   You are prompted for a password - use a long, complex one.
3. Enable it on a location in `~/nginx/50main.conf`:
   ```nginx
   location / {
       auth_basic "Restricted area";
       auth_basic_user_file /var/www/prod/.secrets/htpasswd;

       # optional: trusted IPs skip the login prompt
       allow 203.0.113.10;
       satisfy any;
   }
   ```


Apply and verify

```bash
tscli nginx reload
```

Visit the protected path: you should be asked to log in (or be allowed straight through from a
trusted IP), and blocked otherwise.

> [!WARNING]
> Editing `50main.conf` can take the site offline if a rule is wrong. `tscli nginx reload` validates
> the config and reports the error. If you are unsure, contact support.


Related

- Configure Nginx
- Block or allow IP addresses
- Installing extra OS packages
- Security hardening
</content>


What is Nginx?

what is nginx nginx hosting nginx turbostack nginx web server nginx reverse proxy

# What is Nginx?

Nginx is a web server and reverse proxy that handles many simultaneous
connections with low memory and CPU usage. It serves static files (images,
CSS, JavaScript) directly, and forwards dynamic requests to an application
backend such as PHP-FPM.

Its event-driven design suits high-traffic sites, caching, and routing
HTTP/HTTPS requests to the correct backend. It is the most widely deployed
web server for modern PHP applications.


What is Nginx?

On TurboStack

Nginx is the **default web server** on TurboStack and is recommended for most
workloads.

- Each host runs **one web server**. When Nginx is selected, TurboStack
  provisions and manages it for every application on that host.
- TurboStack **generates the per-application virtual host (vhost)** for you. The
  generated config includes sensible caching headers, static-asset expiry rules,
  security denies (blocking access to sensitive paths), and the correct
  **PHP-FPM backend** for each application's PHP version.
- You do not edit raw Nginx config files. You enable Nginx at the host level and,
  where needed, adjust per-application behavior through the supported settings -
  TurboStack renders and reloads the configuration safely.

> [!NOTE]
> Nginx and Apache are mutually exclusive on a host - you choose one web server
> per host. Nginx is the default and the recommended choice unless your
> application specifically needs Apache features.


What is Nginx?

Best practices

- Keep Nginx as your web server unless an app genuinely requires `.htaccess` or
  Apache-only modules.
- Let TurboStack generate the vhost rather than hand-rolling config, so caching,
  expiry and security rules stay consistent.
- Serve static assets through Nginx and reserve PHP-FPM for dynamic requests to
  keep response times low.
- Pair Nginx with a caching layer (such as Varnish or Redis) for read-heavy,
  high-traffic sites.
- Always front Nginx with Transport Layer Security (TLS) - terminate HTTPS at the web server for every
  public application.


What is Nginx?

Related

- Configure Nginx on TurboStack
- Host Services tab


Configure Node.js on TurboStack

configure node.js turbostack node.js yaml nodejs_version proxy_enabled reverse proxy

# Configure Node.js on TurboStack

Enable the Node.js runtime on an application and proxy public traffic to it with Nginx.


Configure Node.js on TurboStack

Where to configure it

The Node.js runtime is configured per application. In the TurboStack Platform, open an application and go to **Configure application > Technologies > NodeJS**, then choose the version your application should use.

To publish the application, you also enable the reverse proxy so Nginx forwards public traffic to the local port your Node.js process listens on. See Configure the reverse proxy for that side of the setup.


Configure Node.js on TurboStack

Required

| Key | Meaning |
| --- | --- |
| `nodejs_version` | The Node.js major version to install, for example `"24"` (or newer). Setting this enables the Node.js runtime for the application. |

> [!NOTE]
> There is no separate "enable" key. Node.js is installed for an application as soon as you set
> `nodejs_version` on it, and is left out when you omit the key.


Configure Node.js on TurboStack

Optional

These keys are typically added together with the reverse proxy so public traffic reaches your app.

| Key | Meaning |
| --- | --- |
| `proxy_enabled` | Enables the Nginx reverse proxy for the application. |
| `proxy_upstream_port` | The local port your Node.js application listens on. |

```yaml
nodejs_version: "24"

# Publish the app via the nginx reverse proxy
proxy_enabled: true
proxy_upstream_port: 3000   # the port your Node.js process listens on
```


Configure Node.js on TurboStack

Permissions

Harden the files and directories in your application so files are readable but not writable by the group, and directories stay traversable. Run these from the parent of your application's directory (replace `~/app` with wherever your Node.js application lives):

```bash
find ~/app -type f -exec chmod 644 {} \;
find ~/app -type d -exec chmod 755 {} \;
```

This sets files to `644` (owner read/write, others read-only) and directories to `755` (owner read/write/traverse, others read/traverse).


Configure Node.js on TurboStack

Common tasks

- set the Node.js version
- keep a Node.js app running


Configure Node.js on TurboStack

Related

- What is Node.js?
- Keep a Node.js app running
- Configure the reverse proxy
- TurboStack CLI - `tscli app backends` shows the configured process manager.
- Applications overview


How to keep a Node.js app running

keep node running node process manager node service restart node app supervisor node pm2

# How to keep a Node.js app running

A Node.js application is a long-lived process. If it crashes, or the server reboots, it must start
again on its own - otherwise Nginx has nothing to forward to and returns a 502 error. On TurboStack
you keep it running with the **pm2** process manager (a systemd service is the alternative).

pm2 keeps the app running with auto-restarts, manages several apps at once, and gives you monitoring
and log viewing in one place.


How to keep a Node.js app running

Before you start

- **SSH access to the host** - see SSH access. Run these commands as
  your system user.
- **The Node.js runtime enabled** on the application, and your app listening on the local port set
  as `proxy_upstream_port` so Nginx can proxy to it - see Configure Node.js and the
  reverse proxy. When you enable the Node.js runtime, pm2 is
  installed for you by the node package manager, so there is nothing extra to install.


How to keep a Node.js app running

Deploy and start your app under pm2

If you migrated from another environment, reinstall dependencies cleanly first so no incompatible or
corrupted modules are left behind:

```bash
cd ~/app
rm -rf node_modules      # only when migrating or dependencies changed
npm install              # rebuild node_modules
npm run build            # build the app (for example a Next.js build)
```

Then start it under pm2 and give it a name:

```bash
pm2 start npm --name app -- start     # runs "npm start"
# or run a file directly:
pm2 start server.js --name app
```

Check that it is running:

```bash
pm2 ls
```


How to keep a Node.js app running

Make it survive reboots

TurboStack already provisions a platform-managed `pm2-<user>` system service that starts pm2 and
your saved processes at boot, so you do not run `pm2 startup` yourself (as a non-root user it only
prints a `sudo` line and cannot complete). What you must do is save the current process list so the
platform service brings the right apps back:

```bash
pm2 save       # save the current process list - run this again after every change
```

> [!IMPORTANT]
> Run `pm2 save` **every time** you add, rename or remove a process. Without it, pm2 restores an old
> list (or nothing) after a reboot, and your app stays down.


How to keep a Node.js app running

Monitor and read logs

```bash
pm2 ls                 # list processes with status, CPU, memory and restart count
pm2 show app           # details for one process
pm2 logs app           # live logs (use --lines 200, --err or --out to narrow)
pm2 monit              # live dashboard: CPU/memory per app, status, restarts, real-time logs
```


How to keep a Node.js app running

Restart after a change or deploy

```bash
pm2 restart app        # full restart
pm2 reload app         # zero-downtime reload (for cluster-mode apps)
```

When you change dependencies or move the app from another environment, reinstall cleanly first to
avoid incompatible modules:

```bash
rm -rf node_modules
npm install
pm2 restart app
```


How to keep a Node.js app running

Check which process manager is configured

To see which manager each application user runs under, use the
TurboStack CLI:

```bash
tscli app backends
```


How to keep a Node.js app running

Alternative: a systemd user service

Instead of pm2 you can run any long-lived app (Node.js, Python, a custom worker) as a **systemd user
service**. It needs no root, integrates with `journalctl` for logs, and restarts on crash and on
boot. Use pm2 when you want its process dashboard and zero-downtime reloads; use a systemd service
when you prefer one consistent way to run every background process on the host.

For the unit file and the `systemctl --user` commands, see
How to manage user system services.


How to keep a Node.js app running

Related

- Configure Node.js
- What is Node.js?
- Set the Node.js version
- Configure the reverse proxy
- How to manage user system services
- Deploy Medusa


How to set the Node.js version

set node version nodejs_version change node version node.js 24 select node version node runtime turbostack

# How to set the Node.js version

Each application chooses its own **Node.js major version**. Set it when you deploy an app, or when
you move an existing app to a newer runtime.


How to set the Node.js version

Set it in the GUI

1. Open the host and select the application.
2. Go to **Configure application > Technologies > NodeJS**.
3. Choose the version.


How to set the Node.js version

Set it in YAML

Set `nodejs_version` on the application (vhost) to the major version, as a quoted string. This key
on its own installs the runtime. See Configure Node.js for the full set of keys.

```yaml
nodejs_version: "24"
```

Publish the change to apply it.


How to set the Node.js version

Verify and restart

Over SSH, confirm the runtime:

```bash
node -v
```

Then **restart your application** so it runs on the new version - see
Keep a Node.js app running. Long-running Node processes keep using the
old runtime until they are restarted.

> [!TIP]
> Match the version to your app's `engines` field in `package.json`, and test on a staging copy before
> switching a production site.


How to set the Node.js version

Related

- Configure Node.js
- Keep a Node.js app running
- Publishing changes
- What is Node.js?
- Deploy Medusa


What is Node.js?

what is node.js node.js hosting node.js turbostack javascript runtime reverse proxy medusa

# What is Node.js?

Node.js is a server-side runtime that executes JavaScript outside the browser. It is built around an event-driven, non-blocking I/O model, which makes it well suited to network applications such as APIs, real-time services, and modern commerce platforms.

On a hosting platform, a Node.js application runs as a long-lived process that listens on a local port. A web server accepts public HTTPS traffic and forwards requests to that port. Your application code does not handle Transport Layer Security (TLS) or public networking directly.


What is Node.js?

On TurboStack

TurboStack runs Node.js as a per-application runtime. You enable it on an application and pick the major version you want, for example version `24` (or newer). Multiple applications on the same host can run different Node.js versions side by side.

Node.js applications are not exposed to the internet directly. Instead, your app listens on a local port and Nginx acts as a reverse proxy in front of it, terminating TLS and forwarding traffic to your process. This is the same pattern used to run platforms such as Medusa. The Node.js service runs as its own process and Nginx proxies requests to the port it listens on.

Because there is no dedicated `app_type` for generic Node.js apps, you combine the Node.js runtime with the reverse proxy to publish your application.


What is Node.js?

Best practices

- Pin a specific major Node.js version so deployments stay reproducible, and plan upgrades when a version approaches end of life.
- Run your app under a process manager - on TurboStack that is **pm2** (a systemd service is the alternative) - so it restarts on crash and on reboot. See Keep a Node.js app running.
- Have your app listen on a local port only and let Nginx handle public TLS traffic.
- Keep dependencies up to date and audit them regularly for security advisories.
- Use environment variables for secrets and configuration rather than committing them to your repository.


What is Node.js?

Related

- Configure Node.js on TurboStack
- Keep a Node.js app running
- Deploy Medusa


Configure OpenSearch on TurboStack

configure OpenSearch turbostack OpenSearch yaml opensearch_version OpenSearch snapshots opensearch_plugins search plugins opensearch_dashboards OpenSearch Dashboards url

# Configure OpenSearch on TurboStack

Enable OpenSearch and set its version at the host level, then optionally tune the JVM heap and plugins.


Configure OpenSearch on TurboStack

Where to configure it

Open the host, go to the **Services** tab, select **ElasticSearch / OpenSearch**, and choose
**OpenSearch**.


Configure OpenSearch on TurboStack

Required

| Key | Meaning |
| --- | --- |
| `opensearch_version` | OpenSearch version to run (for example, `"2.x"` or `"3.x"`). |


Configure OpenSearch on TurboStack

Optional

| Key | Meaning |
| --- | --- |
| `opensearch_heap_size` | JVM heap size (auto-sized to the host; override only with measured evidence). |
| `opensearch_plugins` | Search-engine plugins to enable. |
| `opensearch_dashboards` | Installs the OpenSearch Dashboards web interface. Off by default. |
| `opensearch_dashboards_usermanagement` | Turns on OpenSearch's own user accounts for the dashboards. |

```yaml
opensearch_version: "2.x"      # required: enable OpenSearch on the host
# opensearch_dashboards: true  # optional: the web interface
```


Configure OpenSearch on TurboStack

Listening address

OpenSearch accepts connections only from the host itself, which is what a single-server setup needs.
If an application on another server has to reach the search engine, ask
Support to open it up to your private network.

> [!WARNING]
> A search engine has no authentication of its own, so anything that can reach the port can read and
> change your indexes. It must never be reachable from the internet.


Configure OpenSearch on TurboStack

Dashboards

`opensearch_dashboards: true` installs the interface, which you then reach at
**`https://<host>/dashboards`**. The web server proxies that path and asks for a user name and
password first; use one of the host's system user accounts, the same credentials you use for SSH.

That login belongs to the web server, not to OpenSearch. Turn on
`opensearch_dashboards_usermanagement` when you need per-user accounts inside the dashboards
instead of one shared door. It is available only in the
Source (YAML) view.


Configure OpenSearch on TurboStack

Plugins

**Plugins** is a multi-select on the Services tab. The list you choose from is maintained by
Hosted Power and changes as engine versions come and go, so check the dropdown for what is
available today.

Two things happen automatically on the next deployment:

- **Removing a plugin from the list uninstalls it.** TurboStack keeps track of the plugins it
  installed and removes only those, so the plugins that ship with OpenSearch itself are left alone.
- **Changing the OpenSearch version reinstalls every plugin**, so each one is installed again for
  the new engine version.

> [!TIP]
> Choose **either** OpenSearch **or** Elasticsearch on a host - not
> both. OpenSearch indices are backed up via nightly snapshots.


Configure OpenSearch on TurboStack

Related

- What is OpenSearch?
- Elasticsearch
- Services


What is OpenSearch?

what is OpenSearch OpenSearch hosting OpenSearch turbostack Elasticsearch alternative open source search

# What is OpenSearch?

OpenSearch is an open-source search and analytics engine - a community-driven fork of
Elasticsearch with a compatible API. It powers the same use cases (full-text product search,
filtering, autocomplete, faceted navigation) and scales across nodes on the JVM.

> [!NOTE]
> OpenSearch and Elasticsearch are alternatives - enable one per host.


What is OpenSearch?

On TurboStack

Enable OpenSearch at the host level and pick a version (`opensearch_version`, e.g. `"2.x"` or `"3.x"`).
TurboStack auto-sizes the JVM heap; you can configure plugins. TurboStack takes **nightly snapshots** of
OpenSearch indices for backup and recovery. Choose OpenSearch when you want a fully open-source
engine.


What is OpenSearch?

Best practices

- Pick OpenSearch or Elasticsearch based on your application's compatibility.
- Keep the heap auto-sized unless you measure memory pressure - see Performance tuning.
- Rely on the nightly snapshots for index recovery; reindex after large data changes.


What is OpenSearch?

Related

- Configure OpenSearch
- Elasticsearch
- Services


Configure PHP on TurboStack

configure php turbostack php yaml php_version php-fpm tuning opcache turbostack

# Configure PHP on TurboStack

Each application chooses its own PHP version and, optionally, its PHP-FPM and
OPcache tuning.


Configure PHP on TurboStack

Where to configure it

PHP is configured per application:

1. Open the application.
2. Go to **Configure application > Technologies > PHP**.
3. Select the PHP version (and adjust advanced settings if needed).

Installed versions and the host default come from the host-level `php_versions`
and `php_main_version` settings.


Configure PHP on TurboStack

Required

| Key | Meaning |
|---|---|
| `php_version` | PHP version for this application/vhost, e.g. `"8.4"`. |


Configure PHP on TurboStack

Optional

A PHP-FPM worker is one PHP process that handles one request at a time, so the number of workers
sets how many PHP requests the application can serve at once.

| Key | Meaning |
|---|---|
| `php_fpm_pm_start_servers` | Number of PHP-FPM worker processes started initially. |
| `php_fpm_pm_min_spare_servers` | Minimum number of idle PHP-FPM workers kept ready. |
| `php_fpm_pm_max_spare_servers` | Maximum number of idle PHP-FPM workers kept ready. |
| `php_fpm_pm_max_children` | The ceiling on workers this application may run at once. Inherited from the host unless you set it here. |
| `php_fpm_pm_max_requests` | How many requests a worker handles before it is restarted. Inherited from the host (`500`) unless you set it here. |
| `php_user_tmp_dir` | Gives the application its own temporary folder instead of the shared one. Off by default. |
| `php_enhance` | Enable OPcache performance enhancements for the site. |
| `php_opcache_preload_script` | Path to a script preloaded into OPcache at startup. |
| `php_ioncube_enabled` | Enable the ionCube loader (for ionCube-encoded apps). |
| `php_versions` | Host-level: PHP versions installed on the host. |
| `php_main_version` | Host-level: default PHP version for the host. |

```yaml
# Per-application
php_version: "8.4"

# Optional PHP-FPM tuning
php_fpm_pm_start_servers: 5
php_fpm_pm_min_spare_servers: 3
php_fpm_pm_max_spare_servers: 6
# php_fpm_pm_max_children: 40      # ceiling on concurrent workers
# php_fpm_pm_max_requests: 500     # restart a worker after this many requests
# php_user_tmp_dir: true           # a private tmp folder for this application

# Optional OPcache + ionCube
php_enhance: true
php_opcache_preload_script: "/var/www/prod/preload.php"
php_ioncube_enabled: false

# Host-level
php_versions:
  - "8.3"
  - "8.4"
php_main_version: "8.4"
```

> [!NOTE]
> Each application runs in its own PHP-FPM pool, so `php_version` and the PHP-FPM tuning
> keys apply independently per site. Set `php_versions` at the host before a
> application can select that version.


Configure PHP on TurboStack

Worker ceiling and recycling

`php_fpm_pm_max_children` is the hard limit on how many requests this application can process at
the same time. Every worker holds its own memory, so the ceiling multiplied by the memory a request
uses is the worst case for this application. Set it too high and a traffic peak pushes the host out
of memory; set it too low and requests queue and time out. See
Out of memory and
Performance tuning.

`php_fpm_pm_max_requests` restarts a worker after that many requests. Restarting reclaims whatever
the process leaked, which keeps a slowly growing application stable without a scheduled restart.

Both are inherited from the host when you leave them out, so set them per application only when
one site needs to differ from the rest.


Configure PHP on TurboStack

A private temporary folder

With `php_user_tmp_dir: true` the application gets its own `tmp` folder under its home directory,
owned by its own user, and PHP's `sys_temp_dir` points at it. Without it, applications share the
system temporary folder. Turn it on when several applications run on one host and you do not want
uploads, sessions or generated files landing in a place another application can read.


Configure PHP on TurboStack

Common tasks

- Switch PHP version
- Override PHP settings
- Flush the OPcache


Configure PHP on TurboStack

Related

- What is PHP?
- Applications: Technologies
- Applications overview
- TurboStack CLI - clear OPcache (`tscli opcache clear`) and manage Blackfire


How to flush the PHP OPcache

flush opcache clear opcache tscli opcache clear php opcache reset recompile php deploy php code validate_timestamps opcache preload

# How to flush the PHP OPcache

PHP's **OPcache** stores compiled PHP as bytecode in memory so it does not recompile your code on
every request. That speeds up the site, but it also means that after you change PHP files the cache
can keep serving the **old** code until it is refreshed.


How to flush the PHP OPcache

Flush it with the TurboStack CLI

Connect over SSH and run:

```bash
tscli opcache clear
```

This resets the OPcache for the site's PHP-FPM, so the next requests recompile from your current
files.


How to flush the PHP OPcache

When you need it

- After deploying or editing PHP files **outside** the normal publish flow, when your changes do not
  show up.
- On sites tuned for production, where OPcache does not re-check file timestamps on every request
  (`validate_timestamps` off) for maximum performance - there, a flush is required to pick up new
  code.

> [!NOTE]
> Right after a flush the first requests are a little slower while PHP recompiles; this settles within
> moments. If you use OPcache **preloading** (`php_opcache_preload_script`), changing the preloaded
> code needs a PHP-FPM reload, not just a cache flush - see Configure PHP.


How to flush the PHP OPcache

Related

- Configure PHP
- Switch PHP version
- Override PHP settings
- Why is my site slow?
- TurboStack CLI - `tscli opcache clear`


How to override PHP settings

override php settings php.ini user.ini memory_limit upload_max_filesize max_execution_time

# How to override PHP settings

You can override most runtime `php.ini` values - such as `memory_limit`, `max_execution_time` and
the upload size limits - per application, without root access. To choose the PHP **version** or tune
PHP-FPM, see Configure PHP instead.


How to override PHP settings

Override per application with a `.user.ini` file

Create a `.user.ini` file in your application's document root (for example `public_html`) and add one
setting per line:

```ini
memory_limit = 512M
max_execution_time = 300
post_max_size = 600M
upload_max_filesize = 512M
```

Most settings that PHP allows to be changed at the directory level can be overridden this way.

> [!NOTE]
> PHP re-reads `.user.ini` only periodically - by default about every **5 minutes** - so a change is
> not always instant. Allow a few minutes before you test the result.


How to override PHP settings

Override for the command line

A `.user.ini` file applies to web requests only. For a one-off command-line run, pass the value with
`-d`:

```bash
php -d memory_limit=512M your-script.php
```


How to override PHP settings

Application-specific exceptions

Some applications set their own PHP values that take precedence over `.user.ini` for web requests.
Magento, for example, enforces limits through a `PHP_VALUE` line in its generated `50main.conf`
(see Custom Nginx configuration):

```nginx
fastcgi_param PHP_VALUE "memory_limit=2048M \n max_execution_time=18000";
```

If a `.user.ini` change has no effect on such a site, look for an override like this first.


How to override PHP settings

Verify

Confirm the value actually applied with a temporary `phpinfo()` page:

```php
<?php phpinfo();
```

Open it in your browser, search for the setting, then **delete the file** - never leave a
`phpinfo()` page on a live site.


How to override PHP settings

Related

- Configure PHP
- Switch PHP version
- Fixing 413 errors
- Custom Nginx configuration


How to switch PHP version

switch php version change php version php_version php 8.4 select php version php versions turbostack php-fpm pool

# How to switch PHP version

Each application on TurboStack runs its own PHP version in its own PHP-FPM pool, so you can change one
application's version without affecting the others. TurboStack supports a range of versions - for
example `8.4`, `8.3` and `8.2`. Older versions can still be installed if your application needs them,
but they may no longer receive security updates. The version dropdown lists the versions available now.


How to switch PHP version

Switch it in the GUI

1. Open the host and select the application.
2. Go to **Configure application > Technologies > PHP**.
3. Choose the version and save.


How to switch PHP version

Switch it in YAML

Set `php_version` on the application (vhost). The version must be installed on the host - it is listed in
the host-level `php_versions`, with `php_main_version` as the host default. See
The Source (YAML) view.

```yaml
php_version: "8.4"
```

Publish the change to apply it.


How to switch PHP version

Verify the active version

- **Web:** open a temporary `phpinfo()` page (see Override PHP settings)
  and check the version at the top, then delete the file.
- **Command line:** each installed version also has its own binary at `/usr/bin/php<version>`
  (for example `/usr/bin/php8.4 -v`). The default `php` on the command line may differ from
  the application's version.

> [!WARNING]
> Test your application against the new version on a staging copy before switching a production site -
> a major PHP jump can break incompatible code or extensions.


How to switch PHP version

Related

- Configure PHP
- Override PHP settings
- Flush the PHP OPcache
- Publishing changes
- Applications


What is PHP?

what is php php hosting php turbostack php-fpm php version hosting

# What is PHP?

PHP is a server-side scripting language used by platforms such as WordPress,
Magento, Drupal, Laravel and Symfony. It runs on the server to generate the
pages and API responses your visitors receive.

On a modern stack, PHP runs through **PHP-FPM** (FastCGI Process Manager), a pool
of worker processes that the web server hands dynamic requests to. The PHP
version and pool tuning directly affect both compatibility with your app and the
performance under load.


What is PHP?

On TurboStack

TurboStack runs PHP as a per-application runtime. Multiple PHP versions can run
side by side on the same host.

- Each application picks its own PHP version via `php_version` (for example
  `"8.4"`), so different sites on one host can run different versions.
- Each application runs in its own PHP-FPM pool, isolating its workers, tuning
  and resource usage from other sites.
- At the host level, `php_versions` lists the PHP versions installed and
  `php_main_version` sets the default.
- Optional per-application tuning covers **PHP-FPM process management**, **OPcache**
  (including preloading) and **ionCube** support - see
  Configure PHP.

> [!TIP]
> We recommend **PHP 8.4** (or newer), or the highest version your application
> officially supports. Newer PHP versions are faster and receive security
> updates for longer.


What is PHP?

Best practices

- Run the newest PHP version your application supports; keep an upgrade path in
  mind for older sites.
- Set `php_version` explicitly per application rather than relying on the host
  default, so upgrades are deliberate.
- Enable OPcache for production sites, and consider OPcache preloading for
  frameworks that benefit from it.
- Tune PHP-FPM process manager values to match each site's traffic instead of
  using one profile for everything.
- Test version upgrades on a copy of the site before changing production.


What is PHP?

Related

- Configure PHP on TurboStack
- Applications: Technologies


Configure PostgreSQL on TurboStack

configure postgresql turbostack postgresql yaml postgresql_version postgresql_shared_buffers postgresql_listen_addresses percona postgresql

# Configure PostgreSQL on TurboStack

Enable PostgreSQL on a host, choose a version, and let TurboStack auto-tune sizing for apps like Odoo and Medusa.


Configure PostgreSQL on TurboStack

Where to configure it

PostgreSQL is a host-level service. Open the host, go to its **Services** tab, and select **PostgreSQL**. Enable it and pick the major version. Saving updates the host YAML and provisions Percona PostgreSQL on that host.


Configure PostgreSQL on TurboStack

Required

| Key | Meaning |
|---|---|
| `postgresql_version` | The PostgreSQL major version to install, for example `"17"` (or newer). |


Configure PostgreSQL on TurboStack

Optional

| Key | Meaning |
|---|---|
| `postgresql_shared_buffers` | Memory used for caching. Auto-tuned to the server by default - override only with measured evidence. |
| `postgresql_listen_addresses` | The addresses PostgreSQL listens on, or `ANY` for every interface. Security-sensitive: keep it on localhost unless remote access is required. |
| `postgresql_extra_access` | A list of host-based access rules for specific networks or hosts. Each entry is a mapping with `type` (for example `host`), `database`, `user`, `address` (a network range or host) and `auth_method` (for example `scram-sha-256`). |
| `postgresql_extensions` | Extra extensions to install. Only `vector`, `postgis`, `timescaledb` and `pg_stat_statements` are accepted; any other name stops the deployment. |

```yaml
postgresql_version: "17"

# Optional overrides
postgresql_shared_buffers: "2GB"          # leave unset to keep auto-tuning
postgresql_listen_addresses: "localhost"  # widen only when needed
postgresql_extra_access:
  - type: host
    database: all
    user: gitlab_db
    address: 10.0.0.0/8
    auth_method: scram-sha-256
```


Configure PostgreSQL on TurboStack

Listening address

`postgresql_listen_addresses` takes an address, or the keyword **`ANY`**, which makes PostgreSQL
listen on every interface the server has.

> [!WARNING]
> `ANY` includes any public interface. A database reachable from the internet is a serious risk, so
> prefer a specific private address, and restrict access with the
> firewall whatever you choose. Widening the listen address is only half
> the job: a client also needs a matching rule in `postgresql_extra_access`.

> [!IMPORTANT]
> On a host that runs **Kubernetes or Docker**, PostgreSQL listens on every interface unless you set
> `postgresql_listen_addresses` yourself. If that is not what you want, set the address explicitly.

> [!WARNING]
> A major-version change requires a migration and is not a simple in-place switch. Back up first and test before applying it in production.


Configure PostgreSQL on TurboStack

Common tasks

- import and export a PostgreSQL database
- connect to your PostgreSQL database remotely
- create and manage PostgreSQL users


Configure PostgreSQL on TurboStack

Related

- What is PostgreSQL?
- Services
- Deploy Odoo


remote postgresql postgres ssh tunnel connect postgres client pgadmin

# How to connect to your PostgreSQL database remotely

Connect a database client on your own computer (for example pgAdmin, DBeaver or `psql`) to a
PostgreSQL database on your host. The recommended, secure way is an SSH tunnel.


Why the database port is not open by default

For security, PostgreSQL listens on `localhost` only (`postgresql_listen_addresses: "localhost"`), so
the database port is not reachable from the internet. Rather than exposing it, you forward it over
your existing SSH access - the connection is encrypted and uses your SSH key.


Connect over an SSH tunnel (recommended)

1. Open a tunnel from a local port (here `5433`) to the database on the host:
   ```bash
   ssh -L 5433:127.0.0.1:5432 prod@web1.example.com
   ```
   Leave this session open while you work.
2. Point your client at the local end of the tunnel:

   | Setting | Value |
   | --- | --- |
   | Host | `127.0.0.1` |
   | Port | `5433` |
   | User (role) | your database role (from Credentials) |
   | Password | the role's password |
   | Database | your database name, for example `prod_db` |

pgAdmin and DBeaver can also create the SSH tunnel for you - set the SSH host and key, then set the
database host to `127.0.0.1`.


Opening the port instead (advanced)

If a tool genuinely cannot tunnel, you can widen access - but this exposes the database, so prefer the
tunnel.

- Widen `postgresql_listen_addresses` and add host-based rules with `postgresql_extra_access` for the
  specific networks or hosts that need it (see Configure PostgreSQL).
- Also allow the exact source IP addresses on the host's **Security** tab
  (Security).
- Connect with a least-privilege role, never the application's main role.

> [!WARNING]
> Never open the database broadly. Grant access only to specific, trusted hosts, and use a dedicated
> limited role.


Troubleshooting

- **Connection refused** - the tunnel is not open, or the client is pointing at the host instead of
  `127.0.0.1`.
- **Authentication failed** - wrong role/password, or no matching host-based access rule (see
  Create and manage PostgreSQL users).
- **Times out when opening access directly** - the source host is not allowed, or
  `postgresql_listen_addresses` is still local. See
  Database problems.


Related

- Configure PostgreSQL
- Create and manage PostgreSQL users
- Import and export a database
- SSH access
- Host Security tab


import postgresql export postgresql pg_dump psql pg_restore backup postgres gzip scp

# How to import and export a PostgreSQL database

We always recommend to dump and import through the command line, if possible. This documentation will
explain how to do this securely.


PostgreSQL export

For most databases (only a couple of gigabytes big), you can dump the database with this command:

```bash
pg_dump -U DBUsername DatabaseName > DBNAME.sql
```

For larger databases (tens of gigabytes or bigger), compress the database to conserve disk space and
speed up transfer:

```bash
pg_dump -U DBUsername DatabaseName | gzip -3 -v > test.gz
```

> [!NOTE]
> As an alternative, you can dump to the compressed custom format instead of piping through `gzip`.
> A custom-format dump restores faster and lets you restore selectively with `pg_restore`:
>
> ```bash
> pg_dump -U DBUsername -Fc DatabaseName > DBNAME.dump
> ```


Transferring the database

Use `scp` to transfer the file:

```bash
scp FileName user@HostnameOrIP:Path/To/Folder
```

> [!NOTE]
> To place the file in the user's home directory, remove everything after the colon.


Importing the database

```bash
psql -U DBUsername DatabaseName < dbname
```

Or, if compressed:

```bash
gunzip -c dbname.gz | psql -U DBUsername DatabaseName
```

> [!NOTE]
> If you dumped to the custom format, restore it with `pg_restore` instead:
>
> ```bash
> pg_restore -U DBUsername -d DatabaseName DBNAME.dump
> ```

> [!NOTE]
> Large databases can take time to import, especially on high-load servers.


Nohup

Use `nohup` to ensure the dump or import continues if the connection is lost.


Screen

Use `screen` to allow session sharing or recovery:

- Create a session:

  ```bash
  screen -S <session_name>
  ```

- Disconnect (keep running):

  ```
  Ctrl + A, then D
  ```

- Reattach or take over session:

  ```bash
  screen -dr <session_name>
  ```

- List sessions:

  ```bash
  screen -ls
  ```


SSH key

Avoid password prompts by setting up SSH key authentication.


Related

- Configure PostgreSQL
- Create and manage PostgreSQL users
- Backups and restore
- SSH access
- Database problems


create postgresql user postgresql role grant privileges database permissions least privilege

# How to create and manage PostgreSQL users

Create additional PostgreSQL users (called **roles**) with only the access they need - for example a
read-only role for reporting, or a separate role per application. Your application already has a main
role; add extra roles rather than sharing it.


The TurboStack way: extra database users

The simplest option is to let TurboStack manage the user for you:

1. Open the application's **Configure application** dialog and go to the **Database Info** tab
   (Applications).
2. Add an **extra database user** and choose its role - **read-only** or **admin**.
3. Publish the host. TurboStack creates the role and shows its credentials on the
   Credentials tab.

Use this for the common cases; it keeps the role in your configuration and recreates it consistently.


Create a role by hand (SQL)

For finer-grained grants, connect over SSH and run SQL with `psql`.
Grant only what the role needs.

A read-only role on one database:

```sql
CREATE ROLE prod_readonly LOGIN PASSWORD 'a-strong-password';
GRANT CONNECT ON DATABASE prod_db TO prod_readonly;
\c prod_db
GRANT USAGE ON SCHEMA public TO prod_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO prod_readonly;
-- also cover tables created later:
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO prod_readonly;
```

A role with full access to a single application database:

```sql
CREATE ROLE prod_app LOGIN PASSWORD 'a-strong-password';
GRANT ALL PRIVILEGES ON DATABASE prod_db TO prod_app;
```

> [!TIP]
> Grant on the specific database and schema, not cluster-wide. Do not make application roles
> `SUPERUSER` or give them `CREATEROLE`.

For a role to connect remotely, it also needs a host-based access rule - see `postgresql_extra_access`
in Configure PostgreSQL and Connect remotely.


Rotate a password

```sql
ALTER ROLE prod_readonly PASSWORD 'a-new-strong-password';
```

Update the password wherever the role is configured (the application, or your client) at the same time.


Verify access

```sql
\du prod_readonly
```

Then connect as that role and confirm it can do what it should - and nothing more.


Related

- Configure PostgreSQL
- Import and export a PostgreSQL database
- Connect to your database remotely
- Credentials
- Applications
</content>


What is PostgreSQL?

what is postgresql postgresql hosting postgresql turbostack percona postgresql relational database odoo database medusa database

# What is PostgreSQL?

PostgreSQL is a standards-compliant open-source relational database known for reliability, data integrity, and a broad feature set. It stores data in tables queried with SQL and supports rich data types, transactions, and extensions.

It is the preferred database for applications such as Odoo and Medusa, where transactional correctness and advanced querying matter.


What is PostgreSQL?

On TurboStack

TurboStack runs **Percona PostgreSQL**, a drop-in, performance-focused build of PostgreSQL, as a host-level service. You enable it on a host and pick the major version (for example `17`).

Memory sizing is auto-tuned to the server's resources. In particular, the `shared_buffers` setting, which controls how much memory PostgreSQL uses for caching, is set automatically. You generally do not need to tune it manually. Applications that need PostgreSQL, such as Odoo, connect to the managed instance on the host.


What is PostgreSQL?

Best practices

- Stay on a current, supported major version and plan major upgrades, which require a migration step.
- Leave `shared_buffers` and other sizing auto-tuned unless you have measured evidence to change it.
- Keep the database listening on localhost; only widen access when an application or host genuinely needs it.
- Use the extra-access mechanism to grant specific networks or hosts rather than opening the database broadly.
- Take regular backups and verify restores, especially before a major-version upgrade.
- Add indexes for frequent queries and run `VACUUM`/`ANALYZE` (autovacuum handles most of this) to keep performance healthy.


What is PostgreSQL?

Related

- Configure PostgreSQL on TurboStack
- Services


Configure Python on TurboStack

configure python turbostack python yaml python_version reverse proxy odoo

# Configure Python on TurboStack

Enable the Python runtime on an application and choose the version your application needs.


Configure Python on TurboStack

Where to configure it

The Python runtime is configured per application. In the TurboStack Platform, open an application and go to **Configure application > Technologies > Python**. From there you enable Python and select the version.

Python applications are usually published with the Nginx reverse proxy: your app listens on a local port and Nginx forwards public traffic to it. See Configure the reverse proxy for that part. If you are running Odoo, provision it through its dedicated app type instead - see Deploy Odoo.


Configure Python on TurboStack

Required

| Key | Meaning |
| --- | --- |
| `python_version` | The Python major version to install, for example `"3.12"` (or newer). Setting this key is what enables the Python runtime for the application; there is no separate enable key. |

```yaml
python_version: "3.12"
```


Configure Python on TurboStack

Related

- What is Python?
- Configure the reverse proxy
- Applications overview


What is Python?

what is python python hosting python turbostack python runtime odoo reverse proxy

# What is Python?

Python is a popular, general-purpose programming language known for its readable syntax and large ecosystem. It is widely used for web applications, APIs, data processing, automation, and business platforms.

On a hosting platform, a Python web application typically runs as a long-lived process served by an application server. A web server in front of it accepts public HTTPS traffic and forwards requests to that process. Your code does not deal with Transport Layer Security (TLS) or public networking directly.


What is Python?

On TurboStack

TurboStack provides Python as a per-application runtime. You enable it on an application and select the version your application needs. Different applications on the same host can run different Python versions independently.

Most Python applications run as their own process and are published through Nginx acting as a reverse proxy. Your app listens on a local port and Nginx terminates TLS and forwards traffic to it.

Odoo is a special case. It is a Python-based ERP and business suite provisioned through its dedicated `app_type: odoo`. The platform manages its runtime and services, so you do not use the generic reverse-proxy pattern.


What is Python?

Best practices

- Pin a specific Python version so deployments are reproducible, and plan upgrades before a version reaches end of life.
- Run your application inside a virtual environment to isolate its dependencies.
- Serve your app with a production application server and let Nginx handle public TLS traffic.
- Manage the process with a service manager so it restarts on failure and after reboots.
- Store secrets and configuration in environment variables rather than in your codebase.


What is Python?

Related

- Configure Python on TurboStack
- Deploy Odoo


Configure RabbitMQ on TurboStack

configure RabbitMQ turbostack RabbitMQ yaml rabbitmq_enabled RabbitMQ version RabbitMQ plugins

# Configure RabbitMQ on TurboStack

Enable RabbitMQ for an application and, where needed, tune the broker version and
plugins at the host level.


Configure RabbitMQ on TurboStack

Where to configure it

RabbitMQ is enabled per application. Open the application, go to **Configure
application > Technologies > RabbitMQ**, and turn it on.

Broker-level options live with the host. Open the host and go to the **Advanced >
RabbitMQ Options** tab to set any plugins. The RabbitMQ version (`rabbitmq_version`)
is not a field there - set it via the **Source (YAML)** view.


Configure RabbitMQ on TurboStack

Required

| Key | Meaning |
| --- | --- |
| `rabbitmq_enabled` | Enables RabbitMQ for the application (`true`). |


Configure RabbitMQ on TurboStack

Optional

There are no optional YAML keys for the application. RabbitMQ **plugins** (`rabbitmq_plugins`) are selected in the GUI under host **Advanced > RabbitMQ Options**; the **version** (`rabbitmq_version`) is set via the host's **Source (YAML)** view.

The management interface is always enabled, so you never have to add it to the list yourself. Removing a plugin from the list disables it again on the next deployment.

```yaml
# Per-application application configuration
rabbitmq_enabled: true
```

> [!TIP]
> The version and plugins are host-level advanced settings shared by the
> applications on that host. Only enable the plugins your application needs.


Configure RabbitMQ on TurboStack

Related

- What is RabbitMQ?
- Host Advanced tab
- Applications overview


What is RabbitMQ?

what is RabbitMQ RabbitMQ hosting RabbitMQ turbostack amqp message broker RabbitMQ message queue

# What is RabbitMQ?

RabbitMQ is a message broker that lets parts of an application communicate
asynchronously. Instead of doing slow work inside a web request, an application
publishes a message to a queue and a separate worker process consumes it later.
This keeps the user-facing site responsive while heavier jobs run in the
background.

RabbitMQ speaks the AMQP (Advanced Message Queuing Protocol) standard. It is
widely used for offloading tasks such as sending emails, processing imports,
rebuilding indexes, and any other work that should not block the main
application. Producers, queues, and consumers are decoupled, so each side can
scale and fail independently.


What is RabbitMQ?

On TurboStack

RabbitMQ is provided as an application technology that you enable per application,
with broker-level options managed at the host.

- You turn RabbitMQ on for an application by enabling it in the application
  configuration. TurboStack then provisions and manages the broker for you.
- The RabbitMQ version and any plugins are set as host-level advanced
  options, so the broker is kept consistent for the applications that use it.
- RabbitMQ is the message queue behind OroCommerce, which relies on a message
  queue to process background jobs. When you deploy OroCommerce, enable RabbitMQ
  so its consumers have a broker to connect to.

> [!NOTE]
> RabbitMQ runs background work. You still need a worker or consumer process
> (for example, OroCommerce's message-queue consumers) actually draining the
> queues, otherwise messages simply accumulate.


What is RabbitMQ?

Best practices

- Enable RabbitMQ only for applications that genuinely use a message queue, to avoid
  running an idle broker.
- Keep consumers running and monitored so queues are drained continuously rather
  than backing up.
- Watch queue depth - a growing backlog usually means too few consumers or a
  stuck worker.
- Make message handlers idempotent, meaning handling the same message twice has the
  same result as handling it once, so a redelivered message does not cause
  duplicate side effects.
- Pin a known-good RabbitMQ version per host and only add the plugins your
  application actually needs.


What is RabbitMQ?

Related

- Configure RabbitMQ on TurboStack
- Deploy OroCommerce


How to clear the Redis cache

clear Redis cache flush Redis redis-cli flushall reset cache redis flushdb

# How to clear the Redis cache

Clear the Redis cache when cached data has gone stale - for example after a deploy, a configuration
change, or while troubleshooting. TurboStack runs two Redis instances, so it
matters which one you clear: the **cache** instance (`6379`) holds throwaway data, while the
**persistent** instance (`6378`) holds sessions and queues you do not want to lose.


How to clear the Redis cache

Clear the cache with the TurboStack CLI

`tscli redis clear` is the usual way. It runs `redis-cli flushall` against the **cache instance
(6379)**, clearing all of its databases. The **persistent instance (6378) is left untouched**, so
sessions and queued jobs survive.

```bash
tscli redis clear
```

Expect a short performance dip while the cache fills again.

> [!NOTE]
> This flushes *all* databases on the cache instance, so every application that caches on `6379` has its
> cache cleared - not just one. To clear a single site, use a targeted command below or your
> application's own cache flush.


How to clear the Redis cache

Clear a single database or the persistent instance

For finer control, use `redis-cli` directly (it connects to the cache instance on `6379` by default):

```bash
redis-cli -n 1 FLUSHDB        # clear only database 1 on the cache instance (6379)
redis-cli -p 6378 flushall    # clear the persistent instance - drops sessions and queues
```

> [!WARNING]
> The persistent instance (`6378`) holds sessions and queues. Clearing it logs users out and drops
> queued jobs - only do this deliberately.


How to clear the Redis cache

Prefer your application's own flush

When you only need to clear one application's cache, its own command is safest because it touches
just that application's keys. For example, Magento:

```bash
php bin/magento cache:flush
```


How to clear the Redis cache

After clearing

The cache rebuilds on the next requests, so the first hits are slower and load is briefly higher.
Warm the important pages by visiting them, or let your sitemap or a crawler do it, before judging the
result.


How to clear the Redis cache

Related

- Use Redis for sessions and cache
- Configure Redis
- Inspect Redis with Redis Insight
- TurboStack CLI
- Performance tuning


Configure Redis on TurboStack

configure Redis turbostack Redis yaml redis_enabled redis_memory Redis cache port

# Configure Redis on TurboStack

Redis is enabled by default; you can confirm it and, if needed, adjust its memory per host.


Configure Redis on TurboStack

Where to configure it

Redis is a host-level service. Open the host, go to its **Services** tab, and find the **Redis**
entry. From there you can confirm it is enabled and adjust its settings. Changes are written to the
host's YAML and applied on the next deployment.

By convention TurboStack runs two instances on the host: port `6379` for transient cache data and
port `6378` for persistent data such as sessions and queues.

> [!TIP]
> Memory is auto-sized to the host. Only set a value when you have a measured reason to override it.


Configure Redis on TurboStack

Required

| Key | Meaning |
|---|---|
| `redis_enabled` | Whether Redis runs on the host. Enabled (`true`) by default. |


Configure Redis on TurboStack

Optional

| Key | Meaning |
|---|---|
| `redis_memory` | Maximum memory for the cache instance (port `6379`). Auto-sized by default; set only to override. |
| `redis_persistent_memory` | Maximum memory for the persistent instance (port `6378`), the one that keeps its data on disk. Auto-sized by default. |
| `redis_listen_addresses` | Which addresses Redis accepts connections on. Local only unless you set it. |

```yaml
redis_enabled: true
# Optional - overrides the automatic memory sizing:
redis_memory: "512mb"
# Optional - reachable from the private network instead of localhost only:
# redis_listen_addresses: internal
```


Configure Redis on TurboStack

Listening address

Leave `redis_listen_addresses` unset and Redis stays on localhost. Set it to `internal` when
another server on the private network must reach the cache: that binds the loopback addresses plus
the host's private IPv4 addresses. `internal` is the **only** accepted value - anything else,
including `any`, stops the deployment with an error.

> [!WARNING]
> Setting `internal` also turns off the Redis protected mode. Redis has no password by default, so
> anything that can reach the port can read and delete your data. Only use it on a trusted private
> network, never with a public address.

> [!IMPORTANT]
> On a host that runs **Kubernetes or Docker**, Redis uses `internal` unless you set
> `redis_listen_addresses` yourself, and protected mode is off on such a host either way.

> [!NOTE]
> The two-instance split (6379 cache, 6378 persistent) is a TurboStack convention. Make sure your
> application connects transient cache traffic to 6379 and durable data to 6378. For the local socket
> paths and how to give each application its own database, see
> Use Redis for sessions and cache.


Configure Redis on TurboStack

Common tasks

- clear the Redis cache
- use Redis for sessions and cache
- inspect Redis with Redis Insight


Configure Redis on TurboStack

Related

- What is Redis?
- Host Services
- Performance tuning
- TurboStack CLI - clear the cache with `tscli redis clear`


How to inspect Redis with Redis Insight

redis insight redis memory analyze redis redis gui redis keyspace

# How to inspect Redis with Redis Insight

Redis Insight is a free desktop tool for browsing Redis and analyzing what uses memory - useful when
a cache is large or you are chasing memory pressure. You
connect to your host's Redis over a secure Secure Shell (SSH) tunnel.


How to inspect Redis with Redis Insight

Before you start

- **SSH access** and your system-user credentials from the host's
  Credentials tab.
- No Redis password is needed. Access is secured by the SSH tunnel and by Redis binding to
  localhost, so leave the password field empty.


How to inspect Redis with Redis Insight

Connect

1. In Redis Insight, select **Add Redis Database**.
2. Enter the connection details:
   - **Host:** `127.0.0.1` and **Port:** `6379` (the cache instance) or `6378` (the persistent
     instance).
   - Under **Security**, enable **Use SSH Tunnel**: SSH host = your server, **port 22**, and your
     system-user name and password.
3. Open the database. Pick the logical database to analyze (the default is `0`); you can list them
   over SSH with:
   ```bash
   redis-cli info keyspace
   ```


How to inspect Redis with Redis Insight

Which instance and database

TurboStack runs two Redis instances. Connect to the one that holds the data you want to inspect:

| Instance | Port | Holds |
| --- | --- | --- |
| Cache | `6379` | Temporary cache; cleared by `tscli redis clear` |
| Persistent | `6378` | Sessions and data that must survive a restart |

Each instance has 16 logical databases, numbered `0` to `15`. When a host runs several sites, each
site often uses its own database. Use the keyspace list above to find the database with the keys you
want.


How to inspect Redis with Redis Insight

Analyze memory use

Browse keys to see their types and time-to-live (TTL), then use the **Analysis** tool in the left
menu to generate a report. The report shows:

- Total memory used and the total number of keys.
- The largest keys, sortable by TTL, so you can see what is worth caching differently.
- The most used key types and how much memory each type takes.
- The memory split between expiring and non-expiring keys.

Use this to decide what to cache differently, or whether to raise `redis_memory` - see
Performance tuning.


How to inspect Redis with Redis Insight

Related

- What is Redis?
- Configure Redis
- Out of memory
- Performance tuning


How to use Redis for sessions and cache

Redis sessions Redis cache session storage Redis databases persistent Redis

# How to use Redis for sessions and cache

TurboStack runs **two Redis instances** on each host so you can keep throwaway cache data apart from
data you cannot afford to lose, such as logged-in sessions and queued jobs. Pointing each kind of
data at the right instance keeps your site fast and avoids logging users out when the cache is
cleared.


How to use Redis for sessions and cache

The two instances

| Instance | Port | Local socket | Use it for | Safe to clear? |
| --- | --- | --- | --- | --- |
| Cache | `6379` | `/var/run/redis/redis.sock` | Page, object and other transient cache | Yes - it is rebuilt on demand |
| Persistent | `6378` | `/var/run/redis-persistent/redis.sock` | Sessions, queues and other durable data | No - clearing it logs users out and drops queued jobs |

Send transient cache traffic to **6379** and durable data to **6378**. Most application types on
TurboStack are already wired up this way; only change it if you configure Redis by hand.


How to use Redis for sessions and cache

Connect over the local socket

When your application runs on the same host as Redis, connect over the **Unix socket** instead of
`127.0.0.1:<port>`. A socket has less overhead than a network connection, which lowers latency and
processor use under load. Use the socket paths from the table above.


How to use Redis for sessions and cache

Give each application its own database

Redis provides **16 logical databases**, numbered `0` to `15`. When several applications share a host,
give each one its own database number (for example application A on `1`, application B on `2`) so they never
read or overwrite each other's keys.


How to use Redis for sessions and cache

Don't clear the persistent store casually

Clearing the **6379** cache is harmless - it simply rebuilds. Clearing the **6378** persistent
instance is not: it drops sessions (logging everyone out) and any queued jobs. The standard
clear the cache command (`tscli redis clear`) already targets the cache
instance (6379), so it is safe; only reach for the persistent instance deliberately.


How to use Redis for sessions and cache

Set a TTL and expiry

By default Redis does not assign a Time-To-Live (TTL) to a key unless you set one. Giving
transient keys an expiry keeps memory usage in check and stops the cache from filling up.

Set a TTL when you write a key - for example one hour:

```bash
SET key value EX 3600
```

As a general guide:

- **Cache keys** - set a TTL matching how long the data stays fresh (for example API
  responses or HTML fragments).
- **Sessions** - use a longer TTL, around **24 hours**.
- **Critical data** - do **not** set a TTL for data that must persist.


How to use Redis for sessions and cache

Verify data is being cached

After wiring up Redis, check that keys are actually being written. Connect with `redis-cli`
and list the keys:

```bash
redis-cli
127.0.0.1:6379> keys *
(empty array)
```

An empty array means nothing has been cached yet - expected right after a clear. Click
around your site, then run `keys *` again. If it stays empty, the application is not writing
to Redis and the integration needs checking.


How to use Redis for sessions and cache

Related

- Configure Redis
- Clear the Redis cache
- Inspect Redis with Redis Insight
- Performance tuning


What is Redis?

what is Redis Redis hosting Redis turbostack in-memory cache Redis sessions

# What is Redis?

Redis is an in-memory data store. Because it keeps data in RAM, it answers reads and writes
with very low latency, which makes it well suited to caching, session storage, rate limiting, and
lightweight message queues. It supports rich data types - strings, hashes, lists, sets, and more -
so applications use it for far more than simple key/value caching.

Caches are transient by nature: data in a cache can be regenerated from the source of truth, so it
is safe to clear. Other Redis uses, such as user sessions or job queues, need their data to survive
restarts. TurboStack handles both needs by running two separate instances.


What is Redis?

On TurboStack

TurboStack runs Redis by convention as two instances on each host so that disposable cache
data and durable data never share the same store:

- **Port 6379 - cache.** Transient data only. Safe to clear at any time; nothing important is lost.
- **Port 6378 - persistent.** Durable data such as sessions and queues, intended to survive
  restarts.

Redis is enabled by default. Its maximum memory is auto-sized to the host, so you normally
do not need to tune it. See Performance tuning for
guidance on sizing.

> [!TIP]
> Point throwaway cache traffic at port **6379** and anything you must not lose at port **6378**.


What is Redis?

Best practices

- Send only regenerable cache data to the 6379 instance; never store data there you cannot rebuild.
- Use the persistent 6378 instance for sessions, queues, and other durable state.
- Let memory auto-sizing do its job; only override it for a measured, specific need.
- Set sensible key expirations so the cache stays within its memory budget.
- Restrict access so only the applications on the host can reach the instances.


What is Redis?

Related

- Configure Redis on TurboStack
- Performance tuning


configure reverse proxy turbostack reverse proxy yaml proxy upstream port nginx proxy turbostack

# Configure the reverse proxy on TurboStack

Enabling the reverse proxy tells Nginx to forward an application's requests to your
application's upstream port instead of serving PHP or static files.


Where to configure it

The reverse proxy is enabled per application:

1. Open the host and select the application.
2. Go to **Configure application > Technologies > Reverse Proxy**.
3. Enable the reverse proxy and set the **upstream port** your application
   listens on.

TurboStack generates the Nginx vhost from there - there is no raw proxy config
to write by hand.


Required

| Key | Meaning |
|---|---|
| `proxy_enabled` | Set to `true` to forward this application's requests to a backend upstream. |
| `proxy_upstream_port` | The port your application listens on, where Nginx forwards requests. |


Optional

| Key | Meaning |
|---|---|
| `proxy_upstream_host` | The host Nginx forwards to. Defaults to `127.0.0.1` (loopback). |

```yaml
# Per-application: forward requests to a backend app on port 3000
proxy_enabled: true
proxy_upstream_port: 3000
proxy_upstream_host: 127.0.0.1   # optional, this is the default
```

> [!TIP]
> Keep `proxy_upstream_host` at `127.0.0.1` so your application is reachable only
> through Nginx. For containerized apps, combine this with
> Docker and point the upstream port at the
> container's exposed port.


Related

- What is a reverse proxy?
- Applications tab
- Applications overview


What is a reverse proxy?

what is reverse proxy reverse proxy hosting reverse proxy turbostack nginx reverse proxy proxy upstream

# What is a reverse proxy?

A reverse proxy is a web server that sits in front of one or more backend
applications and forwards incoming requests to them. Instead of handling a
request itself, the proxy passes it on to an upstream process - typically an
application listening on a local port - and relays the response back to the
visitor.

On TurboStack this means Nginx accepts the public HTTP/HTTPS traffic for a
application and forwards it to your own application or container, rather than serving
PHP-FPM or static files. It is the standard way to publish long-running
application servers, such as Node.js apps, and containerized workloads, behind
TurboStack's Transport Layer Security (TLS), caching and security front door.


What is a reverse proxy?

On TurboStack

The reverse proxy is enabled **per application** under **Configure application >
Technologies > Reverse Proxy**.

- When you enable it, TurboStack generates the Nginx vhost so that requests are
  forwarded to your application's upstream - by default `127.0.0.1` on the port
  you choose.
- Your application keeps running on its own port (for example a Node.js process
  or a Docker container), while Nginx remains the public entry point handling
  TLS termination and request routing.
- It is the recommended pattern for **Node.js applications** such as
  Medusa and for **Docker/containerized
  apps** - pair it with Docker so Nginx proxies to the
  container's exposed port.
- You do not edit raw Nginx config; you enable the proxy and set the upstream
  port (and optionally the host), and TurboStack renders and reloads the
  configuration for you.

> [!NOTE]
> The reverse proxy forwards to a backend you run; it does not serve PHP. Use it
> when your application is its own server (Node.js, a container, a microservice),
> not for standard PHP sites.


What is a reverse proxy?

Best practices

- Bind your application to `127.0.0.1` (loopback) so only Nginx can reach it,
  never directly from the public internet.
- Keep your app on a fixed, predictable port that matches the configured
  upstream port.
- Let TurboStack terminate TLS at Nginx and proxy plain HTTP to the upstream,
  rather than running TLS inside the app.
- Make sure your application starts on boot and restarts on failure, so the
  upstream is always available behind the proxy.
- For containerized apps, expose a single port and proxy to it; keep one
  responsibility per container.


What is a reverse proxy?

Related

- Configure the reverse proxy on TurboStack
- Applications tab


Configure Ruby on TurboStack

configure ruby turbostack ruby yaml ruby_version ruby_sidekiq ruby_start_cmd

# Configure Ruby on TurboStack

Enable the Ruby runtime on an application, choose its version, and optionally add a startup command and Sidekiq background workers.


Configure Ruby on TurboStack

Where to configure it

The Ruby runtime is configured per application. In the TurboStack Platform, open an application and go to **Configure application > Technologies > Ruby**. From there you enable Ruby, select the version, and set how the application starts.

Ruby applications are published with the Nginx reverse proxy: your app listens on a local port and Nginx forwards public traffic to it. See Configure the reverse proxy for that part.


Configure Ruby on TurboStack

Required

| Key | Meaning |
| --- | --- |
| `ruby_version` | The Ruby major version to install, for example `"3.3"` (or newer). Setting this key is what enables the Ruby runtime for the application; there is no separate enable key. |


Configure Ruby on TurboStack

Optional

| Key | Meaning |
| --- | --- |
| `ruby_start_cmd` | The command used to start your Ruby application. |
| `ruby_sidekiq` | Enables a Sidekiq background-job worker alongside your app. |
| `ruby_sidekiq_cmd` | The command used to start the Sidekiq worker. |

```yaml
ruby_version: "3.3"
ruby_start_cmd: "bundle exec puma -p 3000"

# Optional background-job processing
ruby_sidekiq: true
ruby_sidekiq_cmd: "bundle exec sidekiq"
```


Configure Ruby on TurboStack

Related

- What is Ruby?
- Configure the reverse proxy
- Applications overview


What is Ruby?

what is ruby ruby hosting ruby turbostack ruby runtime sidekiq reverse proxy

# What is Ruby?

Ruby is a dynamic, object-oriented programming language designed for developer productivity and readable code. It is widely used for web applications, especially through frameworks such as Ruby on Rails, as well as for tooling and automation.

On a hosting platform, a Ruby web application runs as a long-lived process served by an application server. A web server accepts public HTTPS traffic and forwards requests to that process. Your code does not handle Transport Layer Security (TLS) or public networking directly.


What is Ruby?

On TurboStack

TurboStack provides Ruby as a per-application runtime, isolated per system user. You enable it on an application and select the version your application needs, so each user's Ruby installation stays independent from the others on the same host.

Ruby applications run behind Nginx acting as a reverse proxy: your app listens on a local port and Nginx terminates TLS and forwards traffic to it. You can define the command that starts your application, and you can optionally run Sidekiq alongside it to process background jobs.


What is Ruby?

Best practices

- Pin a specific Ruby version so deployments are reproducible, and plan upgrades before a version reaches end of life.
- Use a defined startup command so the platform always launches your application the same way.
- Offload long-running or scheduled work to Sidekiq background jobs instead of handling them in web requests.
- Serve your app with a production application server and let Nginx handle public TLS traffic.
- Keep gems up to date and audit them regularly for security advisories.


What is Ruby?

Related

- Configure Ruby on TurboStack
- Configure the reverse proxy


Add an SSH key

add ssh key ssh-keygen ed25519 authorize public key puttygen ssh access turbostack

# Add an SSH key

To open a shell or transfer files over SSH File Transfer Protocol (SFTP), you authorize an SSH key on
your host. TurboStack uses public-key authentication: you keep a private key, and you add the matching
public key to the host. This page shows how to create a keypair (if you do not have one) and how to
authorize it.

We recommend the **ed25519** key type. It is secure and fast, and it is the default across the
platform. Any OpenSSH-compatible key type also works.


Add an SSH key

Step 1: Generate a keypair

If you already have a public key you want to use, skip to Step 2.
Otherwise choose one of the methods below.


Add an SSH key

Mac, Linux, or Windows Subsystem for Linux (recommended)

Run `ssh-keygen` in a terminal:

```bash
ssh-keygen -t ed25519 -C "user@example.com"
```

- `-t ed25519` selects the ed25519 algorithm.
- `-C "user@example.com"` adds a comment so you can identify the key later.

You are prompted to:

- Choose where to save the key. Press `Enter` to accept the default `~/.ssh/id_ed25519`.
- Set a passphrase. This is optional but recommended - it protects the private key if it is stolen.

You now have two files:

- `id_ed25519` - your private key. Never share it.
- `id_ed25519.pub` - your public key. This is the one you add to the host.

Print the public key so you can copy it:

```bash
cat ~/.ssh/id_ed25519.pub
```


Add an SSH key

Windows with PuTTY

If you use PuTTY, generate the key with PuTTYgen:

1. Download PuTTY from the official source if you do not have it.
2. Open **PuTTYgen** (`puttygen.exe`).
3. Under **Parameters**, select **EdDSA**, the Edwards-curve Digital Signature Algorithm (Ed25519 is
   the default curve).
4. Click **Generate** and move your mouse over the blank area to add randomness.
5. Copy the **public key** shown at the top of the window.
6. Click **Save private key** to store the private key (set a passphrase if you want).

> [!NOTE]
> If a tool needs the private key in OpenSSH format, use **Conversions > Export OpenSSH key** in
> PuTTYgen and save it.


Add an SSH key

Step 2: Add your key to the host

Authorize the public key in the TurboStack interface:

1. Open your host.
2. Go to the **SSH** tab.
3. Paste your **public key** into the keys field.
4. Click **Save & Publish**.

TurboStack writes the authorized key for you - there is no need to edit any file on the server by
hand. Once published, you can connect over SSH with your private key.

> [!TIP]
> To grant the same key on many hosts at once, add it at the **group** level instead. Member hosts
> inherit group keys automatically. See Configure SSH for the `ssh_keys` setting and
> group inheritance.


Add an SSH key

On cPanel and DirectAdmin hosts

The flow above covers the default TurboStack host. If your host runs the cPanel or DirectAdmin
control panel, add the key through the panel's own SSH-key manager instead:

- **cPanel:** go to **Security > SSH Access > Manage SSH Keys**, import your public key, then
  authorize it.
- **DirectAdmin:** open the **SSH Keys** menu, add your public key, and make sure it is enabled.


Add an SSH key

Related

- Configure SSH
- What is SSH?
- Host SSH tab
- Security hardening


Configure SSH on TurboStack

configure ssh turbostack ssh yaml ssh keys ssh port password authentication

# Configure SSH on TurboStack

Authorize keys and set the SSH options for a host so your team can open shell and
SSH File Transfer Protocol (SFTP) sessions securely.


Configure SSH on TurboStack

Where to configure it

SSH is configured at the **host** level:

1. Open the host.
2. Go to the **SSH** tab.
3. Add authorized public keys and adjust the port and password-authentication
   options.

Keys set at the group level are inherited by member hosts.


Configure SSH on TurboStack

Required

| Key | Meaning |
|---|---|
| `ssh_keys` | List of authorized public keys allowed to open SSH/SFTP sessions on the host. |


Configure SSH on TurboStack

Optional

| Key | Meaning |
|---|---|
| `ssh_port` | The TCP port SSH listens on. |
| `ssh_passwords` | Whether to allow password authentication. Recommended: keep disabled (`false`). |

```yaml
# Host-level: authorized keys, custom port, key-only auth
ssh_keys:
  - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... alice@example.com"
ssh_port: 22
ssh_passwords: false
```

> [!TIP]
> Keep `ssh_passwords` set to `false` and rely on `ssh_keys` for authentication.
> Shared keys can be defined once at the group level and inherited by every host.


Configure SSH on TurboStack

Related

- What is SSH?
- Host SSH tab
- Security hardening


What is SSH?

what is ssh ssh hosting ssh turbostack secure shell sftp access

# What is SSH?

SSH (Secure Shell) is the standard protocol for secure, encrypted access to a
server. On TurboStack it gives you a **shell** for running commands on a host and
**SSH File Transfer Protocol (SFTP)** for transferring files, all over an encrypted connection.

Access is granted with **public-key authentication**: you upload your public key,
keep the matching private key safe, and SSH verifies you without ever sending a
password. This is both more convenient and far more secure than password logins.


What is SSH?

On TurboStack

SSH access is configured at the **host** level, with optional inheritance from
the group.

- You authorize access by adding **public keys** to a host. Each authorized key
  can open a shell or SFTP session.
- SSH keys can also be set at the group level and are inherited by member
  hosts, so you can grant a team access across many hosts in one place.
- You can change the **SSH listening port** and choose whether to allow
  **password authentication** - which we recommend keeping disabled in favor
  of keys.

> [!TIP]
> Set common keys at the group level so every host in the group inherits them,
> and reserve per-host keys for access that should not apply group-wide.


What is SSH?

Best practices

- Use **key-based authentication** and keep password authentication disabled.
- Protect your private keys with a passphrase and never share them.
- Grant access per person with their own key, so you can revoke individuals
  cleanly.
- Manage shared team access at the group level and let hosts inherit it.
- Remove keys promptly when someone no longer needs access.


What is SSH?

Related

- Configure SSH on TurboStack
- Host SSH tab
- Security hardening


How to manage user system services

systemctl --user systemd unit file enable-linger journalctl restart service template unit background worker

# How to manage user system services

This page shows how to run a long-lived process as a systemd user service under your system user.
You will create the service, start and stop it, keep it running after you log out, and read its
logs. For what these services are and which applications use them, see
What are user system services?.

systemd is a native alternative to tools like supervisord or PM2. It integrates with the system, gives
you full logs through `journalctl`, and needs no root access when you run it as a user service.


How to manage user system services

Before you start

- **Secure Shell (SSH) access to the host** - see SSH access. Run
  every command below as your system user; no root access is needed.
- The command your service should run (for example a worker or consumer command from your
  application).


How to manage user system services

Create a service

Create a unit file at `~/.config/systemd/user/<name>.service`, where `~` is your system user's home
directory. This example runs a worker and restarts it if it stops:

```ini
[Unit]
Description=My worker
After=network-online.target
StartLimitIntervalSec=0

[Service]
Type=simple
WorkingDirectory=%h/public_html
ExecStart=%h/public_html/bin/worker
Restart=always
RestartSec=10s

[Install]
WantedBy=default.target
```

- `%h` is your home directory, so the same unit works for any system user.
- `Restart=always` with `RestartSec=10s` restarts the process 10 seconds after it stops.

> [!TIP]
> `StartLimitIntervalSec=0` lets systemd keep retrying every `RestartSec` instead of giving up after
> repeated fast failures.


How to manage user system services

Start, enable and check it

After creating or changing a unit file, reload systemd, then enable and start the service:

```bash
systemctl --user daemon-reload
systemctl --user enable --now my-worker.service   # enable at login + start now
systemctl --user status my-worker.service         # check it is active
```


How to manage user system services

Keep it running after you log out

By default, user services stop when your last session ends. Enable lingering once so they keep
running after you close SSH and start again after a reboot:

```bash
loginctl enable-linger
```


How to manage user system services

Read the logs

Each service logs to the systemd journal. Read or follow it with:

```bash
journalctl --user -u my-worker.service              # recent logs
journalctl --user -u my-worker.service -f           # follow live
journalctl --user -u my-worker.service --since "5 minutes ago"
```

To scan a template unit's instances for fatal errors, match the service name with a wildcard and
filter the output:

```bash
journalctl --user -u "my-worker@*" --no-pager -n 1000 | grep -i FATAL
```


How to manage user system services

Stop, restart or remove a service

```bash
systemctl --user restart my-worker.service        # after a code change
systemctl --user stop my-worker.service            # stop, keep it enabled
systemctl --user disable --now my-worker.service   # stop and disable at login
```


How to manage user system services

Run many instances from one template

When you need several copies of the same service (for example one message-queue consumer per queue),
use a template unit. Add an `@` to the file name and use `%i` for the instance value:

```ini
# ~/.config/systemd/user/my-worker@.service
ExecStart=%h/public_html/bin/worker %i
```

Enable one service per instance; the value after `@` is passed as `%i`:

```bash
systemctl --user enable --now my-worker@queue1.service
systemctl --user enable --now my-worker@queue2.service
```


How to manage user system services

Scale throughput with more instances

A single worker processes one message at a time. Running several in parallel drains a queue faster.
This helps when a backlog builds up, for example during a large import or a sales campaign.

There are two ways to add capacity:

- **More instances:** run the same worker two, four or more times in parallel, one service per
  instance.
- **More threads:** some workers take a thread or process count flag instead (for example
  `--threads=4`). The same total limit below applies.

Add capacity by enabling more instances:

```bash
systemctl --user enable --now my-worker@1.service
systemctl --user enable --now my-worker@2.service
```

Remove capacity by disabling the extra services when the backlog is gone, to free processor time for
the site:

```bash
systemctl --user disable --now my-worker@2.service
```

> [!WARNING]
> Never run more parallel workers than the host has processor cores, and keep a safe margin below
> that number. Background workers compete with PHP, the web server and the database for the same
> cores. Too many workers cause high load and can make the whole server slow or unresponsive.

Check how many cores the host has:

```bash
nproc
```

Start with one or two workers. Measure how fast the queue drains and watch the host load on the
Health tab, then add one worker at a time. On a 4-core host, keep
the total at or below 2 to 3 background workers so the site keeps enough processor time. If the queue
still cannot keep up with a safe number of workers, scale up the host instead of adding more.


How to manage user system services

Application examples

The examples below are template units (note the `@` in the file name and `%i`/`%I` for the instance
value). Adjust `WorkingDirectory` and the PHP binary version to match your setup.

> [!NOTE]
> On TurboStack, PHP binaries are at `/usr/bin/php<version>` - for example `/usr/bin/php8.0` or
> `/usr/bin/php8.3`. The default `php` command also points at the host's main version. There is no
> `/usr/local/phpNN` path.

**Laravel queue worker** - `~/.config/systemd/user/laravel-queue@.service`:

```ini
[Unit]
Description=Laravel queue worker (#%i)
After=network-online.target
StartLimitIntervalSec=0

[Service]
Type=simple
WorkingDirectory=%h/public_html
ExecStart=/usr/bin/php8.3 %h/public_html/artisan queue:work --env=prod
Restart=always
RestartSec=10s

[Install]
WantedBy=default.target
```

**CraftCMS queue runner** - `~/.config/systemd/user/craftcms-queue@.service`:

```ini
[Unit]
Description=CraftCMS queue runner (#%i)
After=network-online.target
StartLimitIntervalSec=0

[Service]
Type=simple
WorkingDirectory=%h/public_html
ExecStart=/usr/bin/php8.3 %h/public_html/craft queue/listen
ExecReload=/bin/kill -SIGABRT $MAINPID
Restart=always
RestartSec=10s

[Install]
WantedBy=default.target
```

For CraftCMS, also disable `runQueueAutomatically` in the general config so the queue is not run
inside web requests.

**Magento message-queue consumer** - `~/.config/systemd/user/magento-consumer@.service`:

```ini
[Unit]
Description=Magento consumer (%i)
After=network-online.target
StartLimitIntervalSec=0

[Service]
Type=simple
WorkingDirectory=%h/public_html
ExecStart=/usr/bin/php8.3 %h/public_html/bin/magento queue:consumers:start %I --single-thread --max-messages=10000
Restart=always
RestartSec=10s

[Install]
WantedBy=default.target
```

Here `%I` is the consumer name, so one template serves every queue. `--single-thread` runs one
thread per process and `--max-messages=10000` restarts the process periodically to keep memory in
check. Enable one service per consumer:

```bash
systemctl --user enable --now magento-consumer@product_action_attribute.update.service
systemctl --user status  magento-consumer@sales.rule.update.coupon.usage.service
```

For a worked example, see the Magento message-queue consumers in
Magento best practices.


How to manage user system services

Related

- What are user system services?
- Application file layout and permissions
- How to keep a Node.js app running
- SSH access


What are user system services?

systemd user service systemctl background process queue worker message queue consumer enable-linger

# What are user system services?

A user system service is a long-lived process that TurboStack runs for you under your own system user, managed by systemd (the Linux service manager). It starts on its own, restarts if it crashes, and can keep running after you log out - without any root access.

Many applications need a process that stays running in the background: a message-queue consumer, a queue worker, a scheduled-job runner, or the application server itself. If that process stops, work stops piling up or the site returns a 502 error. A user system service keeps it running and restarts it automatically.


What are user system services?

How it works on TurboStack

- Each service is described by a unit file under `~/.config/systemd/user/`, where `~` is your system user's home directory (for example `/var/www/prod/`).
- You manage services with `systemctl --user` over Secure Shell (SSH). No root access is needed, because the services run as your system user.
- Logs go to the systemd journal, which you read with `journalctl --user`.
- `loginctl enable-linger` lets your services keep running after you close your SSH session and start again after a reboot.

For the exact commands to create, start, stop and inspect a service, see How to manage user system services.


What are user system services?

Which applications use them

Background processing differs per application. These are the common cases on TurboStack:

| Application | What runs as a user service |
| --- | --- |
| Magento | Message-queue consumers (indexing, emails, order processing) |
| Shopware | Message-queue consumers and the scheduled-task runner |
| Odoo | The Odoo application server itself |
| Akeneo | Job-queue consumers (imports, exports, maintenance) |
| Laravel | Queue workers |
| Craft CMS | The queue listener |
| OroCommerce | Message-queue consumers |
| Medusa | The Node.js application process (or run it under pm2) |
| nopCommerce | The .NET application service |

> [!NOTE]
> A dedicated Node.js process is often run under the pm2 process manager instead. See How to keep a Node.js app running for when to pick pm2 over a systemd service.


What are user system services?

Related

- How to manage user system services
- SSH access
- Application file layout and permissions
- How to keep a Node.js app running


Configure TurboShield on TurboStack

configure turboshield turbostack turboshield yaml rate limiting bot protection http 429 allow list trusted clients bot challenge

# Configure TurboShield on TurboStack

TurboShield is enabled by default with sensible settings. This page describes every setting, so you
can adjust it when the defaults do not fit your traffic. For what each mechanism actually does, see
What is TurboShield?.


Configure TurboShield on TurboStack

Where to configure it

TurboShield is configured at the **host** level and applies to every application on that host:

1. Open the host.
2. Go to the **Security** tab.
3. Find the **TurboShield** section, then enable it and choose a protection level.

The GUI exposes the settings you need most often. The remaining settings are available in the
Source (YAML) view, grouped under the `turboshield` key.

> [!TIP]
> Change one setting at a time and check your logs afterwards. Rate limits interact, so a large
> change in several settings at once makes it hard to see which one caused an effect.


Configure TurboShield on TurboStack

Basic settings

| Key | Default | Values | What it does |
|---|---|---|---|
| `turboshield.enabled` | `true` | `true` / `false` | Turns TurboShield on for the host. Setting it to `false` removes the protection completely. |
| `turboshield.level` | `medium` | `low`, `medium`, `high`, `attack` | The protection level. Tunes all limits at once and unlocks the attack-only mechanisms. |

```yaml
turboshield:
  enabled: true
  level: medium
```


Configure TurboShield on TurboStack

What each level actually does

The level is a single dial over several limits. Use this table when you need to know what you are
changing, rather than guessing between `medium` and `high`.

| | `low` | `medium` (default) | `high` | `attack` |
|---|---|---|---|---|
| Strictly-limited bots | 6 req/s | 2 req/s | 1 req/s | 1 req/s |
| Any single visitor | 60 req/s | 40 req/s | 30 req/s | 20 req/s |
| Burst allowance | 800 | 600 | 400 | 250 |
| Simultaneous connections per visitor | 160 | 120 | 80 | 60 |
| Excess requests | queued, then refused | refused immediately | refused immediately | refused immediately |
| Distributed-attack detection | - | - | - | active |
| Disguised-browser blocking | - | - | - | active |
| Outdated-browser blocking | - | - | - | active |
| Ban duration | standard | standard | standard | longer |

> [!NOTE]
> The per-visitor limits look high compared to the bot limits on purpose. A real browser opens
> many connections and requests dozens of files for a single page view, so the general limit must
> allow that while the bot limits stay strict.