Skip to content

Scripts

Nothing on a server is set up by hand. Every install is a script in the infra repository, so a server can be rebuilt from nothing and a fix is a change you can review.

  1. One settings file, /opt/lake/cluster.env, is the only thing that differs between servers (Settings).
  2. Scripts are numbered. Each one installs one service, in dependency order.
  3. Every script is idempotent: running it again repairs or updates, it never duplicates or breaks.
  4. Every download is pinned to a version and checked against a checksum from the project’s release page.
  5. Every service runs as the system user lake, from /opt/<service>, with config in /etc/lake/<service>/ (mode 640, group lake), as a systemd unit. The one exception is the JupyterHub hub, which runs as root because it must start other users’ notebook units (the notebooks themselves never do).
Group Where Page
Install steps 00-19 and install-all.sh infra/scripts/ Install steps
Deploy (deploy.sh) and lakestatus infra/ Deploy and rebuild
SQL migrations 001-013 infra/sql/ SQL migrations
Developer helpers (tunnel, smoke test, seeders) dev/, apps/api/scripts/ Developer helpers

On your machine, from the repository root, copy everything the server needs:

Terminal window
bash infra/deploy.sh lake

On the server, install everything (or only the listed steps):

Terminal window
bash /opt/lake/scripts/install-all.sh
bash /opt/lake/scripts/install-all.sh 14 15

It checks cluster.env first, refuses to start while any CHANGE_ME is left, runs the steps in order and stops at the first failure. Fix the cause and run it again.

  • Start with set -euo pipefail and source /opt/lake/cluster.env.
  • Create the user lake if it is missing.
  • Pin the version and check the checksum; if the checksum is empty, print the real one and stop so a human compares it with the release page.
  • Make every step safe to repeat: CREATE ... IF NOT EXISTS, ln -sfn, “create only if missing”.
  • Write config with sudo tee, then chown root:lake and chmod 640.
  • End with a check: systemctl is-active, a curl, a test query. A script that cannot prove it worked is not finished.
  • Never put a secret in the script. Generate it with openssl rand -hex 16 and keep it in cluster.env.