Skip to content

Latest commit

 

History

History
290 lines (220 loc) · 9.92 KB

File metadata and controls

290 lines (220 loc) · 9.92 KB

Installing Scriptor

A fresh Scriptor install needs three things in the SQLite database before the frontend can render: the Pages category with its fields, the Users category with its fields, and at least one admin user. bin/scriptor install creates all three plus a minimal Home page so / works on first request.

Prerequisites

  • PHP 8.2+ (8.3 recommended)
  • Composer 2
  • SQLite 3.38+
  • Standard PHP extensions: mbstring, dom, json, gd, pdo_sqlite
  • A web server with its document root pointed at public/

The Docker option below skips all of the above except Docker itself.

Try with Docker (fastest, no local PHP needed)

If you just want to see Scriptor run without installing PHP, Composer, or SQLite locally, the bundled demo image is one command:

git clone https://github.com/bigin/Scriptor.git
cd Scriptor
docker compose up -d --build

The stack listens on http://localhost:8080/. When port 8080 is already taken (ServBay, another local container, …) override the host port:

SCRIPTOR_DEMO_PORT=8090 docker compose up -d --build

The container itself always binds 80; only the host-side port is dynamic. Default admin login is admin / gT5nLazzyBob (the container runs bin/scriptor install on first start with the documented demo password). For a private demo with your own password:

SCRIPTOR_ADMIN_PASSWORD='your-strong-secret' \
  SCRIPTOR_DEMO_PORT=8090 \
  docker compose up -d --build

See docs/demo.md for what the seed creates, how to reset, and when not to use this image (it is built for exploration, not production).

Interactive install (local dev)

git clone git@github.com:bigin/Scriptor.git
cd Scriptor
composer install
php bin/scriptor install

The command will:

  1. Confirm the database path: About to seed /path/to/data/imanager.db. Type INSTALL to proceed:. Type INSTALL and press Enter.
  2. Prompt for an admin password (8 characters minimum, echo suppressed) and ask you to confirm it. The minimum matches iManager's PasswordFieldType so the editor's change-password form accepts the same passwords.
  3. Create the Pages and Users categories with their fields, seed an admin user, and add a Home page.

You should see four [n/4] progress lines and a final summary block with the editor URL.

Point your web server at public/ and visit /. The Home page renders; /editor/ accepts the credentials you just set.

Non-interactive install (Docker, CI, scripted provisioning)

When stdin is not a TTY (CI pipelines, Docker entrypoints) you must pass --yes and supply the password through --password or the SCRIPTOR_ADMIN_PASSWORD environment variable.

SCRIPTOR_ADMIN_PASSWORD='your-strong-secret' \
  php bin/scriptor install --yes

or equivalently:

php bin/scriptor install --yes --password='your-strong-secret'

Without --yes the command bails with a clear error rather than hang waiting for a confirmation that will never come.

All options

php bin/scriptor install [options]

Options:
  --password=<value>   Admin password (overrides SCRIPTOR_ADMIN_PASSWORD env).
  --username=<name>    Admin username (default: admin).
  --email=<addr>       Admin email (default: admin@example.com).
  --db=<path>          Database file path (default: data/imanager.db).
  --yes, -y            Skip the "type INSTALL to proceed" prompt. Required
                       when stdin is not a TTY.
  --help, -h           Show the inline help text.

Password sources are tried in order:

  1. --password=... flag
  2. SCRIPTOR_ADMIN_PASSWORD environment variable
  3. Interactive TTY prompt

Exit codes:

Code Meaning
0 Install completed
1 Already installed (Pages category exists; refusing to overwrite)
2 Invalid admin password (too short or on the blocklist)
3 Invoked under a non-CLI SAPI
4 Confirmation skipped without --yes, or any other unexpected error

Re-installing

bin/scriptor install refuses to run a second time against the same database, by design. To start over, delete the database file:

rm data/imanager.db
php bin/scriptor install

There is intentionally no --force flag. If the install ever needs to recover from a half-written state, fix the data with direct SQL or the editor. The CLI is for greenfield seeding.

Installing plugins

A default Scriptor install ships with zero plugins. Plugins are Composer packages of type: scriptor-plugin that you add per install. Discovery is automatic: Scriptor scans vendor/composer/installed.json on every boot, so the next request picks the plugin up after the composer require completes.

Host install (local PHP, shared hosting)

Plugins are not on Packagist, and Scriptor's composer.json ships clean (it names no plugin repositories). From the Scriptor root, point Composer at the plugin's VCS repository first, then require it:

