Install on your own server
Install Workforce Intelligence on a Linux server you manage, using install.sh and an .env file you prepare.
On a server without CloudFormation, nothing is automated for you. You copy two scripts to the
box, prepare an .env file, and run install.sh.
Read Deployment requirements first.
1. Copy the scripts to the box#
Copy install.sh and find-setup-token.sh from the deploy/ directory of the Workforce
Intelligence repository to a directory on the server, for example:
mkdir -p ~/wi && cd ~/wi
Use scp or paste them in. There is no compose file to transfer: install.sh extracts it
from the wi-server image it pulls, so the file always matches that image's version. Make the
scripts executable with chmod +x install.sh find-setup-token.sh.
2. Prepare .env#
install.sh looks for a file named .env next to itself. If it finds one, it uses it exactly
as it is and never regenerates anything in it. You can create the file yourself, or let
install.sh create it (below). The required values are the two secrets and the origin:
cd ~/wi
sudo tee .env >/dev/null <<ENVEOF
WI_MASTER_KEY=$(openssl rand -base64 32)
WI_SESSION_SECRET=$(openssl rand -base64 32)
WI_ALLOWED_ORIGIN=https://wi.example.com
WI_DOMAIN=wi.example.com
ENVEOF
sudo chmod 600 .env
Leave out WI_DOMAIN if you are not using a domain, and use http://<your-hostname-or-ip>
for the origin. Browsers do not keep a sign-in made over plain HTTP, so use a domain with
HTTPS for real use. Each key must appear once. You do not set WI_API_BASE_URL: the compose
file derives it from WI_ALLOWED_ORIGIN. install.sh adds WI_DOKKU_SSH_HOST for you (see
step 3). The meaning of every value is in Configuration reference.
Back up this file off the box straight away. WI_MASTER_KEY is generated once and cannot
be regenerated. See Master key custody.
If you run install.sh with no .env present, it creates one for you. It generates
WI_MASTER_KEY and WI_SESSION_SECRET and writes WI_DOMAIN and WI_ALLOWED_ORIGIN from the
environment. In that case you must supply WI_ALLOWED_ORIGIN on the command line (the script
stops with "WI_ALLOWED_ORIGIN must be set" otherwise).
3. Run install.sh#
cd ~/wi
GHCR_USER=<your-github-username> \
GHCR_TOKEN=<your-token> \
./install.sh
If you let the script create .env, add WI_ALLOWED_ORIGIN=https://<your-domain> (and
WI_DOMAIN=<your-domain>) to the command line as well.
GHCR_USER and GHCR_TOKEN are your GitHub username and a classic personal access token with
read:packages (see Deployment requirements). The script then:
- Makes sure
.envhas every required value. It addsWI_DOKKU_SSH_HOST, the hostname Builders use forgit push, if it is missing: the value of theWI_DOKKU_SSH_HOSTenvironment variable if you set one, otherwiseWI_DOMAIN, otherwise the host part ofWI_ALLOWED_ORIGIN. It never edits a line that is already there. - Installs Docker through
get.docker.comif Docker is not already installed. - Runs
sudo docker login ghcr.io. The login is stored in/root/.docker/config.json, which the in-app updater also uses. - Pulls the
wi-serverimage (WI_IMAGE_TAG, defaultlatest) and extractsdocker-compose.prod.ymlfrom it into the script's directory. - Pulls the other images and starts the stack with the Compose project name
wi-prod: the database, the application, the web server, and Dokku.
The app container applies database migrations when it starts and never loads sample data, so
you begin with an empty database and a company waiting to be claimed.
GHCR_USER and GHCR_TOKEN are needed only while the box is not logged in to ghcr.io.
Docker remembers the login, so a re-run does not need them.
Upgrade the stack by re-running install.sh#
Run install.sh again to upgrade an installed box. It keeps your .env (the secrets are never
regenerated), adds any newly required value, replaces docker-compose.prod.yml with the one
inside the image it pulls, and recreates whatever changed, including new services and volumes.
It also moves app and web to the pulled images without the backup that Settings →
Updates takes first, so back up the database before you re-run it on a deployment that holds
data. See What an update changes for when a release
needs this.
Do not rename the wi-prod project. The scripts, the in-app updater, and the volume names all
depend on it.
4. Open the app#
Open your address in a browser and continue with First-run setup token.
If the stack does not start#
- A
docker composeerror about a missing variable means you are running Compose from a different directory than the one holding.env, or a required value is missing from it. Re-runninginstall.shadds the ones it can derive. install.shcould not read the compose file out of the image.WI_IMAGE_TAGnames an image that does not carry it. Use a newer tag.docker login ghcr.iofails with "unauthorized" almost always means the token is wrong, expired, missingread:packages, or is a fine-grained token. Create a classic token.- The
appcontainer restarts repeatedly. Runsudo docker compose -p wi-prod logs app. The application refuses to start when its production checks fail, and the log line names the problem. See Production boot checks. - The sign-in page shows instead of the setup wizard. The database is not empty. Setup appears only when no company exists yet.