Lawliet LAWLIET
Book a demo

2. Installation

This guide describes Lawliet 1.5.13.s (the current release). Screens, commands and procedures may change in later versions; the usage guide is updated with each release. Check the version your server runs under Settings > Platform or with ./lawliet version, and see the Releases page for what changed.

From the bundle on a download link to a signed-in, licensed console with a second approver.

You need
WhoA server administrator with root (or sudo) on the Lawliet server
Console roleNone until step 2.9; then the Super administrator account the installer creates
Four-eyesNot needed for anything in this chapter (there is only one approver yet)
TimeAbout 30 minutes, most of it waiting for the first start

Every command in this guide is run from the installation directory, as root or with sudo. Use the same account every time: .env is readable only by the account that wrote it.


2.1 Before you start#

Server requirements#

ItemRequirement
Operating systemLinux on Intel/AMD (x86_64, bundle folder amd64) or ARM (aarch64, bundle folder arm64). Check with uname -m
DockerDocker Engine 24 or later with the Compose plugin (docker compose), or docker-compose. Installed and running before you start. The bundle does not contain Docker
Toolsbash, curl, tar, and sha256sum (or shasum). openssl to generate a self-signed certificate and to check update signatures
CPU, memory4 CPU and 8 GB RAM for a small estate; more for a large one
Disk40 GB free recommended. The installer warns below 10 GB. An update later needs about twice the bundle size free in the parent directory
TimeNTP configured (timedatectl shows System clock synchronized: yes)
InternetNot needed, ever

The bundle must match the server's CPU. A bundle can carry both architectures, or one (its name then ends in -amd64 or -arm64).

Decide three things first#

  1. The address. The host name or IP address operators will type in the browser and agents will connect to. See 2.7 Install by IP address or by name.
  2. HTTPS or plain HTTP. Use HTTPS. Plain HTTP sends passwords and tokens across the network in clear text and exists for a laptop lab.
  3. The certificate. Your own (from your CA), or a self-signed one the installer makes. See 2.8 Certificate choices.

Firewall requests to raise#

FromToPortNeeded for
Operator workstationsLawliet server443/tcp (80/tcp optional, it redirects)Console
Monitored hostsLawliet server443/tcpAgents
Lawliet server and monitored hostsYour NTP source123/udpCommand signing
Log sendersLawliet server5514/udp and 5514/tcpOnly if you collect syslog

In plain-HTTP mode operators need both 3000/tcp and 8000/tcp, and agents need 8000/tcp. The full list, including optional outbound rules, is in Security hardening of the server.


2.2 Install Docker on a server without internet#

