Pyrite ITMenu Download the alpha
Documentation index

Documentation · For the administrator

Administrator guide

From the first launch to day-to-day operations. Each procedure tells you where to find it in the engine console and, where relevant, whether you need to be an Owner or an Admin.

01 /Requirements

02 /First start

  1. Copy the folder where you want to keep it, then double-click pyrite.exe.
  2. The engine starts in the background, without a black window: a Pyrite icon (the cubes of the logo) appears in the notification area, near the clock (if you don't see it, open the small arrow ^ next to the clock).
  3. The first time the program starts from a folder, Windows shows the “Windows Security” window: choose Private networks and allow. If you cancel, or choose only public networks, the other computers of the network can't reach the portal and the apps. Windows asks again for every new folder and for every program file with another name or in another place; a wrong choice is fixed in the Windows firewall settings (“Allow an app through Windows Defender Firewall”), or with pyrite.exe firewall open as administrator (see The Windows firewall).
  4. The browser opens by itself; on a new engine it shows the first-start page (http://127.0.0.1:8080/setup/), where you create the first Owner of the engine: the code of the first start (see below), your email, your name (optional) and a password with at least 8 characters, an uppercase and a lowercase letter, a digit and a special character. The Owner is a person of the directory, like everyone else.
  5. When the Owner is created, the engine console opens, already signed in. From then on: console at http://SERVER-NAME-OR-IP:8080/console/, portal at http://SERVER-NAME-OR-IP:8080/ for whoever uses the apps. Until the first Owner exists, the apps don't start.

If the browser doesn't open, open http://127.0.0.1:8080/setup/ by hand on this computer. If the page can't be opened at all (for example, a server without a browser), create the Owner from a command prompt in the folder: pyrite.exe owner create EMAIL prints a temporary password once; sign in to the console with it and choose a new one (see For technicians).

The code of the first start

The first-start page can be opened from any computer of the network, never from the internet, and only until an Owner exists. To create the Owner it asks for a code that Pyrite prints on the server, so that nobody else in the network can take the engine before you.

03 /The console and the levels

The console is the engine's management area: apps, people, groups, backups, events. Open http://SERVER:8080/console/: the sign-in page (/console/accesso/) asks for the email and the password of your account in the directory. Only Owners and Admins enter; the old address /_/ leads to the console, so old bookmarks keep working.

If you use Pyrite alone, you are the Owner: the levels below matter only when other people help you manage it.

In the console and in the portal you still find words meant for a company: they are the texts of the program, and for now they stay as they are. “IT” is whoever manages Pyrite; “colleagues” are the other people who use the apps; “the office” is the local network; “Tutta l'azienda” is the starting unit, which you can rename. An Owner can also change the title and the opening texts of the portal (“Company applications”), on the page Portal home page.

levelwhat they can do
OwnerEverything. All the apps (New app, Rescan folders, the Configuration tab, archiving, the approval of uploaded apps), people and groups of every level, the level of each person and the apps each Admin manages, engine settings, portal home page, analytics, backups of everything, the engine's events. At the top, Logs (the engine's log page with the chart) and Advanced: the engine's PocketBase tools inside the console (PocketBase settings: mail, storage, backups, crons, export and import of collections, SQL console with a warning; the registry data only for the collections that no console page manages, if there are any). The last active Owner can't be deleted, disabled or moved to another level.
People AdminThe people and the groups of their unit, and the name of their unit at the top. Doesn't see the apps. Sees and manages only the people and groups of that unit; only whoever manages all the units of a person can change that person. Has the History item: who created, renamed, stopped or reactivated the people of the unit, who gave a temporary password, the groups created and the members changed, the password changes and the console sign-ins of those people. Doesn't see the events of the apps, the engine's events, who became Admin of what, the network addresses, nor the events of a person who is also in a unit they don't manage. Doesn't read the name or the email of the Owners (“Owner” is shown instead). An Owner gives the role per unit.
App AdminTheir apps, given per unit or per single app: start, stop and restart, backups, data, access. Chooses the groups of the app's unit; gives access to a single person by typing their exact email in the app's Access tab (only people of the app's unit). Doesn't see the people. The App Admin of a whole unit can upload new apps into that unit; the App Admin of a single app can't. An Owner gives the role per unit or per app.
Admin (as in 0.7.5)Only the apps an Owner assigns: start, stop and restart, access and roles, backups, the app's logs, import and the Data tab. Sees the whole directory except the Owners, who appear as “Owner” without an email. Manages the people with the User level: adds them (initial password, to be changed at the first sign-in), changes name and email, gives a temporary password, disables and enables them, gives and removes access to their apps; every change is written in the events. Doesn't delete people and doesn't change levels; sees the other Admins but doesn't change them. Creates groups and changes their members only for the groups that give access only to apps they manage; the other groups are read-only. Can upload apps, which wait for an Owner's approval.
UserThe portal and the applications they have access to. Doesn't enter the console.

An Owner gives the roles in the person's card, box Units and roles: People Admin or App Admin per unit, App Admin for a single app, or Owner. The two Admin roles add up on the same person. The roles inside the apps (for example manager or storekeeper) are a different thing: they stay as they were and are set on the app's page, tab Access and roles.

The portal greets whoever has signed in (“Good morning, Anna.”, with the time of their computer and the first word of their name) and shows their apps as tiles, with a band in the color of each app; in the List layout of the home page the apps keep the small colored square. The home page is arranged from the console, in Portal home page.

04 /More customers on one engine: units

A unit is a closed group of people, groups and apps: for example a customer, a team or a site. With units one engine can serve several customers, and each one sees only its own things. At the start, and after the update from 0.7.5, there is one unit, called “Tutta l'azienda” (Italian for “the whole company”; the name is the same in both languages), and everybody is in it: if you don't create others, nothing changes for the people who use Pyrite.

Who sees what

What the engine does not show to someone who belongs to another customer

What belongs to another customer “does not exist”: the answer is the same as for a wrong address. The engine decides it, not the page: no answer carries data that the page then hides. This applies to:

Whoever manages without being an Owner never reads the name or the email of the Owners: the word “Owner” is shown instead. The title, the logo and the extra tiles of the home page stay the same for all customers.

How to create a unit

Units page (Owner only; the item is in the sidebar), New unit, a name. The name of a unit is unique. A unit can be deleted only when it is empty. “Tutta l'azienda” can be renamed but not deleted.

Rename “Tutta l'azienda” when you create the customers' units. It stays the starting unit: the people, groups and apps that nobody has moved are in it, and its name no longer tells the truth. It is also the unit of the apps shown in the portal before sign-in. From the Units page give it a name that says what it really contains.

How to move a person or an app

A person always has at least one unit, and a group and an app always have one: if a save (for example from the native card) leaves the field empty, it goes back to “Tutta l'azienda”.

05 /Two-factor authentication

It is a six-digit code, taken from an app on the phone, that you type after email and password. People who enter the console (Owners and Admins) can turn it on. The codes depend on the clock: the time of the server and the time of the phone must be right.

How to turn it on

  1. From the Profile, from the local network (not from the internet), box Two-factor authentication, Turn on: type your password.
  2. With a code app on the phone, scan the QR (or type the key by hand).
  3. Put aside the ten reserve codes (copy, download or print).
  4. Type the first code and tick I have put them away.

All sessions are closed: you sign in again with password and code. A code that has just been used is no longer valid: wait for the next one, at most 30 seconds.

How to sign in

If the phone is lost

  1. If you have a reserve code: sign in with it and, from the Profile, turn off the two-factor authentication (or make new codes). To make new reserve codes you need the code from the phone: whoever has lost the phone turns it off (a reserve code is valid there) and turns it on again.
  2. Otherwise an Owner opens the person in the People page and presses Remove two-factor authentication. You can't remove your own from there.
  3. If the one left out is an Owner and there is no other, from the server: pyrite.exe owner two-factor-off EMAIL, with the engine running or stopped. It works only for an Owner.

Who can remove it from whom

whofrom whomhow
the personthemselvesfrom the Profile, with the password and a code
an Owneranother personPeople page, Remove two-factor authentication
whoever has access to the serveran Ownercommand pyrite.exe owner two-factor-off EMAIL

An Admin who is not an Owner can't remove it from anybody else.

The key and the backups

The codes are protected with a key kept in control\doppia. On Windows the key file opens only on that computer. If the engine is moved to another computer, if Windows is reinstalled or if the key file is lost, whoever had the two-factor authentication is shown as “to be turned on again” and can't enter the console until it is removed: at start the history says who they are. An Owner frees themselves with the command from the server, then removes it from the others on the People page, and each one turns it on again. For this reason the control\doppia folder must be kept together with the rest of the engine data in every copy you make by hand.

With update-restore

The plan of update-restore (see Updating from 0.7.5) says who loses the two-factor authentication by going back, who gets back the one they had, and who is left out because the server's key was made again after the restore point.

06 /People and groups

wherePeople, Groups

In the parts that follow, “an Admin” means the Admin “as in 0.7.5”. The People Admin and the App Admin have narrower limits: what each level can do and see is written in The console and the levels.

Adding a person

Choose New person. For an Owner this opens a PocketBase record. Enter a name, email and initial password that meets the policy (at least one uppercase letter, one lowercase letter, one number, one special character and the minimum length in Engine settings). Then select the level in the same record. For an Admin the engine opens its own page. Enter a name, email and initial password using the same rules, or leave the password blank to generate one that the engine displays only once. The person is created at User level. They sign in to the portal with their email and initial password, then choose a password of their own. A password assigned by the administrator automatically requires a change at first sign-in. You can disable this requirement in the record (“must_change_password”).

Changing a name, email or password

An Owner can make these changes in any person's record. An Admin can edit User-level records. A password set here is temporary and the person must choose a new one at their next sign-in. Anyone can change their own password from the portal under Change password. If the administrator increases the minimum length, people with shorter passwords must replace them at their next sign-in. See Passwords and account recovery for forgotten passwords.

Deactivating a person

Deactivation immediately blocks the person from the portal, console and every app, including sessions currently in use. This is the fastest way to revoke all access when someone leaves. Admins can deactivate and reactivate Users. Only an Owner can delete a person.

Groups

A group brings together people who need the same access, such as a team. Grant access to the group once and it applies to all current and future members. Owners can create and edit all groups. Admins can create groups and change their membership only if the group grants access exclusively to apps they manage. Other groups are read-only for them, but they can grant or revoke any group's access to their own apps.

Importing people, groups and access permissions from Excel

On the People page, Owners and Admins who can create people can select Import from Excel. This opens Import people and groups, where you can load an entire team or company at once.

  1. Download the template in your language. It has four sheets. Groups contains Name (required) and Description. People contains full name, Email (required, one row per person), Level (User or Admin, blank means User, never Owner, and only an Owner can import Admins), Groups (separated by semicolons, missing groups are created) and Active (yes or no, blank means yes, no creates a disabled account). Access contains Group, App (ID, short name or name) and the optional Role. Instructions is the fourth sheet.
  2. Upload the file. Excel .xlsx and legacy .xls files up to 10 MB are supported, with up to 5,000 people and 1,000 groups. A CSV file is treated as a People sheet.
  3. The preview counts new and existing rows and lists errors with their row numbers. Any error blocks the whole import.
  4. Confirm to start the all-or-nothing import. A progress bar tracks it. The import only adds data. Existing records are unchanged and nobody is removed from a group or deactivated.
  5. Download the Excel file with the temporary passwords (to be changed at first sign-in) once only, within 10 minutes. The passwords are not stored elsewhere. If you lose the file, reset each person's password in their record. New users do not receive an email. Give them their passwords individually.

An Admin can add only User-level people, assign them to groups they can edit and grant access only to apps they manage. An in-app role belongs to an individual, independently of group access. The engine checks that the Role column names a role defined by the app. Once the import finishes, it assigns the role to new members of the group if the app is running. The results list any roles that could not be assigned because an app was stopped. Assign them from the app's Access and roles tab. Engine history contains a single summary entry without passwords.

Changes an Admin makes to people or groups appear in Engine history under that Admin's name.

07 /Granting and revoking access

wherePeople or Groups → record → App access

Access lets a person enter an app. Grant it directly to a person or to a group to include every member. App access has one switch per app. A person may have both direct access and access through one or more groups. Any single grant lets them in. Apps open to everyone have no grants to manage.

An Owner can grant and revoke access to all apps. Admins can do so only for apps they manage and never for an Owner.

The Access and roles tab on the app page shows who can enter and how. To change access grants, open the person's or group's record.

Revoking access

Revocation takes effect immediately across apps, even for people already signed in. The engine checks the session and access grant on every request.

08 /Roles within apps

whereApp page → Access and roles

A role, such as manager or warehouse clerk, defines what a person can do within a particular app and is managed there. It is independent of their console level and of groups, which determine who can enter.

Below the list, Other users inside the app shows accounts that exist in the app database but lack a central access grant. The engine blocks them at the gateway.

09 /People who already have app accounts

wherePeople → Import from apps (Owners only)

Use this only when apps already have accounts missing from the central directory. For example, an app might have had its own login before moving to the engine. Fresh installations with new apps do not need this step.

  1. Open People and choose Import from apps.
  2. The engine reads each app's existing users, adds missing people to the directory and grants them direct access to the apps where they already had accounts. Their existing in-app roles are preserved.
  3. The initial passwords of newly created people appear below the summary. The console shows them once. Copy them immediately and deliver them in person or through a private channel.
  4. Review the list and remove test accounts, duplicates and people who no longer use the apps.

10 /What an app can do

The scripts of an app (the pb_hooks and pb_migrations folders) run inside a fence: the engine stops them from doing many things. You don't have to choose anything: this chapter says what to expect.

The limit, stated plainly. The fence greatly reduces what an app's script can do, but it is a defence inside the program: the script runs in the same process as that app's engine, with the same Windows user, and every road has to be closed one by one. Against a script written on purpose to get out, the full guarantee will be to run each app with its own Windows user, which can't touch the files of the others even if it gets out of the fence. This is not in this version; it is planned for a future version. Until then, apps of different customers on the same engine are fine if the scripts are written or checked by whoever runs the engine. Don't upload scripts written by someone you don't trust relying only on the fence.

11 /The icon near the clock

12 /Where things are

Everything stays in the folder of pyrite.exe; the engine creates the folders at the first start.

folderwhat is there
control\pb_data\the engine's data: people with their levels, groups, who can enter which app, settings, the list of the apps, the engine's logs and events
control\pb_data\backups\backups of the engine's data (every night at 3:00; the last 7 are kept) and the copies made by earlier versions before an update of the program (pre_migrazione_…zip, to delete by hand; an update makes a restore point in control\aggiornamenti\)
apps\<app>\one folder for each app: app.json (its card), release\ (its code)
apps\<app>\state\pb_data\the app's data (its own database and uploaded files)
apps\<app>\state\pb_data\backups\the app's backups (every night at 3:00 for the apps that are running; the last 7 are kept; manual backups from the app's Backups tab)
apps\<app>\logs\worker.logthe output of the app's process (also in the console: app page, Status tab)
logs\engine.logthe engine's messages; up to 10 MB, the 3 previous files are kept
control\aggiornamenti\the restore points of the engine updates (the last 2 are kept) and the copies set aside before going back to a previous version (folders ritorno_…: the engine never deletes them, and the engine's Backups page lists them; delete them by hand when they are no longer needed). They contain personal data (people, password hashes, all the apps' data): when someone's data must be deleted, delete them here too.
apps\<app>\logs\network.logthe network calls of the app's scripts (address, size, time: never the content); also in the console, app page, Outbound network tab
archivio\apps archived from the console, each with all its data (page Archive: restore them or delete them for good, see The Archive page)
control\copia_rete.jsonhow the last copy of the backups to the network folder went (the page and the Overview read it from here; see Copy of the backups to a network folder)
control\doppia\the key that protects the codes of two-factor authentication (see Two-factor authentication)
control\biglietti\the key of the portal sign-in tickets: not to be copied together with the registry backups (see Updating from 0.7.5)
control\passaggio-ruoli.txtthe summary written at the first start of 0.7.6: who is an Owner, who is an Admin and of which apps
control\pyrite.jsonthe network rules of the engine and its identifier (see Network rules)
control\storico\the engine history (storico.db) and, in copie\, its nightly copies; control\storico-fuori.jsonl keeps the events that could not be written there (see The engine history)

Events are read in the console: Owners see all of them in the Engine history (side bar, see The engine history) and in Logs (at the top); Admins see the events of their apps in the Engine history, on the overview and on the app pages. Each app's page has a Logs tab with the requests that reached the app. To back up everything by hand, stop the engine and copy the whole folder.

13 /Loading and starting an app

Apps arrive as a zip file (for example from an AI agent that follows the agent standard).

  1. In the console, open Upload app in the side bar and choose (or drag) the zip.
  2. The engine checks it step by step. Three steps are real checks (the package, the app.json card, the folder structure); two, “Security check” and “Compatibility with the standard”, are marked demo in this alpha: their score is simulated. Review the app yourself before starting it. In the app.json step the summary also lists, as information, the tools the app opens to its pages and for whom, and the network addresses it wants to reach: read them before installing. A package with routes under /api/tools/ is refused: that path belongs to the engine. The id of an app can't be a name of the engine (console, archivio…) nor the name of a Windows device (con, nul, com1…). Files named pyrite-archivio.json or pyrite-ripristino.json next to app.json are not installed (the summary says so): the engine keeps those names for the Archive.
  3. Read the summary and the delivery notes, then press Install. The app is installed stopped and doesn't appear in the portal yet.
    • Uploaded by an Owner: it can be started right away.
    • Uploaded by an Admin: it is waiting for approval and the Admin manages it. Until an Owner approves it, nothing starts it and it isn't in the portal. Owners find it in Apps waiting for approval on the overview and on the app's page (who uploaded it and when): they review it and press Approve. To refuse it, an Owner presses Reject (see Apps waiting for approval).
  4. On the app's page press Start. Then give access to people or groups (People, Groups) and, if the app has roles, set them in the Access and roles tab. Look also at the tabs Tools for pages (what the pages may use, and who; there you also see the Jobs started from the pages, which you can Cancel) and Outbound network (the addresses the app reaches). In a public app that needs users (for example the people who may write), create them in the Data tab (see Sign-up to the apps).

To try, there is an example app, example-parts-pricelist.zip: it is the one of the agent standard, with sign-in and two roles, port 8105.

An Owner can also install an app by copying its folder into apps\ and pressing Rescan folders.

Load app and the port

The port written in app.json is a request. In the summary of Upload app:

Apps waiting for approval

Updating an installed app

A new version of an app arrives as a zip with the same identifier. Start from Upload app, or from Update from zip in the Configuration tab of the app (from there, the zip of another app is refused).

  1. The engine makes the usual checks and then shows what changes compared with the installed version: versions, fields of app.json, new migrations. Nothing is touched yet. A migration that has been renamed or removed, and a new app.json that widens permissions (access that becomes public, new addresses in network, new toolAccess or tools, new roles), are a strong warning: read it, and go on only if you are sure. An Owner approves exactly the package seen in the summary: if an Admin uploads another one meanwhile, the page shows the new summary. A package with a state folder is refused: the data are never replaced.
  2. An Owner presses Update now. An Admin who manages the app sends it for approval: the current version keeps running until an Owner approves or rejects it in the same page.
  3. All or nothing: the app stops (scheduled jobs in progress are interrupted, as with a restart), a safety copy of release, app.json and the app's data (the whole state folder, without temporary files) is made in control\aggiornamenti_app\<app>, out of the app's reach, the files are replaced, the new version starts, applies its migrations and must answer. An app that was stopped starts only for this, then stops again.
  4. If something fails, everything goes back by itself as it was, data included (checked with the fingerprints), the previous version restarts and the page says why. If the engine or the PC shuts down halfway, the engine puts back the previous version at its next start, before starting the apps, and writes it in the events.

Afterwards an Owner can press Go back to the previous version in the same tab, typing the app's identifier. The data written after the update are lost for the app: first the state of that moment is copied aside in a da_parte_… folder, which whoever manages Pyrite can read by hand. For each app the engine keeps the copy of the last successful update and the last copy set aside (two folders at most, each as big as the app's data). The port goes back to the one it had before the update, too: if you changed it in the meantime from the Configuration tab, change it again from there after going back; the summary shown before going back says so. They hold personal data: to delete a person's data for good, delete them there too, by hand.

