site commands
Run with sudo /root/simai-env/simai-admin.sh site <command> [options] or via menu.
add
Create nginx vhost and project root for an existing path.
Options:
--domain(required)--project-name(optional; derived from domain if missing)--path(optional; default uses path style under/home/simai/www/)--path-style(slug|domain) controls default path when--pathis not set. Default isdomain(e.g.,/home/simai/www/your-domain.tld). Use--path-style slugto restore legacy slug paths or set/etc/simai-env.confwithSIMAI_DEFAULT_PATH_STYLE=domain|slug. Menu does not prompt for path style; domain-based default is used unless overridden via CLI/config.--profileselects site type; profiles are defined declaratively inprofiles/*.profile.sh. Supported:generic,laravel,static,alias(defaultgeneric).--host-mode standard|wildcardcontrols whether the site serves only the main domain or the main domain plus all first-level subdomains. Default isstandard.--wildcard-domain(optional) overrides the wildcard hostname stored in metadata for--host-mode wildcard. Default is*.your-domain.tld.--frame-policy same-origin|anycontrols whether browsers may embed the site in an iframe. The safe default issame-origin; useanyonly for a dedicated embedded application endpoint.--usageselects a user-facing activity class:standard(default),high-traffic, orrarely-used. simai-env maps this to the internal performance mode automatically.--target-domain(alias only) set target non-interactively; required in CLI for alias when not in menu.--php(optional; choose from installed if omitted; in menu the selector shows only installed versions that are compatible with the chosen profile)- SSL (optional):
--ssl=ask|yes|no,--ssl-email,--ssl-redirect=yes|no,--ssl-hsts=yes|no,--ssl-staging=yes|no - DB (optional):
--create-db=yes|no(alias:--db=yes|no),--db-name,--db-user,--db-pass(defaults from project; password generated),--db-export=yes|no(export to project.env; default yes for required DB profiles, no otherwise),--skip-db-required=yes|no(defaultno; allow required-DB profiles to be created without DB — for migration only, emits warning) - Access (optional):
--access-create=yes|no,--access-login,--access-password(create project-scoped SFTP access after site creation; menu prompts when omitted) - Bitrix helper files (Bitrix profile only):
--bitrix-files=none|setup|restore. Default isnoneso new Bitrix sites do not expose public installer/restore scripts until the operator chooses the required flow.
Behavior:
- Generic uses placeholder and profile-driven docroot (
PROFILE_PUBLIC_DIR, defaultpublic); Laravel requiresartisan. Static is nginx-only (no PHP/DB) withindex.htmlplaceholder under docroot and nginx-served/healthcheck(local-only). Alias points the domain to an existing site (reuses its root, no DB/pool creation). - Creates PHP-FPM pool and nginx vhost for non-static profiles; installs
healthcheck.phpinto the profile docroot when the profile healthcheck mode isphp. --host-mode wildcardmakes nginx serve both the main domain and all first-level subdomains by writingserver_name <domain> *.domainand storing the host mode in metadata.- When a wildcard-host site is created, the summary now prints the DNS records the user needs to create:
<domain> -> A -> <server-ip>*.domain -> A -> <server-ip>
- The same summary and
site infoalso print the next wildcard HTTPS step for the currently supported DNS provider flow (Cloudflare DNS challenge). - If
create-db=yes(ordb=yes), creates or reuses the managed DB/user for the site and stores creds in/etc/simai-env/sites/<domain>/db.env(0640 root:root); forgeneric, exports to<project>/.envidempotently; for required DB profiles,.envexport stays enabled by default and menu no longer asks a separate technical question about it. In menu mode, DB setup now offers a clearer branch between creating a managed DB now and continuing without DB setup. Required-DB profiles can still be created without DB only when--skip-db-required yesis supplied in CLI (intended for migration); create DB later viasite db-create. - For Bitrix profile,
site addasks in menu mode whether to prepare public helper files:none: create only infrastructure; nobitrixsetup.phporrestore.phpis added.setup: download currentbitrixsetup.phpfrom the official Bitrix URL and write DB preseed files when managed DB credentials exist.restore: download currentrestore.phpfrom the official Bitrix URLs, prepare restore-writable paths, and write.settings.phpplus connection initialization from managed DB credentials without creating a prematuredbconn.php. The archive restores its owndbconn.php; this avoids legacymbstring.func_overloadchecks on PHP 8. After uploading every archive volume, runbitrix restore-readyagain; the browser URL is shown only after the archive passes integrity validation. CLI default isnone. Usebitrix installer-readyorbitrix restore-readylater if the choice changes.
- If
--ssl=yes,site addissues a Let’s Encrypt certificate after the site is created. SSL issuance is best-effort: site creation still succeeds if cert issuance fails. In menu mode, when--sslis not supplied explicitly, the site creation flow now asks whether to issue Let’s Encrypt and requests an email if needed. In non-menu CLI,--ssl=askbehaves asno. - After creation, the summary prints profile-aware
Next stepsso the user can move directly to the expected installer or finalize flow. - After creation, simai-env automatically stores the selected activity class in
/etc/simai-env/sites/<domain>/perf.envand applies the mapped site-level performance mode:standard->balancedhigh-traffic->aggressiverarely-used->parked
- Central SSL defaults can be defined in
/etc/simai-env.conf:SIMAI_SSL_AUTO_ISSUE_ON_CREATE=ask|yes|noSIMAI_SSL_LE_EMAIL_DEFAULT=<email>SIMAI_SSL_REDIRECT_DEFAULT=yes|noSIMAI_SSL_HSTS_DEFAULT=yes|noSIMAI_SSL_STAGING_DEFAULT=yes|noExample:
SIMAI_SSL_AUTO_ISSUE_ON_CREATE=ask SIMAI_SSL_LE_EMAIL_DEFAULT=ops@example.com SIMAI_SSL_REDIRECT_DEFAULT=yes SIMAI_SSL_HSTS_DEFAULT=no SIMAI_SSL_STAGING_DEFAULT=no - For static profile,
--phpand DB flags are ignored (with warnings); no PHP-FPM pool or cron is created. - Project ID (slug) is still used for pools/cron/queue/sockets/logs even if the path style uses the domain.
site infoandsite listshow the site host mode and wildcard hostname when enabled.site infofor wildcard-host sites also shows:- the DNS records to create
- the wildcard HTTPS command to run after DNS is ready
- If the target domain already exists as a configured site,
site addnow refuses to continue instead of silently reattaching or downgrading the site profile. - Menu-based
site addnow expects a new empty project directory. Reusing a non-empty path requires an explicit CLI--pathflow and is refused in the regular menu wizard. - The menu wizard collects DB, access, SSL, runtime, and target choices before the first filesystem/service change, then shows a final creation plan with a default-safe
noconfirmation. The final prompt names the domain and explains thatyescreates the site whilenoexits without creating files or configuration. - Cancelling a
site addwizard step returnsCANCELLED(exit89) and writes the exact step and domain to/var/log/simai-admin.log; cancellations before final confirmation do not apply site changes. - If an apply-stage failure occurs after confirmation, site creation rolls back only resources created by that invocation; pre-existing pools, paths, databases, users and access entries are not treated as owned cleanup targets.
- Required markers: if the directory is newly created or empty, missing markers do not block immediately; bootstrap files are applied first, then markers are rechecked. On non-empty directories without markers, the command now errors instead of falling back to
generic. /healthcheck.phpis localhost-only by default for php-mode profiles; test withcurl -i -H "Host: <domain>" http://127.0.0.1/healthcheck.php. Static uses nginx-mode healthcheck at/healthcheck(local-only).- Web root is profile-driven (
PROFILE_PUBLIC_DIR, empty/“.“ means project root).
Examples:
- Create without TLS:
simai-admin.sh site add --domain example.com --profile generic --php 8.3 - Create and issue TLS immediately:
simai-admin.sh site add --domain example.com --profile generic --php 8.3 --ssl yes --ssl-email ops@example.com - Create one site for domain plus subdomains:
simai-admin.sh site add --domain obr.site --profile generic --host-mode wildcard - Create a dedicated iframe application endpoint:
simai-admin.sh site add --domain app.example.com --profile laravel --frame-policy any - Create Bitrix infrastructure only:
simai-admin.sh site add --domain example.com --profile bitrix --php 8.3 --create-db yes - Create Bitrix and prepare fresh installer helper:
simai-admin.sh site add --domain example.com --profile bitrix --php 8.3 --create-db yes --bitrix-files setup - Create Bitrix and prepare restore helper:
simai-admin.sh site add --domain example.com --profile bitrix --php 8.3 --create-db yes --bitrix-files restore
adopt
Attach an existing application directory as a site without scaffolding.
Requirements come from composer.json and .simai/app.json
(docs/architecture/app-manifest.md).
sudo /root/simai-env/simai-admin.sh site adopt --domain app.example.com --path /home/simai/www/app.example.com
sudo /root/simai-env/simai-admin.sh site adopt --domain app.example.com --path /home/simai/www/app.example.com --confirm yes
Apply installs the required PHP version, extensions and packages (and
PostgreSQL when declared), creates .env from .env.example only when it is
missing, sets manifest env defaults only where unset, runs
composer install --no-dev as the site user, generates APP_KEY once, runs
migrations when requested (--migrate yes or "migrate": true) and writes
the declared workers and scheduler. Options: --profile, --php, --owner,
--db-engine, --create-db, --migrate, --build yes|no|auto,
--pgdg yes. Running adopt again on the same domain reconciles.
deploy
Deploy a release with an atomic switch.
sudo /root/simai-env/simai-admin.sh site deploy --domain D --git https://github.com/org/app.git --ref v1.4.0 --confirm yes
sudo /root/simai-env/simai-admin.sh site deploy --domain D --archive /root/app-1.4.0.tar.gz --sha256 <sum> --confirm yes
sudo /root/simai-env/simai-admin.sh site deploy --domain D --from /root/build/app --confirm yes
sudo /root/simai-env/simai-admin.sh site deploy-rollback --domain D --confirm yes
sudo /root/simai-env/simai-admin.sh site deploy-status --domain D
Layout: shared .env and storage/ stay in the site root; code lives in
releases/<id>; current points at the live release and nginx serves
current/<public>. The first deploy keeps the adopted code as
releases/<id>-initial. Each deploy fetches as the site user, runs
composer install --no-dev, migrates before the switch, switches current,
reloads PHP-FPM and runs artisan queue:restart. A failed build never touches
the live release. --keep (default 5) limits stored releases. Rollback
switches code only; database migrations are not reverted.
describe
JSON for people and AI agents: layout, database engine (no secrets), user, release, workers, logs, validated manifest and ready-to-run commands.
sudo /root/simai-env/simai-admin.sh site describe --domain D
isolate
Move an existing site from the shared simai account to its own Unix user
site-<slug>: project files, PHP-FPM pool, cron file, queue unit and SFTP
ACLs. New sites are created isolated automatically.
sudo /root/simai-env/simai-admin.sh site isolate --domain example.com
sudo /root/simai-env/simai-admin.sh site isolate --domain example.com --confirm yes
Without --confirm yes only the plan is printed. The command reloads
PHP-FPM, nginx and cron; any failure restores the previous owner, pool, cron
and unit. Alias sites follow their target site. After migrating, run
site doctor and open the site. Code that writes outside the project
directory (for example to another site’s folder) stops working by design.
Symlinked modules keep working as long as their targets are readable by
others (for example /home/simai/git/<repo> with mode 755). Deploy scripts
that used to write into the project as simai must now run as the site user
(sudo -u site-<slug> ...) or as root followed by
chown -R site-<slug>:site-<slug> <project>.
frame-policy
Change the embedding policy of an existing managed site. The setting is stored in nginx metadata and survives SSL regeneration.
- Block cross-origin embedding (default):
simai-admin.sh site frame-policy --domain app.example.com --mode same-origin --confirm yes - Allow embedding from any origin:
simai-admin.sh site frame-policy --domain app.example.com --mode any --confirm yes
any removes the legacy X-Frame-Options: SAMEORIGIN response header and adds
Content-Security-Policy: frame-ancestors *. It should be enabled only on a
dedicated application domain whose own authentication and authorization remain
enabled.
remove
Remove site resources (profile-driven; no fixes on target data unless confirmed).
Options:
--domain--project-name--path--remove-files(yes|no)--drop-db(yes|no, default DB name from project)--drop-db-user(yes|no, default user from project)--db-name,--db-user--dry-run(yes|no, defaultno; whenyes, plan-only and no confirm needed)
Behavior:
- Dry-run mode (
--dry-run yesor menu “Plan only”) prints what would be removed and exits without changes (no confirm needed). - Apply mode removes nginx vhost/symlink (with nginx -t before reload; restores if test fails).
- PHP/cron/queue removal only when the profile requires PHP (alias/static skip automatically; cron removal is profile-gated).
- DB prompts only when
PROFILE_REQUIRES_DB != no; static/alias skip DB prompts entirely. DB drop flags are errors for such profiles even in dry-run. - File removal and DB/user drops happen only when explicitly confirmed (defaults to “no” in CLI; menu asks). Uses safe fallback slug for derived paths when metadata is invalid.
- A full successful DB and user drop removes
db.env; site removal always removes managedperf.envandruntime.env, then removes the metadata directory when it becomes empty. Partial DB/file/metadata failures return a non-zero status and preserve unresolved metadata for inspection. - Alias profile: refuses file/DB removal flags and ignores path overrides (manage on the target site instead).
Destructive operations and --confirm
In non-menu mode, --confirm yes is required only when any destructive flags are set:
--remove-files yes--drop-db yes--drop-db-user yes
Examples:
- Dry-run (plan):
simai-admin.sh site remove --domain <domain> --dry-run yes - Dry-run with flags (still plan-only):
simai-admin.sh site remove --domain <domain> --remove-files yes --drop-db yes --dry-run yes - Apply destructive removal (confirm required in CLI):
simai-admin.sh site remove --domain <domain> --remove-files yes --confirm yes
Safety guards:
- Managed file removal is allowed only for real project directories under the configured web root (
/home/simai/wwwby default). - Symlink project roots, resolved paths outside the managed web root, and filesystem-boundary crossings are refused.
- Alias sites do not remove target files; remove or repair the target site explicitly.
list
List domains from nginx sites-available with profile, PHP version, root/alias target, and brief SSL status (off/LE:YYYY-MM-DD/custom).
info
Show the main site card for one domain.
Options:
--domain(required outside menu)
Output includes:
- domain, profile, project, slug
- host mode and hostnames
- root/docroot
- nginx enabled state
- nginx conf path
- expected nginx log paths
- healthcheck endpoint
- PHP and socket/pool details
- SSL summary plus redirect/HSTS hints
- scheduler file state
- worker unit state
- activity class and plain-language optimization recommendation
This is the command used by Sites -> Site info.
set-php
Switch site to a different PHP version (profile-driven).
Options:
--domain(required; aliases are not allowed)--php(target version; menu lets you pick installed versions allowed by the profile and can offer installation of apt-available versions when missing; CLI still requires it installed)--keep-old-pool(yes|no, defaultno; ifno, removes old PHP-FPM pool)
Behavior:
- Loads the profile from nginx metadata; refuses when
PROFILE_REQUIRES_PHP=no,PROFILE_IS_ALIAS=yes, orPROFILE_ALLOW_PHP_SWITCH=no. - Enforces profile PHP constraints when set: explicit
PROFILE_ALLOWED_PHP_VERSIONSor dynamicPROFILE_ALLOWED_PHP_MIN_VERSION/PROFILE_ALLOWED_PHP_MAX_VERSION. - Recreates PHP-FPM pool for the target version, patches nginx upstream sockets in-place, validates with
nginx -t, then reloads nginx/php-fpm. Socket/pool naming uses a safe fallback slug when metadata is invalid. - Laravel/queue profiles keep their cron/unit wiring;
--keep-old-pool=yespreserves the previous pool, otherwise it is removed.
perf-status
Show per-site runtime governance and PHP-FPM pool footprint.
Options:
--domain(required outside menu)
Output includes:
- activity class and its mapped governance baseline
- human-readable optimization posture (
automatic,manual,paused) - a plain-language recommendation based on current runtime state and server pressure
- profile and PHP version
- current pool mode / children / request limits
- current request timeout
- memory limit and a best-effort memory risk estimate
- opcache / redis extension presence
- cron / queue footprint summary
perf-tune
Apply per-site PHP-FPM governance mode.
Options:
--domain(required outside menu)--mode(parked|safe|balanced|aggressive, defaultbalanced)--confirm(yes|no, defaultno; required outside menu)
Behavior:
- Stores managed site-level performance settings in
/etc/simai-env/sites/<domain>/perf.env. - Applies a managed
simai-site-perf-*block to the current PHP-FPM pool. - Keeps existing
site php-iniand profile-managed INI blocks intact. - Validates php-fpm config before reload and restores the previous pool on failure.
usage-status
Show the simple user-facing activity class for a site.
Options:
--domain(required outside menu)
Output includes:
- activity class (
standard,high-traffic,rarely-used) - human-readable optimization posture
- mapped internal performance mode
- a plain-language recommendation
- current runtime state
usage-set
Set the simple user-facing activity class for a site.
Options:
--domain(required outside menu)--class(standard|high-traffic|rarely-used)--confirm(yes|no, defaultno; required outside menu)
Behavior:
- Stores
usage_classin/etc/simai-env/sites/<domain>/perf.env. - Automatically maps the class to the internal mode:
standard->balancedhigh-traffic->aggressiverarely-used->parked
- Applies the mapped pool governance immediately for PHP sites.
- Non-PHP profiles still store the usage class so future tooling can respect the same user intent.
auto-optimize-status
Show whether a site participates in automatic optimization.
Options:
--domain(required outside menu)
Output includes:
- effective automatic optimization state
- current site-level override (
inherit,yes,no) - usage class and mapped performance mode
- runtime state
auto-optimize-enable / auto-optimize-disable / auto-optimize-reset
Control the per-site automatic optimization override.
Options:
--domain(required outside menu)--confirm(yes|no, defaultno; required outside menu)
Behavior:
- Stores
auto_optimizein/etc/simai-env/sites/<domain>/perf.env. enableforces the site to participate in automatic optimization when the global scheduler job is enabled.disableexcludes the site from scheduler-drivenautorebalance actions.resetremoves the explicit decision and returns the site to the global default (inherit).- Manual commands like
site perf-tunestill work even when automatic optimization is disabled for the site.
runtime-status
Show whether a site runtime is active or suspended.
Options:
--domain(required outside menu)
Output includes:
- runtime state (
active/suspended) - PHP pool state
- cron file state
- queue unit state
runtime-suspend
Suspend a site runtime without deleting the site.
Options:
--domain(required outside menu)--confirm(yes|no, defaultno; required outside menu)
Behavior:
- Disables the site PHP-FPM pool by moving it out of active
pool.d. - Adds a managed nginx
503 Site is parked by simai-envblock while keeping ACME validation reachable. - Disables site cron/queue where the profile uses them.
- Stores runtime state in
/etc/simai-env/sites/<domain>/runtime.env.
runtime-resume
Resume a previously suspended site runtime.
Options:
--domain(required outside menu)--confirm(yes|no, defaultno; required outside menu)
Behavior:
- Restores the disabled PHP-FPM pool.
- Removes the managed nginx suspend block.
- Re-enables cron/queue if they were disabled by
runtime-suspend.
fix
Plan or apply profile-required PHP fixes (PHP extensions and PHP INI overrides). Defaults to plan-only (no changes).
Options:
--domain(required outside menu)--apply(none|php-ext|php-ini|all, defaultnone)--include-recommended(yes|no, defaultno)--confirm(yes|no, defaultno; required in non-menu mode when--apply != none)
Behavior:
- Validates domain/path/profile; refuses alias/static (
PROFILE_IS_ALIAS=yesorPROFILE_REQUIRES_PHP=no) or sites without PHP metadata. - Plans missing PHP extensions (required; recommended when
--include-recommended=yes) and INI entries (required; recommended when flag is on). - Apply modes:
php-ext: install missing extensions via mapped apt packages, then reload php-fpm (config test skipped if binary absent); fails when required extensions remain missing.
php-ini: write managed pool block (; simai-profile-ini-begin/end) with required (and optional recommended) INI overrides, php-fpm config test, reload on success; restores backup if test fails.all: both of the above.- Non-menu apply requires
--confirm yes; menu prompts for apply mode and whether to include recommended items.
Examples:
- Plan only:
simai-admin.sh site fix --domain example.com - Apply missing required extensions:
simai-admin.sh site fix --domain example.com --apply php-ext --confirm yes - Apply extensions + INI including recommended:
simai-admin.sh site fix --domain example.com --apply all --include-recommended yes --confirm yes
doctor
Diagnose a site against its profile contract (read-only; no fixes applied).
Options:
--domain(required outside menu)--strict(yes|no, defaultno) – exit non-zero on FAIL whenyes--include-target(yes|no, defaultyes) – for alias, run a partial (non-recursive) target inspection with prefixed results
Checks (non-destructive):
- Filesystem: root/docroot, markers, bootstrap files, writable paths,
.envpermissions, world-writable files/directories - nginx: config/symlink presence, healthcheck policy vs profile,
nginx -t - PHP: version installed, php-fpm service/pool/socket, required/recommended extensions, INI expectations
- Cron:
/etc/cron.d/<project-slug>when profile enables cron - SSL: cert files present when metadata says ssl=on
- DB: mysql service presence when profile requires DB, public listener exposure
on
3306/33060,.envpresence for required DB profiles - Alias profiles: when
--include-target=yes, performs a prefixed partial check of the target site (root/docroot/markers/healthcheck/nginx/php service/pool/socket) without recursion
Output: PASS/WARN/FAIL per check with hints; no secrets are shown.
Per-site PHP ini overrides
- Overrides are stored at
/etc/simai-env/sites/<domain>/php.iniand applied as a managed pool blocksimai-site-ini-*(profile-managedsimai-profile-ini-*stays last and has higher priority). - Commands:
simai-admin.sh site php-ini-set --domain example.com --name memory_limit --value 512M --apply yes --confirm yessimai-admin.sh site php-ini-unset --domain example.com --name memory_limit --apply yes --confirm yessimai-admin.sh site php-ini-list --domain example.comsimai-admin.sh site php-ini-apply --domain example.com --confirm yes
Profile selection
- The admin menu lists profiles from the registry
profiles/*.profile.sh; default ordering:generic,laravel,static,alias. - CLI
--profilemust match a registered profile; registry is declarative only (no executable logic). - doctor:
simai-admin.sh site doctor --domain <domain> [--strict yes|no] [--include-target yes|no]
Read-only contract diagnostic: checks profile validity, filesystem/docroot, world-writable files, nginx healthcheck policy, PHP/cron/SSL/DB expectations, and MySQL network exposure. No fixes applied. Use--strict yesto exit non-zero on FAIL. - drift:
simai-admin.sh site drift --domain <domain> [--fix yes]
Checks metadata/cron drift;--fix yescan migrate marked legacy cron blocks to/etc/cron.d/<slug>(safe markers only). Does not auto-fix metadata/DB/files/SSL. - config-normalize:
simai-admin.sh site config-normalize --domain <domain> --confirm yes
Removes duplicate directives from the site PHP-FPM pool (the last value wins, site overrides are kept). For Bitrix sites it also aligns the request budget to 300 seconds in nginx, PHP-FPM and PHP. Every file is backed up first and restored if validation or reload fails.
Node.js services (profile node)
sudo /root/simai-env/simai-admin.sh profile enable --id node --confirm yes
sudo /root/simai-env/simai-admin.sh site add --domain D --profile node --confirm yes # optional --app-port 3189
sudo /root/simai-env/simai-admin.sh site deploy --domain D --git https://github.com/org/service.git --ref v1.0.0 --confirm yes
sudo /root/simai-env/simai-admin.sh site service-restart --domain D --confirm yes
journalctl -u simai-app-<project> -n 100
The site gets a local port and an nginx proxy; the release describes the
service in .simai/app.json (node.start, dependencies, Python
requirements, shared paths, health check). Deploy builds as the site user,
runs simai-app-<project>.service from current (restarted on failure and
on boot) and returns to the previous release when the health check fails.
Details: docs/architecture/app-manifest.md.
Static sites from CI artifacts
sudo /root/simai-env/simai-admin.sh site deploy --domain D --archive site.tgz --sha256 <sum> --confirm yes
sudo /root/simai-env/simai-admin.sh site deploy-key-add --domain D --pubkey-file ci.pub --confirm yes
sudo /root/simai-env/simai-admin.sh site redirect-add --domain D --from / --to /ru/ --code 302 --confirm yes
The artifact is the document root; <root>/public points at current.
Static sites behave like GitHub Pages (/dir/, name.html, 404.html,
200.html for single-page apps). Deploy keys, the gate and the workflow
step: docs/operations/ci-deploy.md.