composer config repositories.scriptor-markdown-pages \
  vcs https://github.com/bigin/scriptor-markdown-pages
composer require bigins/scriptor-markdown-pages

The first command adds a repositories entry to your project's composer.json; without it composer require reports "Could not find a version of package …". A plugin published on Packagist needs only the composer require.

Docker

Container filesystems are immutable below the volumes, so the Docker workflow is to bake the plugin into the image via two build args in your compose override (both space-separated lists, both empty by default):

  • SCRIPTOR_PLUGIN_REPOSwhere to find packages not on Packagist: a list of VCS (git) URLs, each registered with composer config repositories before the require. Omit for Packagist-only plugins.
  • SCRIPTOR_PLUGINSwhich packages to install: composer package specs (name:constraint).
services:
  scriptor:
    build:
      args:
        SCRIPTOR_PLUGIN_REPOS: "https://github.com/bigin/scriptor-markdown-pages"
        SCRIPTOR_PLUGINS: "bigins/scriptor-markdown-pages:^0.1"

Then docker compose up -d --build. Scriptor's Dockerfile registers each repo URL, then runs composer require $SCRIPTOR_PLUGINS during image build, so the plugin lands in vendor/ and survives every restart, recreation, or deploy. Scriptor's own composer.json declares no plugin repositories, so the downstream image supplies both the URLs and the package specs.

Multiple plugins go in the same args as space-separated lists — one repo URL and one spec per plugin:

SCRIPTOR_PLUGIN_REPOS: "https://github.com/bigin/scriptor-markdown-pages https://github.com/bigin/scriptor-simple-router"
SCRIPTOR_PLUGINS: "bigins/scriptor-markdown-pages:^0.1 bigins/scriptor-simple-router:^0.1"

Trap: docker exec scriptor composer require ... Works immediately because the discovery cache invalidates from installed.json mtime, but the change lives in the running container's layer and is wiped by the next docker compose down && up. Use it for "does this plugin even boot" probes; never as an install path for anything you want to keep.

Disabling a plugin without uninstalling it

Set $config['plugins']['disabled'] = ['vendor/name'] in data/settings/custom.scriptor-config.php. The plugin stays in vendor/ but PluginManager skips it. Useful when bisecting a suspected plugin bug without touching Composer.

Uninstalling plugins

Reverse of the install path you used.

Host install:

composer remove bigins/scriptor-markdown-pages

The plugin disappears from vendor/composer/installed.json, the discovery cache invalidates on the next request, and the editor modules + nav items the plugin contributed are gone.

Docker: drop the plugin from your SCRIPTOR_PLUGINS build arg in the compose override (or remove the whole arg block if it was the only plugin), then rebuild:

docker compose up -d --build

The new image is built without that composer require step, so the plugin never lands in vendor/.

Plugin-owned data is not removed. Content trees, settings, uploads, or database rows the plugin manages stay where they are. Check the plugin's README for its on-disk footprint and delete those paths manually if you want a clean state. For bigins/scriptor-markdown-pages that means the per-theme content/ directories with _index.md files.

Security notes

  • The install command only runs from the command line. A misconfig that exposed bin/scriptor over HTTP would still be refused at the SAPI check on the first line of the script.
  • There is no default admin password. The command rejects passwords under 8 characters and a small blocklist of obvious defaults. The editor's login flow rate-limits failed attempts via LoginAttempts, so the 8-char floor plus lockout is the real brute-force defence; the blocklist is a copy-paste catch.
  • The "already installed" check looks at the actual database, not a lock-file. An attacker who can delete files under data/ cannot trigger a re-install that would overwrite credentials.

For the full security rationale and the design alternatives that were considered, see docs/scriptor-install-cli-plan.md.

Troubleshooting

"Category with slug 'pages' not found"

You started the web server before running bin/scriptor install. iManager auto-creates the schema on first PDO connection, but it does not seed any rows. Stop the server, run the install command, then start the server again. Or just delete data/imanager.db and run the install command, which is faster.

"Refusing to proceed: stdin is not a TTY"

Add --yes and supply a password via --password or SCRIPTOR_ADMIN_PASSWORD. The confirmation prompt only makes sense when a human is at the keyboard.

"Invalid admin password: too short"

The minimum is 8 characters, matching iManager's PasswordFieldType. There is no override; pick a longer one. The editor's login rate-limiter is the real brute-force defence, but the floor stops the most obvious typos.