Archiving the app. The safety copies don't go into the archive entry: they move to control\aggiornamenti_app\_archiviate\<entry>, the Archive page shows them with the entry, and they are deleted when you delete the entry. After a restore from the archive, Go back to the previous version isn't offered any more. Copies of an app whose folder is gone are set aside at the engine's start and written in the events at every start, until you remove them.

App stopped after an update. If the previous version couldn't be put back (full disk, a file held by another program, a damaged copy), the app stays stopped with the marker control\aggiornamenti_app\<app>\in_corso.json and the engine tries again at every start. Remove the cause and restart the engine. If that is not enough: with the engine stopped, copy by hand release, app.json and state from file\apps\<app> of the copy named in the marker, then delete in_corso.json. Without the marker the engine doesn't delete that copy any more: it writes it in the events at every start, and you remove it when the app works. update-restore doesn't start while there is a marker: start the engine once first.

14 /Editing an app

whereApp page → Configuration (Owners only)

You can change the name, contact person, description, access mode, version, port, memory limit, roles and default role. The previous manifest is saved alongside the new one as app.json.prima. Changing the port, memory, access or roles automatically restarts the app within a few seconds. Meanwhile its port returns an “updating” message. Editing app.json manually and clicking Rescan folders has the same effect.

Roles work only if the app has a user role field (auth.roleField in the manifest). If it is missing, Configuration shows a notice beneath the roles field.

