Manual install
Install Bouée by hand, behind a reverse proxy of your own.
With a reverse proxy of your own, the same steps by hand.
1. Configure
Clone the Bouée repository onto the server, then create .env from the example and keep it private:
cp .env.example .env
chmod 600 .envFill in at least these. Every variable is described in .env.example, and in production Bouée refuses to use
the example values of its own secrets, or any shorter than 32 characters.
| Variable | Value |
|---|---|
APP_URL | The https address people will open, e.g. https://support.example.com. Sign-in, setup and the console answer there and nowhere else. |
POSTGRES_PASSWORD | openssl rand -hex 32 |
BETTER_AUTH_SECRET | openssl rand -base64 32 |
PORTAL_LINK_SECRET | openssl rand -base64 32 |
SECRET_ENCRYPTION_KEY | openssl rand -base64 32. Optional but recommended: without it, changing BETTER_AUTH_SECRET makes the stored Resend connection unreadable. |
S3_ACCESS_KEY_ID | echo "GK$(openssl rand -hex 16)" |
S3_SECRET_ACCESS_KEY | openssl rand -hex 32 |
GARAGE_RPC_SECRET | openssl rand -hex 32 |
GARAGE_ADMIN_TOKEN | openssl rand -base64 32 |
Leave S3_BUCKET, S3_REGION="garage" and S3_FORCE_PATH_STYLE="true" as they are for the bundled Garage.
DATABASE_URL and S3_ENDPOINT in .env are for local development only: Compose points the containers at its
own database and storage. TRUSTED_PROXIES="1" is right for one reverse proxy on the same host. There is no
BETTER_AUTH_URL to set; an older .env that still has one must match APP_URL, or the server will not start.
Keep a copy of .env somewhere safe and separate from the server: the secrets in it are needed to read a
restored backup.
2. Start
docker compose --profile app up -d --buildThe first run builds the image, applies the database migrations, and starts the web server on
127.0.0.1:3000 (WEB_BIND_ADDRESS changes the address). docker compose up -d without the profile
starts only PostgreSQL and Garage, which is what local development uses.
Read the log once it is up:
docker compose --profile app logs webIt names the address Bouée answers at ([config] APP_URL is …), warns about anything that will not work
as configured (an APP_URL that is unset, on localhost or plain http; an unset SECRET_ENCRYPTION_KEY),
reports whether the attachment bucket answers ([storage] …), and prints the setup link ([setup] Setup link: …).
3. Point DNS at the server
Create an A record, and an AAAA record if the server has IPv6, for APP_URL's hostname. Brand hostnames
need records of their own later; see Brand hostnames.
4. Put the reverse proxy in front
The proxy terminates TLS and forwards to 127.0.0.1:3000. It has to:
- pass the original
Hostheader through. Bouée decides from the Host what a request may reach: everything answers onAPP_URL's host, and any other hostname is a brand's knowledge base and nothing more; - send
X-Forwarded-ProtoandX-Forwarded-For, appending the client's address: per-address limits on sign-in and setup read it,TRUSTED_PROXIEShops from the right; - accept request bodies of at least 64 MB, for attachments (up to 50 MB per message).
With Caddy, which obtains the certificate itself and preserves the Host by default:
support.example.com {
request_body {
max_size 64MB
}
reverse_proxy 127.0.0.1:3000
}With nginx and a certificate you manage:
server {
listen 443 ssl;
server_name support.example.com;
ssl_certificate /etc/ssl/support.example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/support.example.com/privkey.pem;
client_max_body_size 64m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}Open https://support.example.com/api/health: it answers {"ok":true} once the app and its database are up.