Installing a self-hosted EntryWick (week 21)
From a new Ubuntu 24.04 server to signing in as the Owner, in order. Every command is meant to be copied as it is; the
only things to change are the domain, the IP address and the release number, shown as events.example.org,
203.0.113.10 and 1.0.0. The target is under 15 minutes from the first SSH login. PRICING_ENTITLEMENTS §5,
ADR-019, ADR-020. What each command does and refuses: cli.md.
Who opens it: whoever installs EntryWick on their organization's own server.
What they came to do: get a running, licensed instance and sign in to it.
What must be true when they leave: EntryWick answers on https at the organization's address, the Owner can sign in,
the instance runs a release EntryWick signed for the license's channel, and a copy of .env is in their password
manager.
Before you start
- A server that meets requirements.md: Ubuntu 24.04 LTS on amd64, 2 vCPU and 4 GB for events of up to 2,000 attendees (4 vCPU and 8 GB up to 10,000), 20 GB free disk (40 GB recommended), and its public IPv4 address. Nothing else installed on it.
- A domain for EntryWick whose DNS you can change, such as
events.example.org. - The license key EntryWick sent you. It starts with
ew_lic_and is one long line. It names your organization and your update channel (stableorbeta). - The release to install, such as
1.0.0— sent with the key, or the newest release on your channel. - For the Owner: a name, an email address, and a password of 12 characters or more that is not in a known breach.
1. Point the domain at the server
At your DNS provider, create two A records (use your domain and the server's address):
events.example.org. A 203.0.113.10
*.events.example.org. A 203.0.113.10
Do this first: the records often take a few minutes to be seen everywhere, and certificates can only be issued once
they are. If the domain has AAAA records, point them at the same server or remove them.
2. Log in as root
ssh root@203.0.113.10
If your provider gave you a user with sudo instead, log in as that user and run sudo -i. Every command below runs
as root. Check that the records from step 1 already reach this server (both should print its address):
getent hosts events.example.org
getent hosts check.events.example.org
If they print nothing yet, carry on; check again before step 8.
3. Open the firewall (only if one is on)
ufw status
If it says Status: inactive, skip this step. If it is active:
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 443/udp
If your provider has a firewall in its control panel, allow the same ports there (22, 80 and 443 over TCP, 443 over UDP).
4. Install Docker
Docker's own packages for Ubuntu 24.04, as Docker documents them:
apt-get update
apt-get install -y ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
If a screen asks which services to restart, press Enter. Then check (Docker Engine 24 or newer, Compose 2.24 or newer):
docker version --format '{{.Server.Version}}'
docker compose version --short
Docker starts now and on every reboot.
5. Install PHP
entrywick is a PHP program that runs on the server; EntryWick itself runs in its image.
apt-get install -y php8.3-cli
php -v
6. Install the entrywick command
Set the release, then download the tool with its checksum and its signature:
EW_RELEASE=1.0.0
EW_DOWNLOAD="https://github.com/entrywickapp-coder/entrywick/releases/download/v${EW_RELEASE}"
mkdir -p /tmp/entrywick && cd /tmp/entrywick
curl -fsSLO "$EW_DOWNLOAD/entrywick.phar"
curl -fsSLO "$EW_DOWNLOAD/entrywick.phar.sha256"
curl -fsSLO "$EW_DOWNLOAD/entrywick.phar.sigstore.json"
Pending: the download address. Each release's
entrywick.phar,entrywick.phar.sha256andentrywick.phar.sigstore.jsonare attached to that release on GitHub, at the address inEW_DOWNLOADabove. That repository is not public yet, so today this address cannot be downloaded from; EntryWick will publish a public one (docs/NEEDS_FROM_OWNER.md, week 21). When it does, only theEW_DOWNLOAD=line changes. Until then, use the copy of the three files EntryWick sends you: put them in/tmp/entrywickand continue below.
Check the file is the one EntryWick's release workflow built and signed. The first command prints
entrywick.phar: OK, the second Verified OK:
sha256sum -c entrywick.phar.sha256
docker run --rm -v /tmp/entrywick:/w:ro \
ghcr.io/sigstore/cosign/cosign:v2.6.1@sha256:68839b7f13dac5a6744a5d8818e984dd39183374e37855c19e14d623d9bc9037 \
verify-blob --bundle /w/entrywick.phar.sigstore.json \
--certificate-identity "https://github.com/entrywickapp-coder/entrywick/.github/workflows/release.yml@refs/tags/v${EW_RELEASE}" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
/w/entrywick.phar
If either fails, stop: do not install that file. Otherwise:
install -m 0755 entrywick.phar /usr/local/bin/entrywick
cd /
entrywick --version
It prints entrywick 1.0.0. That is also the release entrywick install installs.
Pending: reading the image.
entrywickpullsghcr.io/entrywickapp-coder/platform. While that package is private, the server must be signed in to it first:docker login ghcr.iowith the read-only token EntryWick gives you. Once it is public, skip this (docs/NEEDS_FROM_OWNER.md, week 21).
7. Have the license key ready to paste
Open it in your password manager or the email from EntryWick. It is pasted once, in the next step, and is not shown on screen as you paste it.
8. Run the installer
entrywick install
It first checks the server. Each line starts ok, warn or FAIL; any FAIL stops it (see Troubleshooting). Then it
asks, one at a time (a value in [brackets] is the default: press Enter to take it):
| Question | What to answer |
|---|---|
Domain for EntryWick (organizations get their own name under it) |
The domain from step 1: events.example.org |
Your organization's name |
As it should appear to people, up to 160 characters |
Its address (…events.example.org) |
The name in front of the domain: riverside gives riverside.events.example.org. 3 to 63 lowercase letters, numbers or inner hyphens. Not one of the names EntryWick keeps for itself, such as admin, api, app, scan, www, mail, support or status |
Timezone |
Where your events happen, such as America/Chicago ([UTC] by default) |
Owner's name (the first person to sign in) |
The person who will own the organization in EntryWick |
Owner's email |
Their email: how they sign in. It is also the address the certificate authority writes to, and the sender of the app's email until you set up mail |
License key (ew_lic_…, not shown as you paste) |
Paste the whole key and press Enter. A key that is cut short is asked for again |
It then writes /opt/entrywick/.env (mode 600) with new random database passwords and a new APP_KEY, and works
through its stages, each starting with ==>:
- checks the signature of the release for your key's channel, and pulls it by the digest that was signed;
- takes the Compose files out of that image and starts the database and Redis;
- has the app check the license key — a key the app does not accept is asked for once more, then the install stops (exit 7) before any table is created;
- creates the database tables and starts EntryWick;
- asks the app whether it takes the organization's name, address and Owner — the app knows which addresses EntryWick
keeps for itself and which emails already have an account. An answer it refuses is said with the app's reason and
asked for again (without a terminal the install stops and names the option to give; the refused answer is not
kept). Then it asks for the Owner's password, twice:
Password for …@… (12 characters or more, not shown)andThe same password again, and creates the organization the key names, with its Owner; - says hello to EntryWick's license server (a
warnhere is harmless: the instance runs without it); - checks that everything answers, and that the organization's address has a certificate.
Every question can be given as an option instead, and the key and the password from a file:
entrywick help install. --version=X.Y.Z installs that release instead of the tool's own (it must be signed for your
key's channel).
If the install is cut short (a dropped connection, a failure you then fix), run entrywick install again: it carries
on from the stage that did not finish, with the same answers. An option given on the second run replaces the answer
kept from the first (except the domain, which is in .env by then, and the release, which is in .env.version).
Done
It ends like this:
EntryWick is installed.
Sign in: https://riverside.events.example.org/admin as dana@example.org
Scanner: https://scan.events.example.org
Settings: /opt/entrywick/.env — copy it to your password manager now
Mail goes to the log until you set MAIL_MAILER and its settings in .env.
Next: entrywick backup, and entrywick doctor any time.
Open the Sign in address and sign in as the Owner with the password from stage 5. The first visit to each address takes a few seconds longer while its certificate is issued.
9. Right after installing
- Save
.env. Copy the whole of/opt/entrywick/.envinto your password manager (cat /opt/entrywick/.env). Without itsAPP_KEY, no backup can be read. - Set up email. Open
/opt/entrywick/.env(nano /opt/entrywick/.env) and replace theMAIL_lines with your mail provider's settings, for example over SMTP:
(on port 465 addMAIL_MAILER=smtp MAIL_HOST=smtp.example.com MAIL_PORT=587 MAIL_USERNAME=events@example.org MAIL_PASSWORD=your-smtp-password MAIL_FROM_ADDRESS=events@example.org MAIL_FROM_NAME="Riverside Events"MAIL_SCHEME=smtps). Then apply it — the app, Horizon and the scheduler restart with the new settings:entrywick compose up -d - Take the first backup, and schedule the rest:
entrywick backup, then the nightly schedule in backup.md. - Check everything:
entrywick doctor. It endsAll well.(exit 0); a warning (exit 1) says what to look at. Run it again before every event.
Updating later: update.md.
How long it takes
Most of the 15 minutes is Docker installing (step 4) and the images downloading (stage 1 and 2 of step 8); the rest is typing. A slow disk or network makes the downloads longer. Nothing waits on DNS except the certificates, which are issued on the first visit once the records reach the server.
Troubleshooting
Messages start FAIL or warn on a line of their own, or error: at the end. The exit code is in echo $? right
after the command.
| You see | Exit | What to do |
|---|---|---|
FAIL Docker Engine is not installed, not running, or this user may not use it. |
2 | Do step 4, and run entrywick as root (sudo -i). systemctl status docker shows whether it runs |
FAIL The Docker Compose v2 plugin is missing (apt install docker-compose-plugin). |
2 | apt-get install -y docker-compose-plugin |
FAIL Docker Engine …: 24.0 or newer is needed / FAIL Docker Compose …: 2.24.0 or newer is needed |
2 | An older Docker is installed. Remove it (apt-get remove -y docker.io docker-compose docker-compose-v2) and do step 4 |
FAIL Port 80 is already in use; EntryWick's Caddy serves 80 and 443 … |
2 | See what holds it: ss -ltnp 'sport = :80'. For Apache or nginx: systemctl disable --now apache2 (or nginx) |
FAIL … at least 2 vCPU and 4 GB are needed … |
2 | A bigger server. For a trial only: entrywick install --skip-requirements |
FAIL … GB free: at least 20 GB is needed |
2 | A bigger disk, or free space. --skip-requirements also skips this |
error: No terminal to ask: add --…=…. |
2 | The installer was run without a terminal (from a script, or ssh with a command). Run it in a normal SSH login, or give every answer as an option (entrywick help install) |
error: … is not signed by EntryWick's release workflow for the stable channel, or could not be checked. Nothing was pulled. |
5 | Usually the server cannot reach ghcr.io or Sigstore (requirements.md, outbound), or the image is still private (the note in step 6). Also when that release was never published on your channel: check the release number with EntryWick |
error: … is a beta; this license is on the stable channel. |
5 | Install a stable release, or ask EntryWick for a key on the beta channel |
error: This entrywick build names no release (dev): add --version=X.Y.Z. |
2 | The tool was not downloaded from a release: do step 6, or name the release: entrywick install --version=X.Y.Z |
error: This install was started with … (.env.version); finish it without --version, then entrywick update --to=…. |
2 | Run entrywick install without --version to finish, then update (update.md) |
warn the app refused the slug "…": … (or the organization, admin name, admin email) |
— | Give another answer when asked. Without a terminal the install stops with error: Run entrywick install again with --slug=… …: run it again with that option |
error: The app did not accept the license key: expired … (or invalid, missing) |
7 | The key is past its dates, or was not pasted whole. Put the right key on the EW_LICENSE_KEY= line of /opt/entrywick/.env, then entrywick install again |
error: The new key is for another update channel. Run entrywick install again to install from it. |
7 | Run entrywick install again, as it says |
error: Creating the organization (ew:instance:organization) failed: then a reason |
1 | The reason is the app's, and after the check above it is the password: too short, or found in a known breach. Run entrywick install again and choose another |
warn no certificate for … yet (…). Point … and *.… at this server; Caddy gets one on the first visit. |
0 | Check step 1 with getent hosts, and that ports 80 and 443 are open (step 3). Then open the address in a browser; entrywick compose logs caddy shows why a certificate was refused |
warn the license server did not answer (…) |
0 | Nothing to do: the instance runs without it and tries every night (heartbeat.md) |
error: EntryWick started but is not healthy yet. Run entrywick doctor, then entrywick install again to finish. |
1 | Do both. entrywick compose ps lists the containers; entrywick compose logs app (or horizon, mysql) shows why one does not start |
error: /opt/entrywick/.env has no APP_KEY. Restore it from your copy, or move it away to start again. |
1 | .env was edited or cut short. Put back your copy |
EntryWick is already installed in /opt/entrywick (since …). |
0 | It is. Use entrywick doctor, and update.md |
Starting a first install again from nothing. Only on a server that has never held real data — this deletes the database and every stored file:
entrywick compose down -v
mv /opt/entrywick /opt/entrywick.failed
entrywick install
Every exit code: cli.md.