The same tab lists the checks recommended by PocketBase for production deployment. Rate limiting can be enabled with one click.

To update an app from a zip see Updating an installed app.

Updating app code manually

  1. Make a manual backup of the app.
  2. Replace the files inside apps\<id>\release. Leave state, which contains the data, untouched.
  3. Restart the app from its page. New migrations run at startup. Then check Status and Logs.

15 /Engine tools

whereTools, or App page → Configuration → Engine tools (Owners only)

Engine tools handle intensive tasks for app scripts without requiring extra programs or libraries. Eight tools are available: Excel and CSV import, Excel and CSV export, PDFs, photos, numbering, change history, statistics and scheduled jobs. Email and notifications, and reservations, are planned.

Console imports need no extra tool to be enabled. Every database app has an Import tab.

16 /Importing data from Excel or CSV

whereApp page → Import (Owners and Admins of the app)

  1. Upload an Excel .xlsx or legacy Excel 97–2003 .xls file, a CSV or JSON (.json, .jsonl, .ndjson). The size limit is 100 MB, or 128 MB for JSON. Password-protected files, Excel 95 or earlier formats, damaged files and Word or PowerPoint documents renamed to .xls are rejected with a message. Reopen them in Excel and save as .xlsx. Excel files can contain at most 5,000,000 distinct strings and 256 MB of text. Beyond that the engine reports “too much text”. Split unusually large files or save as CSV.
  2. Choose the format. For CSV, choose the separator (semicolon by default). For Excel, choose the sheet and layout. In data only, data begins on the first row and columns are named A, B, C and so on. With column titles, the first row supplies the names. With a header section, select the number of initial rows to skip in the preview. The next row supplies the column names and the one after starts the data.
  3. Check the preview for columns, inferred types, sample rows and warnings.
  4. Choose the collection and review the engine's proposed column-to-field mappings. A key, such as a registration number, allows the next import to update existing records instead of duplicating them.
  5. Run a trial. It validates everything without saving. Errors include the row number and reason.
  6. Import the data. The progress display stays visible until you see the result. Save the settings as a recipe to reuse them for next month's file.

Each import appears in the tab's history with the name of the person who ran it. Undo removes newly created records and restores updated records to their previous values. Both imports and reversals also appear in Engine history.

Imports write directly to the app database

Field validation still applies (required fields, formats, allowed values). Automatic rules triggered when someone enters a record through the app's pages do not run. Examples include sequential numbers, author, status and capitalization. Supply these values in the file or fix them afterward. Always run a trial first and back up the app before a large import.

Importing an entire file

At the Destination step choose One collection or The whole file, the default even for a single sheet. In The whole file mode the engine examines each sheet (or list in JSON) and suggests:

The engine selects the key for matching existing records only when unambiguous: a unique index provided by the app, or, in a collection without any single- or multiple-value relationships in the file, a code, registration number or name whose values are all distinct and nonempty. It never chooses a key automatically for a related collection, such as order lines or items in a category. This prevents updates to another order's line. A warning suggests a manual choice, for example “order + item”. Save that key in the recipe so subsequent imports of the same file match and update the records. If a key matches multiple existing records the row is skipped with a reason. The same applies to an ambiguous relationship, such as two orders called “O-1”.

Preview (nothing is saved) shows what each collection would create, update, leave unchanged or skip, including row numbers and an estimate of how many seconds other app writes would wait. Import all becomes available after a successful preview. It is all-or-nothing, in two phases. Validation runs outside a transaction. Writes run in a single transaction limited to 50,000 rows across all sheets and 60 seconds of writes. If a limit is exceeded nothing is saved, and the engine asks you to split the file or import one collection at a time. Any invalid row prevents the import unless you choose Load the good rows anyway.

Stop interrupts a running job. Stopping a multi-collection import leaves nothing saved (“Import stopped: nothing was saved”). For a single collection, batches already saved remain and can be removed with Undo.

Undo in the history reverses the entire import as one operation. It stops without making changes and lists up to 20 affected records if other records reference the imported ones (for example, someone entered an order for an imported supplier). You cannot force that undo. It also stops if records have changed since import. For those changes, Undo anyway is available with confirmation.