./lawliet install checks for Docker and stops if it is missing. It does not install it.

  1. On a machine with internet access, download from Docker's package site (download.docker.com) the packages for the server's distribution, version and CPU: containerd.io, docker-ce, docker-ce-cli, docker-buildx-plugin, docker-compose-plugin (.deb for Debian and Ubuntu, .rpm for RHEL, Rocky, Alma). An internal mirror that carries Docker CE works too.

  2. Copy them to the server and install them together:

    sudo dpkg -i ./*.deb          # Debian, Ubuntu
    sudo dnf install ./*.rpm      # RHEL, Rocky, Alma
  3. Start Docker and check it:

    sudo systemctl enable --now docker
    sudo docker info
    sudo docker compose version

What you see: docker info prints the server details without an error, and docker compose version prints a version.

If it fails: Cannot connect to the Docker daemon means the service is not running (sudo systemctl status docker). docker: 'compose' is not a docker command means the docker-compose-plugin package is missing.


2.3 Download the bundle and check it#

Your vendor sends download links that expire after a few days. Each link resumes after a dropped connection. You receive:

FileWhat it is
lawliet-docker-<version>-<customer>.tar.gzThe bundle
lawliet-docker-<version>-<customer>.tar.gz.sha256Its SHA-256 checksum
INSTALL-NOTES.txt, installation-guide.htmlNotes for this delivery

On the machine with internet access:

  1. Download each file. To resume a broken download, run the same command again:

    wget -c '<link>'
    # or
    curl -C - -fLO '<link>'

    Keep the single quotes: the links contain &.

  2. Check the bundle against its checksum:

    sha256sum -c lawliet-docker-<version>-<customer>.tar.gz.sha256
  3. Copy the bundle and the .sha256 file to removable media, carry them to the server and check again there (step 2 of 2.4).

What you see: lawliet-docker-<version>-<customer>.tar.gz: OK

If it fails: FAILED means the file is damaged or incomplete. Download it again with wget -c (it continues) or from the start. Do not install a bundle that fails this check.


2.4 Unpack the bundle on the server#

Choose a parent directory with room for two versions side by side, for example /opt. An update unpacks the new version beside the current one.

  1. Copy the bundle and its .sha256 file to the parent directory.

  2. Check the checksum on the server:

    cd /opt
    sha256sum -c lawliet-docker-<version>-<customer>.tar.gz.sha256
  3. Unpack and enter the installation directory:

    sudo tar xzf lawliet-docker-<version>-<customer>.tar.gz
    cd lawliet-<version>/

What you see: a directory lawliet-<version> containing lawliet, docker-compose.yml, images/, agents/, docs/ and more.

If it fails: gzip: stdin: unexpected end of file means the copy is incomplete. Copy it again from the original file.


2.5 Run the installer#

sudo ./lawliet install

The installer asks a few questions, shows a summary, and writes nothing until you confirm the summary. Press Enter to take the default shown in brackets.

Step by step#

  1. Checking this machine. No question. It checks Docker, Compose, curl, free disk, that this is a complete bundle, that the bundle carries images for this CPU and that every image file is present, and that no deployment with the same project name exists.

  2. Licence. No question. It says whether a licence is embedded in the bundle. Most bundles have none: the licence is issued for this installation after it is running (step 2.10).

  3. Existing configuration. Only when .env already exists: Overwrite it and configure from scratch? Default no. Yes keeps the old file as .env.backup.<timestamp>.

  4. Where will operators reach this server? Type the address. The default is this server's detected IP address. Check it: if it shows localhost or the wrong network card, type the right address.

  5. How should it be served?

    ChoiceMeaning
    1 (default)HTTPS on 443 through the bundled nginx. Recommended
    2Plain HTTP on 3000 and 8000. Lab use only
  6. Host ports. Only shown when 80/443 (HTTPS) or 3000/8000 (plain HTTP) are already in use. The installer picks the next free port and uses it in every URL and command it prints.

  7. TLS certificate (HTTPS only). See 2.8.

    ChoiceThen it asks
    1 (default)Path to the certificate (fullchain PEM): and Path to the private key (PEM):
    2Nothing. It generates a self-signed certificate
  8. Administrator account.

    • Username: default admin.
    • Generate a strong password for me? Default yes (20 characters, shown once at the end). Answer n to type one: 12 to 128 characters, not a known default or a placeholder, typed twice.
  9. Generating secrets. No question. It generates the JWT signing key, the data encryption key, the database password and the agent enrolment secret.

  10. Ready to install. A summary: address, console URL, serving mode, administrator. Write this configuration and start the platform? Default yes.

  11. Loading images. It checks each image file against its checksum and loads it into Docker. Nothing is downloaded.

  12. Starting and Waiting for services. A live list of services with their state. This takes a few minutes on the first start; the installer waits up to 7 minutes.

  13. Verifying the install. It checks that the API and the login page answer at the address you gave, and that the database schema is stamped.

What you see at the end#

  +-----------------------------------------------------------+
  |  Installed and running                                    |
  +-----------------------------------------------------------+

  Console                    https://10.0.0.5
  Username                   admin
  Password                   <the password>

  ! Save that password now. It is stored in .env and not shown again.

Then, in order:

Save the administrator password now in your password safe. If you lose it, see Troubleshooting.

If it fails#

MessageCause and fix
Docker is not installed or Docker is installed but not runningDo 2.2, then run the installer again
curl is not installedInstall it from the OS media (apt-get install curl, dnf install curl)
Only N GB free hereFree disk space, or answer yes to continue (not recommended below 10 GB)
This does not look like a Lawliet bundle: <file> is missingThe unpack is incomplete. Unpack the bundle again
This bundle has no images for this server (<arch>)The bundle was built for the other CPU. Ask your vendor for a bundle for this CPU
Bundled image <file> is missing or failed its checksumThe copy is damaged. Copy the bundle again and check its .sha256
Not enough disk space to load the imagesFree space where Docker keeps its data (docker info shows the directory)
A Lawliet deployment named 'lawliet' already exists on this hostSee 2.6
That certificate and key do not matchThe key belongs to another certificate. Give the matching pair
Not everything became healthy within 7 minutesRun sudo ./lawliet logs backend and sudo ./lawliet doctor. See Troubleshooting
Installed, but the checks above did not passFix what is listed above that line, then sudo ./lawliet restart and sudo ./lawliet status
API answering on this host, but not at <url> (a warning, not a failure)The platform is running, but this server cannot reach itself by that address. Normal behind NAT or split DNS. Check from an agent host before enrolling: curl -k https://<address>/health

If you stop the installer before the summary, nothing is written. Run it again.


2.6 Two deployments on one host#

Container names and data volumes are tied to the Compose project name (lawliet by default). A second deployment on the same host, for example a staging copy, needs its own name. Use the same variable for every command in that directory:

sudo COMPOSE_PROJECT_NAME=lawliet-staging ./lawliet install
sudo COMPOSE_PROJECT_NAME=lawliet-staging ./lawliet status

The installer moves the second deployment's host ports to the next free ones and prints them.

If the installer stops with A Lawliet deployment named 'lawliet' already exists on this host, the existing containers are in the way. Stopping them is not enough (a stopped container keeps its name). Your choices, as the installer lists them:


2.7 Install by IP address or by name#

By IP addressBy host name
What operators typehttps://10.0.0.5https://lawliet.corp.example
NeedsNothingA DNS record (or hosts-file entry) that operator workstations and every agent host resolve
CertificateMust name the IP address as an IP entry. A self-signed certificate made by the installer always doesMust name the host name. A self-signed certificate made by the installer also names this server's IPv4 addresses
Air-gapped site without DNSRecommendedOnly if you maintain hosts files everywhere

Whichever you choose, the installer:

The backend refuses any request whose host name is not in TRUSTED_HOSTS with 403 Invalid host header. This is why an agent can still reach a server installed by name through its IP address.

Avoid localhost as the address. The installer warns: localhost is reachable only from this machine. Agents on other hosts cannot enrol against it, and browsers elsewhere cannot open the console.


2.8 Certificate choices#

ChoiceWhen to use itWhat agents need
Your own certificate from your CA (recommended)Your browsers and agent hosts already trust that CANothing extra
Self-signed, generated by the installerNo CA available, or to start quicklyEach agent host must be given the certificate: sudo ./lawliet tls --export writes lawliet-server.pem
Plain HTTP (no certificate)A lab laptop onlyInstallers add --insecure. Not for a real network

Your own certificate. Give the full chain (server certificate first, then intermediates) and the private key, both in PEM. The installer checks that they match and shows the expiry date. If agents will connect by IP address, the certificate must carry that address as an IP subjectAltName.

Self-signed. RSA 2048, valid 825 days, naming the address you gave, this server's own IPv4 addresses and localhost. Browsers warn until it is replaced. The installer prints Agents must trust it too. Run: ./lawliet tls --export.

A certificate already present in infra/docker/ssl/fullchain.pem and privkey.pem is kept as it is. Use this to move an existing certificate onto a new server.

You can replace, re-issue or switch the certificate later without reinstalling. See TLS and certificates.


2.9 First sign-in#

Open the console URL from your workstation (not from the server: localhost works only there). With a self-signed certificate the browser warns once. Before you accept it, compare the fingerprint the browser shows with the one on the server:

openssl x509 -noout -fingerprint -sha256 -in infra/docker/ssl/fullchain.pem

Step 1: sign in#

  1. On the Sign in page, enter the administrator username and password from the installer.
  2. Press Sign in.

What you see: the Set a new password page.

Step 2: set a new password#

The install-time password must be replaced, even a generated one. The page says This password was set at install time, not by you.

  1. Enter Current password (the installer's), New password and Confirm new password.
  2. Press Set password.

If it fails: the new password must be different from the current one, and the two new entries must match. The page shows which check failed.

Step 3: turn on two-factor authentication#

Required for every local account (REQUIRE_TWO_FACTOR=true, the default).

  1. 1. Scan with an authenticator app. Scan the QR code with Google Authenticator, Microsoft Authenticator, 1Password or any TOTP app. If you cannot scan, use the key shown under Can't scan? Enter this key:.
  2. 2. Save your recovery codes. Ten codes, each works once, shown only now. Press Copy or Download and store them offline. Tick I have saved these codes somewhere safe.
  3. 3. Enter the 6-digit code from the app.
  4. Press Turn on two-factor authentication.

If it fails: That code was not accepted. Check the time on your phone and try the next one. The code is checked against the server's clock with no tolerance window, so the phone's time must be correct. Wait for the next code and try again.

Step 4: the activation screen (only without a licence)#

If no licence is active, the console shows Activate this installation. Continue with 2.10. Until then nothing else in the console opens.

Step 5: create the second approver#

Until two approvers who can approve each other exist, every page shows Four-eyes is inactive until a second approver exists. End this state on the first day.

  1. Go to Settings > Users.
  2. Under Add an account, enter the username, email and a temporary password, and choose the role.
  3. Press Create user.

Choose the role so that the two of you can approve each other's user and policy changes:

You areCreateResult
Super administrator (the install account)A second Super administratorEach approves the other
Super administratorAn LSO, then an RSOThe LSO and RSO approve each other; keep the Super administrator account sealed for recovery

A Super administrator and an LSO alone are not a pair (an LSO is approved by an RSO). Details: Users, roles and approvals.

  1. The new person signs in on their own device with the temporary password and enrols two-factor (required). Then they replace the temporary password on the page Change your password at https://<address>/change-password.

What you see: once the pair exists, the banner disappears. From then on, critical actions wait under Approvals.

If it fails: 409 MANAGEMENT_WOULD_LOCK means the account you tried to make the first second approver could not approve user management or policy changes. Choose one of the pairs above.


2.10 Activate the licence#

You need
CLI routeRoot on the server. No four-eyes
Console routePermission Manage the licence. Four-eyes: Change the licence (on the first day it runs on your one signature)

Step 1: send the fingerprint to your vendor#

Read the installation fingerprint, either way:

sudo ./lawliet licence

or in the console on the activation screen (or Settings > Platform, panel License) under Installation fingerprint, with a copy button. The console also shows Request for your vendor: a ready text with the fingerprint, version, host name and date.

Send the fingerprint (or the request text) to your vendor. It identifies the installation and nothing else.

Step 2: install the key you receive#

From the server (the key, or a file that contains it):

sudo ./lawliet licence /path/to/customer.key

What you see:

> Checking the new licence
  OK complete licence for <organisation>, valid until 2027-10-14
  OK Bound to this installation
  OK Written to .env (previous file kept as .env.backup.*)

> Applying
  OK Licence in effect

From the console: on the activation screen, or Settings > Platform, panel License, paste the key into Licence key / Enter a new licence key and press Activate licence. Once a second approver exists, this goes to Approvals first: Sent for approval. It is activated once signed off and executed.

If it fails#

MessageCause and fix
That is not a licence key. A key starts with LAWLIET-.Paste or point to the whole key
The licence is not valid yetThe server clock is behind the licence start time. Fix the clock (see Troubleshooting), then install it again
A key bound to another installation is refusedThe key was issued for a different fingerprint. Send this installation's fingerprint again
This key was issued ... before the licence in useAn older key cannot replace a newer one. Nothing was changed
The backend is not answeringStart the platform: sudo ./lawliet start

2.11 The setup checklist#

Settings > Setup lists what is still open on a new installation:

StepDone whenButton
Set an administrator passwordThe install-time password is replacedSet password
Activate a licenceA valid licence is activeOpen settings
Configure outbound emailSMTP_ENABLED=true with SMTP_HOST, SMTP_PORT and SMTP_FROM_EMAIL in .env (optional; needed for password-reset links and scheduled reports)-
Enrol your first agentA real agent has registeredInstall an agent

After editing .env, apply it with sudo ./lawliet start. A restart does not re-read .env.


2.12 Next steps#

  1. Check the installation: sudo ./lawliet status (CLI reference).
  2. Take a first backup and copy it off the server (Backup and restore).
  3. Install agents (Agents overview).
  4. Walk through Security hardening of the server.

Removing an installation#

See CLI reference: uninstall. It deletes the database.