The tab also shows the app's policy: “The app allows console imports only into …”. The app developer sets import.consoleCollections in app.json. Without this field, the console can import into every collection like the server, and the tab warns you. Recipes marked “app package” come from the app's release/import folder. You can use them but cannot delete them. Save the recipe lets you repeat the import with one click next month.

A blank cell in a number column leaves the existing number in place and produces a warning. Enter 0 to clear the number. JSON accepts an array of objects, an object containing several arrays (one “sheet” per array), or JSON Lines. Use dot notation for nested values (supplier.name).

“Import preview” for users

Signed-in users can open the “Import preview” tile from the portal home page. Upload a file to preview how the engine will read it using the same format options, without importing any data. The engine stores the file temporarily and deletes it two hours after its last use. This helps users prepare a file before asking the administrator to import it.

17 /The portal home page

wherePortal home (Owners only)

The left side previews the home page as users will see it. Settings are on the right. Choose Save to apply changes to the portal.

New apps appear at the end or in Other applications until you arrange them. Hiding a tile changes its visibility on the home page only. The app remains reachable on its port and its access rules still apply.

18 /Sign-up to the apps: decided by whoever manages Pyrite

No app lets people sign up by themselves, not even the public ones: whoever manages Pyrite decides who has a user in an app.

19 /The Archive page

An Owner archives an app from its page, Configuration tab: the engine stops it, copies its whole folder (code, data, users of the app, backups) into archivio\, checks the copy and only then removes the app from the engine. The Archive page (for the Owners) lists the archived apps: when and by whom, the space used, whether the copy was checked, who could enter back then, the engine version.

20 /Backups

whereBackups for all apps, or App page → Backups for one app

Keep a copy off the server

Backups live on the same disk as the apps. If that disk fails, the data and backups are lost together. You can enable copying backups to a network folder, such as a NAS. Backups are copied to another disk daily and the Backups page shows the last successful copy. If you do not use network copies, download important backups regularly and keep them elsewhere.

The Engine updates panel on the Backups page lists restore points created when a new pyrite.exe is installed (control\aggiornamenti), and the ritorno_<data> folders that update-restore sets aside before a rollback. They contain personal data and app data written after the update. The engine never deletes them automatically. Remove them manually when no longer needed.

21 /Restoring from backup

whereBackups → Restore on the selected backup

The engine restores the app in four steps:

  1. It stops the app.
  2. It copies the current data to apps\<id>\state\copia_prima_del_ripristino_<data>.
  3. It replaces the data with the contents of the backup.
  4. It restarts the app if it was running. An app that you stopped with Stop stays stopped until you select Start.

Data returns to the point in time represented by the backup. Anything written afterward exists only in the safety copy.

The engine keeps the three most recent safety copies per app. Configure between 1 and 50 under Engine settings → Backups and restores. It removes older copies only after a successful restore and records each removal in Engine history. The ritorno_ folders created when rolling back the engine are never removed automatically (see above).

22 /Passwords and a forgotten password

23 /Network rules

The console page Network rules (group System, for Owners only) gathers all the network settings of the engine in one place. Every section saves by itself and says whether the change holds at once or from the next start. If you change nothing, the engine works as in 0.7.4. The settings are kept in control\pyrite.json. pyrite.exe network status shows the rules in use; with the engine stopped, pyrite.exe network reset goes back to the values of 0.7.4 (the file you had stays in control\).

Where the apps listen

Every app has its own port. The port can stay open on the whole network (as in 0.7.4), listen only inside the server (people then reach the app through the engine, with the names) or listen on an address you choose. The change holds at once, without a restart: whoever was using an app finishes what they were doing. Before you save “only inside the machine” the page warns that the other people lose the address name:port. An address that does not exist on the server can't be saved. In the same section you choose the port the new apps start from.

A name for each app

By default the apps are reached with the computer name and a port (http://SERVER:8105/). In The addresses of the apps you can choose one name for each app instead, all under one domain used only for Pyrite, for example app.example.com: the portal is there, and every app has its name under it (booking.app.example.com: the id of the app, or the name chosen in its Exposure tab). Don't write your whole domain (example.com): the single certificate for the apps would be valid for all the sites of that domain (mail, VPN, website).

The entrance from the internet

It is off until you turn it on. The choices are Off, Tunnel (for example Cloudflare), Port open on the router or public address and An existing proxy (nginx, IIS…).

If the internet arrives where it shouldn't. If the router or a proxy sends by mistake the traffic of the internet to the network entrance, Pyrite says so in the events, in the Overview and in the Network rules page, with the last addresses seen. It only warns and blocks nothing: whoever arrives from there is treated like someone in the local network. Fix the router or the proxy.

Which apps are seen from the internet

Every app has its own choice, Local network only or Internet too, in the Exposure tab of its page. New apps start as “Local network only” (except when the users arrive only from the internet).

The two questions and the command pyrite.exe network setup

Two questions choose the starting values: Where is the server and how do you get there (From a private network or Only from the internet, for a VPS) and Where do the users come from (From the local network, From the internet or From both, app by app). The answers only choose starting values, and Pyrite shows what would change before you apply them (Show what would change, then Apply these rules); after that you change every item on its own. You answer them at the first start, from the page (Answer the questions again) or, on a server without a screen, from a terminal with pyrite.exe network setup (with the engine stopped; on Windows from cmd type start /wait pyrite.exe network setup, or give the options and --yes: network setup -h lists them).

24 /The Windows firewall

For the other computers to open the portal and the apps, the Windows firewall must let pyrite.exe in. Pyrite now reads how the firewall is, shows it, and can make the rule. It uses one rule for the program (inbound, private and domain networks), not one for each port: it covers the engine, every app and the apps of tomorrow. It is called Pyrite (pyrite-…), with the name of the service.

When the rule is made

The box “Windows firewall” in Network rules

At the top of the Network rules page the box says in one sentence how the firewall is for Pyrite:

“Lets Pyrite in” and “open” always mean “if the network of this computer is marked as private or domain”. Below the state the box lists the apps switched on in the network, each with its port: open, closed by the firewall or not known. The button Open Pyrite on the local network is there only if all these are true: the state is “No rule” or “Only some ports”, whoever looks is an Owner, the page is opened from the computer of the engine, Pyrite runs with the icon (not as a service), somebody is in front of the screen, Pyrite was not started as administrator (Windows would ask for nothing), and Windows on this computer is not set to give administrator rights without asking (if Pyrite cannot read the setting, there is no button). When you press it and confirm, Windows shows its own request, and it is for netsh.exe, a program of Windows, not for pyrite.exe: Pyrite itself never runs with administrator rights because of the button. One request at a time; no black window. The result (rule made, not made, request refused) is written in the History within two minutes; then reload the page. In every other case the box does not show the button but the command to give by hand on the server (pyrite.exe firewall open as administrator): when Pyrite runs as a service, when nobody is in front of the screen, when Pyrite is already started as administrator, when Windows gives administrator rights without asking, and in the states Blocked and Forbidden the command is not enough either.

The limits

25 /Sign-in: one sign-in, wrong attempts, the console

One sign-in even with a name for each app

When every app has its own name (for example booking.app.example.com), whoever opens an app without being signed in goes through the portal, types the password once and comes back to the app by itself. The step uses a code that works once, for one minute, only for that app and only in the browser that asked for it. No cookie is valid for the whole domain. With name + port (the usual way) nothing changes.

Several engines on the same server

Every engine has its own cookies, so two engines on the same server (on different ports) no longer throw each other out. Whoever was signed in before the update stays signed in. Be careful: a folder of the engine copied as it is carries its identifier with it, and the two copies on the same server go back to throwing each other out.

Wrong attempts

The engine counts the wrong passwords for every real address, also behind a tunnel. Whoever makes mistakes from the internet no longer blocks the people in the local network.

The console only from some addresses

In Network rules, section The console, you can say from which addresses or networks the console opens (for example the VPN, or only the server itself). Empty means from the whole network. The list must also include the address you are using now. From another address the sign-in page says so at once, before the password. The portal stays open to everyone.

The console closes by itself

After 30 minutes without use the console asks again for the password (and for the code, for whoever has two-factor authentication). The page goes back to the sign-in by itself and writes “Session closed after N minutes without use”. A page left open on a screen that nobody touches doesn't keep the session alive: only what the person does counts.

26 /HTTPS and certificates

Without a certificate the engine works in HTTP: passwords and data travel in clear text on the network, and the Overview says so. From Engine settings → Certificates (Owners only, in both console layouts) you turn HTTPS on. One certificate is enough for the engine and for every app port: a certificate is valid for a name, not for a port. Today's addresses (http://SERVER:8080/, http://SERVER:8105/, bookmarks) keep working: the engine sends them to https:// on the same port. The apps' processes stay in plain HTTP on 127.0.0.1, inside the server. At the top of the page: the mode, the names covered, the expiry, who signed, and Check (a real test of every port). First write the names and addresses people use to reach the server: the computer name, the full name in the domain, the IP address.

  1. a. No certificate (HTTP): the engine keeps working in HTTP. Fine only for a test.
  2. b. Request for the company CA (Active Directory Certificate Services, AD CS, or another CA).
    1. Is there a CA? On a PC in the domain, in a command prompt: certutil -dump (or certutil -TCAInfo). An entry Config: with a server and a CA name means yes. If nothing is found, use the internal CA (d).
    2. Create the request: the private key is born on the server and never leaves it. Download the request (pyrite.csr).
    3. Have it signed, on a PC in the domain, as someone who may request certificates: certreq -submit -attrib "CertificateTemplate:WebServer" pyrite.csr pyrite.cer (a window asks which CA). If it waits for approval: the CA administrator approves it, then certreq -retrieve RequestId pyrite.cer. Or with the web page of the CA: http://CA-SERVER/certsrv → Request a certificate → advanced certificate request → paste the text of pyrite.csr → template Web Server → Submit → Base 64 encoded → Download certificate (or the chain, .p7b).
    4. Upload the .cer, .crt, .pem or .p7b you received: the engine checks that it belongs to the request and covers the names, then uses it at once. The domain PCs already trust an enterprise CA: nothing to distribute.
  3. c. Upload a file: a .pfx/.p12 with its password (both the ones Windows exports today, AES-256 with SHA-256, and the old ones, 3DES or RC2 with SHA-1), or .pem (certificate and key, in one file or two). The engine checks that the key belongs to the certificate, that it is valid today, that it is for a web server, that the key is strong enough and that it covers the names; if it covers only some names it asks before using it. The password is used only to open the file and is not written anywhere. If a .pfx is still refused: openssl pkcs12 -in certificate.pfx -out pyrite.pem -noenc and upload the .pem.
  4. d. Internal CA created by Pyrite: Create the internal CA creates a certification authority and the server certificate (with the names, plus localhost and 127.0.0.1) without turning HTTPS on: first distribute the CA to the PCs, then press Turn HTTPS on. The server certificate lasts 397 days and renews itself 30 days before it expires, with the same CA. The CA may sign only web server certificates and only for these exact names and addresses (a new name needs a new CA, and a new CA must be distributed again to all the PCs: so first choose all the names, the engine's and, if you want them, the domain of the apps, and only then create the CA): if someone stole its key, they couldn't pretend to be internet sites or other servers of the domain, nor sign programs. Replacing the CA (New CA), the key of the previous one is deleted at once; its public certificate stays for reference (remove it from the PCs). Distribute pyrite-ca.cer to the PCs with a group policy:
    1. download it from the page (Download the CA certificate);
    2. on a server with Group Policy Management (gpmc.msc): create (or edit) a Group Policy Object linked to the organizational unit of the PCs, or to the domain;
    3. Computer Configuration → Policies → Windows Settings → Security Settings → Public Key Policies → Trusted Root Certification Authorities → right click → Import → pyrite-ca.cer → Next until the end;
    4. the PCs receive it at the next policy refresh (at restart, or within about 90 minutes; at once with gpupdate /force);
    5. check on a PC: certlm.msc → Trusted Root Certification Authorities → Certificates: the Pyrite CA is there, with the thumbprint shown on the page.
    By hand, on a PC outside the domain: double click pyrite-ca.cer → Install Certificate → Local Machine → Place all certificates in the following store → Trusted Root Certification Authorities. Edge and Chrome use the certificates of Windows; Firefox too in recent versions (otherwise import it in its settings).

What people see the first time. With a certificate the PCs trust (company CA, or the internal CA already distributed): the padlock and nothing else; the old http:// addresses go to https:// by themselves, and people sign in to the portal once more (the sign-in of the plain address doesn't carry over). With the internal CA not yet on the PCs, the browser says the connection is not private: distribute the CA first, then turn HTTPS on, and don't teach people to click through the warning. Whoever arrives with a name the certificate doesn't cover (for example the short name when only the full one is in the certificate) sees the warning: the Certificates page and the Overview list those names.

Expiry. The engine checks every day: in the Overview and in the events at 30, 14, 7 and 1 day before; an expired certificate is shown in red. Nothing is turned off by itself.

Emergency exit. If HTTPS is misconfigured and the console doesn't open from the network: from the server itself the console always opens in plain HTTP at http://127.0.0.1:8080/console/. If not even that works: stop the engine (icon → Exit) and in a command window in the folder type pyrite.exe certificates off (pyrite.exe certificates status says how it is set). At the next start the engine works in HTTP; the certificate stays, and you turn HTTPS back on from the page. If HTTPS is on but the certificate can't be read (for example after moving the engine to another computer), or the certificates state file is damaged, the apps don't answer in clear text from the network (closed by default): they show a page that says to tell whoever manages Pyrite. With a damaged state file the page offers Repair the state (it keeps a copy of the damaged file and rebuilds the state from the folders, internal CA included); certificates off repairs it too. Going back to HTTP, people sign in again with their password: in HTTPS the sign-in cookie has another name (__Host-), so it doesn't get in the way. On the server itself the icon and the small window always open http://127.0.0.1, so there is no certificate warning there.

Where the keys are. In control\certificati\. Only SYSTEM, the Administrators and the account the engine runs as can open that folder (the engine sets these permissions, without inheriting those of the engine folder); if the engine later runs as another account, give that account control of the folder (icacls) or create the certificate again. The keys are also protected with Windows DPAPI of this computer: that protects against copying the files to another computer, not against the other users of this one (that is the job of the folder permissions). No route of the engine serves them; they are not in the events, the logs, the backups or the restore point of the engine update, and an engine update or update-restore doesn't touch them. Moving the engine to a new computer: create the certificate again (with the internal CA, a new CA to distribute again). HSTS is off by default; turned on (page, More), the browsers that see it refuse plain HTTP for that name, on every port, for 180 days, even after certificates off. To go back to HTTP after HSTS: turn HSTS off and leave HTTPS on for a few days; for 180 days the engine tells the browsers that come by in HTTPS to forget the rule.

27 /Let's Encrypt, Cloudflare and more certificates

All of this is in the Certificates page (HTTPS and certificates), for Owners.

More than one certificate

Pyrite can keep several certificates and chooses by itself the right one for every name: first the exact name, then the one with an asterisk, otherwise the default one. To add one: Certificates → Upload a file → Add it next to the default one, for its own names. In the same page you choose which one is the default (Use as the default certificate) and remove the ones you don't need. Without extra certificates nothing changes.

One certificate for all the apps

A certificate *.app.example.com is valid for all the apps under app.example.com (booking.app.example.com, orders.app.example.com…), on one level only, and the names of the single apps don't end up in the public registers of the certificates. You can get it from Let's Encrypt (below), from the company CA (write *.app.example.com among the names of the engine) or from the internal CA: with the names on, the internal CA also covers the domain of the apps and the names of the portal. If the CA was created before, the page says a new one is needed, to be distributed again to the PCs.

Let's Encrypt with Cloudflare

Suggested; it also works for the apps used only in the local network.

  1. Certificates → Let's Encrypt and the DNS → open the Let's Encrypt account (Open the account: accept the terms of use; the email is optional).
  2. Put the Cloudflare key (Cloudflare key for the check in the DNS, then Test and save). The smallest key: on Cloudflare, My Profile → API Tokens → Create Token → Edit zone DNS (Zone · DNS · Edit), only the zone of your domain and, if possible, with the filter on the public IP address of the server. A key of the account works too. Pyrite tests it at once (it writes and removes a test record) and then never shows it again: you only see its last characters. It stays only on this server, protected like the keys of the certificates; if the engine moves to another computer, put it back.
  3. Certificates from Let's Encrypt → Request the certificate (by default the single certificate for the apps plus the portal). The page follows the steps while they happen.

For more separation: a separate domain used only for the checks, and in the DNS of your domain a CNAME _acme-challenge.app.example.com pointing to _acme-challenge. followed by the domain for the checks; with a split internal DNS, the same CNAME in the internal DNS too. Before the first real request Pyrite makes a trial run with the test environment of Let's Encrypt, so a mistake doesn't use the limits. The “test” account is only for trying: its certificates are not put in use.

Let's Encrypt with port 443

Without Cloudflare, only with the port open to Pyrite: the router sends the public port 443 to the internet entrance of Pyrite (Network rules, open port) and Pyrite answers the check by itself (Request with port 443). It makes one certificate for every name on the internet (the portal and the apps open to the internet), with no asterisks; with a tunnel or a proxy you need the DNS. Pyrite doesn't use port 80.

Renewal and notices

Going out to the internet

Let's Encrypt and Cloudflare are reached in HTTPS (port 443 going out). If your network goes out through a proxy, put it in the environment variable HTTPS_PROXY of the user Pyrite runs as. The check that the record has spread uses the DNS (port 53 going out, to the Cloudflare servers): if it is closed, Pyrite waits a minute and goes on.

Tunnel or proxy in front

If the HTTPS from the internet is done by the tunnel (for example Cloudflare) or by a proxy, the Overview says so instead of the notice “you are in HTTP”. To protect the local network too, turn on the HTTPS of Pyrite anyway (for example with Let's Encrypt through the DNS).

From the internet with an open port

From the internet, public certificates only. With the port open on the router, Pyrite never shows the certificate of the internal CA from the internet, nor a certificate that contains internal addresses (192.168…, 10…, 127.0.0.1) or the name of the computer without a domain. Whoever connects without a name (by IP address, as the scanners of the internet do), with a name that Pyrite doesn't have, or with the name of an app only for the inside receives no certificate: the connection closes at once (a connection error in the browser). The same happens for the portal and for the apps open to the internet, until they have a public certificate for their name (Let's Encrypt, or an uploaded one). Note: if the internal CA covers that name, the Certificates page shows it as covered even though it doesn't open from the internet: always check from outside. So from the internet the names and the addresses of the internal network cannot be read. From the network, from this computer and with a tunnel or a proxy in front nothing changes.

If something goes wrong

28 /The engine history

The events of the engine (who started an app, who gave an access, who signed in to the console, who changed a setting…) are now in a history of their own, the file control\storico\storico.db, outside the registry. From the console nobody deletes or changes them, not even an Owner: emptying the technical logs or putting back a backup of the registry doesn't touch them.

29 /Copy of the backups to a network folder

The backups (every night, of the engine and of the apps) stay on the engine's disk: if that disk breaks, they are lost with it. Engine settings → Copy of the backups to a network folder (Owners) copies them every day to a network folder (a NAS, a shared folder of a server) or to another disk.

Setting it up

  1. On the NAS make a shared folder only for these copies, for example \\nas\backup\pyrite, closed to everyone else (see Security).
  2. Give the permission on it to the account the engine runs as (see Permissions).
  3. In the console: Engine settings, section Copy of the backups to a network folder. Write the folder (\\nas\backup\pyrite; another drive such as D:\pyrite-copies works too, but not a mapped letter such as Z:: it exists only for whoever mapped it), the time (default 05:00, after the nightly backups at 3:00: both are the computer's time), the days and the months to keep, turn on Copy every day and Save. The folder can't be inside the engine's folder nor in a Windows folder; if it is on the same disk as the engine the page warns you.
  4. Press Test the folder: it writes a test file, reads it back, compares it and removes it, and tells the free space and the account. Then Copy now and wait for «Last copy done».

What ends up in the folder. The engine writes only in <folder>\<COMPUTER NAME>, with the same paths as in the engine's folder: control\pb_data\backups\ (backups of the engine registry: people, access, settings, list of the apps), apps\<app>\state\pb_data\backups\ (backups of the apps), apps\<app>\app.json and release\ (the code of the apps), archivio\ (the archived apps, which exist only there) and pyrite-giri\ (one manifest per copy: date, files, SHA-256 fingerprints, outcome). Not copied: the keys in control\certificati (they belong to the computer), the safety copies of the app updates (control\aggiornamenti_app), the restore points of the engine (control\aggiornamenti), the logs, and the data of an app outside its backups. Nor the native automatic backups of PocketBase (names starting with @auto_pb_backup_, which exist only if someone turned them on in the native settings of an app or of the engine): they hold the same data as Pyrite's nightly backups, which are all copied and are enough to put back the registry and the apps. There is also pyrite-versioni\<date>\: the previous version of a file of the code or of the archive that changed or was removed in the engine.

How it copies. Every file all or nothing: written with a temporary name, read back from the folder and compared with the original (SHA-256), and only then renamed to its final name in the folder; the originals are never touched. A file already there and equal is not copied again. The old copies are removed only after a copy where every file was copied and checked, and only the files the engine wrote (listed in its manifests): never other files of the folder. With the defaults you keep every backup of the last 14 days (twice the 7 the engine keeps on its disk) and, for the 12 months before, the most recent of each month for every app and for the registry; archived apps stay while they are in the Archive and for 12 more months after you delete them for good; the code of the apps is always the current one. One copy at a time, at most 8 hours (the files already copied stay: the next copy goes on from there); if the nightly backups are still running, the copy waits for them. It is the scheduled job pyrite_copia_rete of the engine (Advanced → Crons). All the scheduled jobs of the engine count in the computer's time; those of the apps stay in UTC. If the engine is off at the time of the copy and the last copy done is more than 24 hours old, the copy starts by itself 10 minutes after the engine starts; a copy interrupted by a shutdown shows up after the restart as not done.

Safeguards. Writing goes without the Windows cache and so does the read back (only the cache of the disk or of the NAS remains). A backup already copied is never overwritten: if in the engine a backup with the same name changed (damaged disk, virus that encrypts), the copy fails, says so, and the one on the network stays as it was. The code of the apps and the archive do change: the previous version goes to pyrite-versioni\ and stays there for the days kept, and the folder of the app always has the current code. An app registered without its folder in the engine, or a folder of the engine that can't be read, make the copy fail and stop the cleaning (the network copy is exactly what puts them back). At every copy a part of the files already on the network (up to 2 GB, the ones checked longest ago first) is read back in full: a damaged copy of a file the engine still has is made again (event), one of a file the engine no longer has is an error event. The copy never reads or writes through a link (junction) in the network folder, and checks where every file it writes really is. The cleaning is skipped if the computer's time is before the last copy or more than 48 hours after the last copy done (with a warning: check the time; if the current time is right and the most recent manifest comes from a wrong clock, copy it out of pyrite-giri\ and then delete it), removes only the files with the names and in the folders the engine writes, and always leaves at least the last 3 checked backups of every app and of the registry. When space runs out the copy first removes the expired copies the engine no longer has and tries once more. If the computer folder holds the copies of another engine with the same computer name, the copy stops without writing anything: choose another folder.

If it fails you see it. An error event with the reason in plain words (folder not reachable, access denied with the engine's account and what to do, out of space, different fingerprint, too slow); in the Overview a red box when the copy is on and the last copy done is more than 26 hours old (or there has been none); on the Backup page a line with the last copy done (green; yellow if the last copy failed, red after 26 hours).

Permissions on the folder

No password is stored: the copy runs with the engine's account (the section shows it, and so does the test).

Security

Putting back an app from a copy

  1. In the network folder open <COMPUTER NAME>\apps\<app>\state\pb_data\backups\ and choose the backup (the name has date and time: auto_20261105_030000.zip).
  2. Copy it (copy, don't move) into the same folder of the engine: apps\<app>\state\pb_data\backups\.
  3. Console → Backup → the app: the file is in the list. Press Restore: the engine stops the app, keeps a copy of the current data (state\copia_prima_del_ripristino_…), puts back the backup and starts the app again.

An app whose whole folder is gone: copy apps\<app>\ from the network folder (code and backups) into apps\ of the engine, then Rescan folders, start it and restore the backup as above. An archived app: copy archivio\<entry>\ back into archivio\ of the engine and use the Archive page.

Restoring the engine registry

The registry (people, levels, groups, who enters which app, settings, list of the apps) is restored with the engine stopped. Everything changed after that backup (new people, passwords, access) is lost.

  1. Choose the backup: in control\pb_data\backups\ of the engine, or in the network folder (<COMPUTER NAME>\control\pb_data\backups\).
  2. Icon near the clock → Exit.
  3. Copy the whole folder control\pb_data to a folder outside the engine (copy, don't move: it is the way back).
  4. Extract the zip (right click → Extract All) into a folder outside the engine: inside there are data.db, auxiliary.db and maybe storage\.
  5. In control\pb_data delete data.db-wal, data.db-shm, auxiliary.db-wal, auxiliary.db-shm if they are there, then copy the extracted files over the ones in control\pb_data (replace). Don't touch control\pb_data\backups.
  6. Start the engine and check people and apps in the console. If something is wrong: Exit, put back the folder copied at step 3, start again.

A new computer (the old disk is gone)

  1. Put pyrite.exe (the same version) in a new folder; don't start it yet.
  2. In the engine's folder create by hand the folder control\pb_data (the engine hasn't started yet, so it isn't there). Then from the network folder <OLD COMPUTER NAME>\ copy into the engine's folder control\pb_data\backups\ (inside the control\pb_data just created), apps\ and archivio\ (not pyrite-giri\ and pyrite-versioni\).
  3. Put back the registry from its most recent backup (steps 4 and 5 above).
  4. Start the engine: the apps are there, with their code and empty data. For each app with a database: Backup → the app → the most recent backup → Restore.
  5. HTTPS: the certificate is not in the copy (its keys belong to the old computer): make it again from the Certificates page. The network copy comes back on with the registry and writes in the folder with the new computer's name.

30 /Moving Pyrite to another computer

This is for when the old computer still works and you want Pyrite on a new one. If the old disk is gone, see A new computer (the old disk is gone) above.

  1. Stop the engine first (icon near the clock → Exit, or stop the service), so that no file is being written during the copy.
  2. Copy the whole folder of Pyrite, not only pyrite.exe: it must contain control, apps and logs. The registry of the engine (people, levels, groups, the list of the apps) is the file control\pb_data\data.db: without it the new engine starts empty.
  3. It is safer to make a ZIP of the folder and to extract it on the new computer into a new, empty folder, rather than copying file by file.
  4. How to know the copy worked. At the first start the page of the first Owner does not appear: you go to the sign-in page and the people are there. If the page of the first Owner appears, the copy is incomplete (usually control\pb_data\data.db is missing). Don't create anything: close the engine, and copy again.
    Incomplete copy? Pyrite says it by itself. If control\pb_data\data.db is missing but the folder shows a past life (old logs, apps with their data, the history), the page of the first Owner shows a warning and does not go on until you tick “Yes, it is a new engine”; the same warning is written in the window of the engine and in logs\engine.log (it works also when Pyrite starts from the icon or as a service: then the log and the page tell it); from a terminal, pyrite.exe owner create EMAIL stops and asks for --new-engine. If it is a copy: close the engine and make the copy again, with the whole folder. Only if it really is a new engine, tick the box (or use --new-engine): the History records it. The warning goes away by itself when the registry is back. A really new engine, with an empty folder, shows no warning.
  5. What is tied to the computer and must be done again. The HTTPS certificate: its keys belong to the old computer, so make it again from the Certificates page (see A new computer above and HTTPS and certificates). The two-factor authentication: the key of the codes opens only on the computer that made it, so whoever had it is shown as “to be turned on again” (see The key and the backups).
  6. Windows settings to do again. The firewall: the rule is for the file on that computer. On the new computer pyrite.exe firewall status says if it is there; pyrite.exe firewall open (as administrator) makes it, and installing the service makes it by itself (see The Windows firewall; Windows may also ask at the first start, see First start). And the start with Windows (the icon's menu, the service or the scheduled task: see Pyrite as a Windows service).
  7. Keep the old computer off, and its folder intact, for a few days. It is the way back. Don't start the two engines together on the same network: a folder copied as it is carries its identifier with it, and the two copies throw each other out of the sign-in (see Several engines on the same server).

31 /Languages, colors and theme

32 /Updating from 0.7.6

It is done as the update from 0.7.5, described below: only pyrite.exe is replaced, the engine makes the restore point by itself and updates everything or nothing. There are no checks to make on the scripts of the apps this time. After the update the small window of the icon and pyrite.exe -v must say alpha 0.7.7 (see “What to check after the update” below). To go back: update-restore, as described below.

What changes by itself

What does not change until you decide

33 /Updating from 0.7.5

The engine is updated by replacing only pyrite.exe: same name, same folder. Addresses, ports, accesses, data, apps, people and settings stay where they are, and nobody is thrown out: whoever was signed in to the portal stays signed in. To check which program you have, pyrite.exe -v prints the version. This chapter is for reaching 0.7.7 from 0.7.5 as well; whoever comes from 0.7.5 should also read Updating from 0.7.6: what changes by itself applies to them too.

  1. Check the new pyrite.exe: in PowerShell, in its folder, Get-FileHash .\pyrite.exe -Algorithm SHA256 must give the same SHA-256 fingerprint you received with the file (in the message or on the page you downloaded it from). If it is different, do not start it.
  2. Stop the engine: icon near the clock → Exit. Wait until the icon disappears. If Pyrite runs as a Windows service: net stop pyrite-… (see Pyrite as a Windows service).
  3. Keep the old program: copy pyrite.exe (copy it, don't move it) to a folder outside the engine, named after the version you have, for example C:\Pyrite-0.7.5\pyrite.exe. It is what you need to go back.
  4. Copy the new pyrite.exe into the engine folder, over the old one (same name). Nothing else changes.
  5. Before updating, make the checks on the apps' scripts listed below (Checks to make first) and make a copy of the whole folder with the engine stopped.
  6. Double-click pyrite.exe (or net start pyrite-…). Before changing anything the engine checks the folder (no other engine running on it, files it can write, enough free space on the disk) and makes a restore point by itself: a copy of the engine's data and of the data and settings of the apps, in control\aggiornamenti\ (the last 2 are kept). Then it updates. Everything or nothing: if something goes wrong, or the computer turns off halfway, the engine puts everything back from the restore point and writes it in logs\engine.log; start it again to retry, or put back the old pyrite.exe. If a check doesn't pass, the engine changes nothing, doesn't start and says why (see Problems).
  7. If Windows shows the “Windows Security” window, choose Private networks and allow, as at the first start. Usually it doesn't ask, because the file has the same name in the same folder.
  8. The console sessions are kept only in memory: after the restart, Owners and Admins sign in again with the same email and password. Coming from 0.7.5, everybody signs in to the portal once more (see below); from 0.7.6, who was inside the portal stays inside.

With many apps and a lot of data the first start takes longer, because the restore point copies the data first. It needs free space on the disk about as large as the data: if it isn't there, the engine changes nothing and says how much it needs.

What changes from 0.7.5

Checks to make first on the apps' scripts

0.7.6 narrows the fence around the scripts (see What an app can do). Before updating, for each app, look in the files of apps\APP-NAME\release\pb_hooks and pb_migrations for these things. If you find none, for that app the update changes nothing.

What happens to an app that uses one of these things: the script gets an error in English and that part of the app doesn't work. The engine stops restarting an app with a problem in its files and tries again when the files change or when you press Restart; the Status tab and the events say why. If something is wrong after the update, the way back is update-restore (below).

If you come from 0.7.4

What to check after the update

Going back to the previous version

To go back, always run pyrite.exe update-restore --yes BEFORE putting back the old pyrite.exe. If you put back only the exe, the old engine takes the folder for an update: it makes a new restore point and removes the oldest, and after another step forward the point with the data from before the update is gone.

  1. Stop the engine: icon → Exit (or net stop pyrite-…).
  2. Open a command prompt (cmd) in the engine's folder (in PowerShell type .\pyrite.exe instead of pyrite.exe) and run pyrite.exe update-restore. It changes nothing: it only says what it would do. Which restore point, from when, and which choices made after the update it undoes: people removed or blocked afterwards become active again, passwords changed afterwards go back to the old ones, the Owners, accesses and apps removed afterwards come back. The plan also says who becomes an Admin again, who is no longer one and to whom the previously managed apps return; who loses the People Admin and App Admin roles received after the update; the units created afterwards and the people created afterwards, who won't be there any more after going back; who loses two-factor authentication and who is left out because the server's key was made again after the point. Write it all down. The prompt comes back at once (see For technicians): wait for the last line, “Nothing has been changed. To go on: pyrite.exe update-restore --yes”.
  3. Run pyrite.exe update-restore --yes and wait for the line “Done in … s”: it puts back the engine's data and the apps' data and settings as they were before the update. What changed after the update (also what people wrote in the apps in the meantime) is first copied aside, in control\aggiornamenti\ritorno_…; the engine never deletes that copy (the Backups page lists it): delete it by hand when you no longer need it.
  4. Only then put back the old program: copy C:\Pyrite-0.7.5\pyrite.exe (or the one of your previous version) into the engine's folder, over the new one, and start it. If instead you restart the new version, it updates again, with a new restore point.
  5. Check: the small window says the previous version; on the Backups page, box Engine updates, the point of the update is “put back with update-restore”; the apps are running with the data from before the update.
  6. In the console redo what the command listed: block the people again, change the passwords again, remove again Owners, accesses and apps. People sign in to the portal again, once.

What is lost by going back. The registry goes back to how it was before the update: the level and the managed apps of that time come back, while the units, the roles and the new fields disappear. What was done after the update is lost: people created, levels and managed apps changed, accesses, two-factor authentication turned on. Before going back the engine makes a copy of it in control\aggiornamenti\ritorno_…. The history does not go back: the summary lines stay. If you then restart the new version, the move starts again from the data of the point, gives the same result and writes the summary again (once). The file control\passaggio-ruoli.txt stays where it is and is rewritten.

With the engine running, update-restore refuses and changes nothing. An app archived after the update comes back among the apps, with the data from before the update, and its archived copy stays in archivio\ with the data from when it was archived: they are two copies, so before deleting one see which to keep. An app installed after the update leaves the engine (its files stay in the copy put aside). An app updated from a zip after the engine update goes back to the previous version, and its “Go back to the previous version” is no longer offered: the backup of that update keeps the data of the round that was left behind (it stays on the disk, marked as superseded; the update-restore plan lists it). The same steps are on the engine's Backups page, box Engine updates. update-restore doesn't touch the backups, the copies made before a restore, the logs, the engine history and its copies.

Certificates: 0.7.4 uses only the standard certificate. If from 0.7.5 you go back to 0.7.4 and then forward again, the Let's Encrypt certificates come back by themselves (or Pyrite asks for them); the Let's Encrypt account and the Cloudflare key stay. Extra certificates uploaded by hand must be uploaded again if 0.7.4 removed the folder.

34 /Stopping apps and the engine

35 /Pyrite as a Windows service

Besides the icon near the clock, Pyrite can run as a Windows service. As a service it starts by itself when the server is switched on, even if nobody signs in; if it stops because of a failure, Windows starts it again after a minute (up to three times a day); when the server shuts down, Pyrite stops the apps in order. It has no icon and no windows: the console opens at the usual address, also from the server itself (a double click on pyrite.exe opens the console in the browser). The main messages are also in the Windows Event Viewer (Windows Logs → Application, source pyrite-…), besides logs\engine.log.

On a server, do not start Pyrite by double-click with a Windows administrator user. Started that way, the engine and the scripts of all the apps run with full rights on the server. The intended way is the Windows service, which runs with an account of its own (see below).

Install, look, remove

The account and the folder

The first start can ask for the same choice, with your session (icon) or as a service: see First start.

36 /Starting with nobody logged in

The best way to start Pyrite with nobody signed in is the Windows service (see Pyrite as a Windows service). If you prefer a scheduled task of Windows, or the service can't be used, this is how. You set up the task once. After setting it up, try it as described under “The limits of the scheduled task”.

What to prepare

The scheduled task

The command is C:\Pyrite\pyrite.exe --autostart --unattended.

In PowerShell as an administrator:

$c = Get-Credential 'DOMAIN\svc-pyrite'   # a window asks for the password, so it does not stay in the command history
$a = New-ScheduledTaskAction -Execute 'C:\Pyrite\pyrite.exe' -Argument '--autostart --unattended' -WorkingDirectory 'C:\Pyrite'
$t = New-ScheduledTaskTrigger -AtStartup
$t.Delay = 'PT1M'    # one minute after the start, so the network (and the NAS) is ready
$s = New-ScheduledTaskSettingsSet -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) `
       -ExecutionTimeLimit ([TimeSpan]::Zero) -StartWhenAvailable -AllowStartIfOnBatteries `
       -DontStopIfGoingOnBatteries -MultipleInstances IgnoreNew
Register-ScheduledTask -TaskName 'Pyrite' -Action $a -Trigger $t -Settings $s `
       -User $c.UserName -Password $c.GetNetworkCredential().Password -RunLevel Limited

The same thing by hand: Task Scheduler → Create Task; General: the account, Run whether user is logged on or not, leave Do not store password unticked (the password is kept by Windows); Triggers: At startup, delay 1 minute; Actions: start the program C:\Pyrite\pyrite.exe, arguments --autostart --unattended, start in C:\Pyrite; Settings: If the task fails, restart every 1 minute, up to 3 times; untick Stop the task if it runs longer than; If the task is already running: do not start a new instance. Do not use Run with highest privileges: the engine does not need it.

Exit codes and what happens

CodeWhenWhat the task does
0The engine was stopped on request (Exit, Windows shutting down).Nothing: it is not a failure.
1An error: port 8080 is taken by another program; logs\engine.log cannot be opened (the account has no Modify on the folder); the icon or the engine do not start; the engine stops by itself.“If the task fails, restart” should start it again (up to 3 times, one minute apart): see below. The reason is in logs\engine.log (if the log can be opened).
3There is already a Pyrite running for the same folder, or one answers on the same port.The new copy gives way: a restart would find the first one again, so after the attempts the task stays as it is. The line in logs\engine.log says which case it was.

If you end the task (Stop-ScheduledTask, or “End” in the Task Scheduler), the exit code is not chosen by Pyrite: Windows decides it.

To start it without restarting the PC: Start-ScheduledTask -TaskName Pyrite. Stop-ScheduledTask ends the task, but it is not proven that the engine then stops in an orderly way: the engine closes in order only when the program that starts it is asked to close or Windows shuts down, and ending a task usually ends the process at once. So, before stopping it, stop the apps from the console (button Stop in the page of each app) and, if you have just changed something, make a backup from the Backups page; after the restart look at the Overview and at logs\engine.log. An engine started by hand and the task cannot run together on the same folder: a second engine on the same folder does not start (exit code 3 without anybody at the screen).

The limits of the scheduled task

37 /Alpha warnings

  • Local network first. Without a certificate the engine works in HTTP and passwords and data travel in clear text inside the network: turn on HTTPS from the Certificates page. From 0.7.5 you can open some apps to the internet (Network rules): do it only with HTTPS on, one app at a time, and only for non-sensitive data. The console never opens from the internet.
  • Non-sensitive data only. Don't use it for personal data that need protection, health data, payments or anything critical.
  • No warranty. This is an alpha, provided “as is”, to try the product. Data formats and screens may change in the next versions. Keep copies of what matters.
  • Apps of several customers on one engine. The fence around the scripts is a defence inside the program, not a wall: do not rely on it alone for scripts written by someone you don't trust (see What an app can do).
  • Updating the engine. The engine makes a restore point by itself. For an extra safety net in this alpha, you can also copy the whole folder while the engine is stopped, before replacing pyrite.exe.

38 /Known limits

These are the things 0.7.7 does not do, or does only in part. They are here so that you know them before you rely on it.

39 /For technicians

Commands

They are typed in a command window opened in the folder of the program (in PowerShell type .\pyrite.exe instead of pyrite.exe); with a command after the name, the program writes into that window. Without any command (pyrite.exe alone) it starts as with the double click, with the icon.

commandwhat it does
pyrite.exe serve --http=0.0.0.0:8080the engine in the terminal, on the chosen address and port; Ctrl+C stops it cleanly
pyrite.exe owner reset EMAILa temporary password for an Owner, printed once, to be changed at the next sign-in; the other console sessions of that Owner end. With --enable it also enables an Owner who is disabled. Only for Owners
pyrite.exe owner create EMAILcreates an Owner with a temporary password, when /setup/ can't be opened; --name "Mary Smith" for the name. If the engine already has an active Owner, repeat the email with --confirm EMAIL. If the folder looks like the incomplete copy of a Pyrite that was already there, the command stops and asks for --new-engine (see Moving Pyrite to another computer). Never an email that is already in the directory (for an existing Owner use owner reset)
pyrite.exe owner two-factor-off EMAILremoves two-factor authentication from an Owner (lost phone, engine moved), with the engine running or stopped; the sessions of that Owner end. Only for Owners (see Two-factor authentication)
pyrite.exe update-restorewith the engine stopped, puts back the restore point of the last engine update (the engine's data, the data and settings of the apps); without --yes it only says what it would do. Then put back the pyrite.exe of before (see Updating from 0.7.5)
pyrite.exe network statusthe network rules in use (file control\pyrite.json). With the engine stopped, network reset goes back to the values of 0.7.4 and network setup asks the two network questions (see Network rules)
pyrite.exe service installin a Command Prompt opened as administrator: installs Pyrite as a Windows service; service status says how it is, service uninstall removes it; service install --no-firewall skips the firewall rule (see Pyrite as a Windows service)
pyrite.exe firewall statushow the Windows firewall is for Pyrite (no administrator rights needed); firewall open and firewall close make and remove the rule for the program (TCP only), in a Command Prompt opened as administrator (see The Windows firewall)
pyrite.exe certificates offwith the engine stopped, goes back to HTTP when HTTPS is misconfigured (the certificate stays: turn it back on from the console); certificates status says how HTTPS is set (see Emergency exit)
pyrite.exe import <file>reads a CSV, Excel (.xlsx, .xls) or JSON file and tells columns and types, without loading anything; options such as -sheet, -separator, -encoding, -header none|titles|preamble, -json (all of them with import -h)
pyrite.exe toolsthe catalog of the engine tools; --md the tools chapter of the agent standard, --json the data, --lang it the Italian texts
pyrite.exe --helpthe list of the commands

40 /Problems and licenses

Pyrite includes PocketBase (MIT license, © Gani Georgiev) and other open-source components: their licenses are in THIRD-PARTY-NOTICES.txt. Pyrite is an independent project built on PocketBase; it is not affiliated with or endorsed by PocketBase or its author.