Install with Docker
Docker is the recommended way to run Arenile in production. The official image ghcr.io/coste360/arenile is
public and free, multi-architecture (amd64 and arm64) and based on distroless: it contains only the
binary, with no shell or unnecessary packages.
Before you start
Section titled “Before you start”| Requirement | Guidance |
|---|---|
| Server | Linux amd64 or arm64 with Docker and Docker Compose |
| Resources | 1 vCPU and 512 MB of RAM are enough for one beach; 1 GB of disk plus room for backups |
| Domain | A subdomain, for example prenota.mio-lido.it, pointing to the server’s IP (A/AAAA record) |
| Email (optional) | SMTP credentials for confirmations and manage links to customers |
| Online payments (optional) | A Stripe account in the establishment’s name |
Standard installation (SQLite)
Section titled “Standard installation (SQLite)”-
Prepare the server. On Ubuntu or Debian install Docker with the official script and open only the ports you need:
Finestra del terminale curl -fsSL https://get.docker.com | shsudo ufw allow OpenSSHsudo ufw allow 80/tcpsudo ufw allow 443/tcpsudo ufw enable -
Create the installation folder and download the official compose file and the example variables:
Finestra del terminale sudo mkdir -p /opt/arenile && cd /opt/arenilecurl -fsSLO https://raw.githubusercontent.com/coste360/arenile/main/deploy/docker-compose.ymlcurl -fsSL -o .env https://raw.githubusercontent.com/coste360/arenile/main/.env.examplechmod 600 .envDirectory/opt/arenile/
- docker-compose.yml the
arenileservice with the data volume - .env the configuration (never share it)
- docker-compose.yml the
-
Generate the encryption key and put it in
.env:Finestra del terminale openssl rand -base64 32Then edit
.envwith at least these lines:.env ARENILE_BASE_URL=https://prenota.mio-lido.itARENILE_SECRET_KEY=the-key-generated-in-the-previous-step# First owner user, created on first start only if the database is emptyARENILE_BOOTSTRAP_OWNER_EMAIL=owner@mio-lido.itARENILE_BOOTSTRAP_OWNER_NAME=Mario RossiARENILE_BOOTSTRAP_OWNER_ORG=Lido EsempioARENILE_ADMIN_PASSWORD=choose-a-long-password# Email (optional but recommended)ARENILE_SMTP_URL=smtp://user:password@smtp.my-provider.com:587ARENILE_MAIL_FROM=Lido Esempio <bookings@mio-lido.it> -
Start and check the logs:
Finestra del terminale docker compose up -ddocker compose logs -f arenileDatabase migrations are applied automatically at startup (
ARENILE_AUTO_MIGRATE=true). The SQLite database, uploaded files and backups live in thearenile-datavolume. -
Set up HTTPS. Put Arenile behind a reverse proxy (Caddy, Nginx, Traefik) or let the binary obtain the certificates: every option is in Reverse proxy and HTTPS.
-
Sign in at
https://prenota.mio-lido.it/admin/with the email and password from step 3. After the first sign-in you can removeARENILE_ADMIN_PASSWORDfrom.env. Continue with the first start.
Creating the first user by hand
Section titled “Creating the first user by hand”If you prefer not to use the ARENILE_BOOTSTRAP_OWNER_* variables, create the owner with the container running.
The image has no shell, but exec runs the binary directly:
docker compose exec -e ARENILE_ADMIN_PASSWORD='choose-a-long-password' arenile \ /arenile admin create --email owner@mio-lido.it --name "Mario Rossi" --org "Lido Esempio"The password must be at least 10 characters long.
Variants
Section titled “Variants”The repository includes deploy/docker-compose.postgres.yml, with a PostgreSQL service already configured and
DATABASE_URL set automatically. Add the database password to .env, generated with URL-safe characters only:
echo "POSTGRES_PASSWORD=$(openssl rand -hex 24)" >> .envdocker compose -f docker-compose.postgres.yml --env-file .env up -dWhen PostgreSQL is worth it and how to back it up: SQLite or PostgreSQL.
The arm64 image runs on Raspberry Pi 4 or 5 (at least 2 GB of RAM) and on mini PCs.
- Install a 64-bit system (Raspberry Pi OS Lite 64-bit or Ubuntu Server arm64).
- Use a USB SSD instead of the microSD card for the data: faster and far more reliable.
- Protect the power supply with a small UPS.
- For online booking the device must be reachable from the internet: consider a tunnel (for example Cloudflare Tunnel or Tailscale Funnel) instead of opening ports on the router.
- Create a Docker Compose resource with the template in
deploy/coolify/(arenile.ymlorarenile-postgres.yml). - Set
ARENILE_BASE_URL,ARENILE_SECRET_KEYand the first-owner variables (Coolify’s terminal does not work: the image has no shell). - Bind the domain to the service on port
8080: Coolify handles the certificate. - Configure the healthcheck on
GET /healthzand setARENILE_TRUSTED_PROXIESto the proxy network.
- Create an app with persistent data and map
/datato a volume (template indeploy/caprover/). - Image
ghcr.io/coste360/arenile:latest, container port8080. - Set the environment variables as above, enable HTTPS and “Force HTTPS”.
- Create the first owner with the
ARENILE_BOOTSTRAP_OWNER_*variables and setARENILE_TRUSTED_PROXIES.
What the official compose file does for security
Section titled “What the official compose file does for security”deploy/docker-compose.yml is already hardened: read-only file system (read_only: true, with /tmp in memory),
no privilege escalation (no-new-privileges), all Linux capabilities dropped (cap_drop: ALL), non-root user and
Docker log rotation (5 files of 10 MB).
Troubleshooting
Section titled “Troubleshooting”| Symptom | What to check |
|---|---|
| The container keeps restarting | docker compose logs arenile: usually ARENILE_SECRET_KEY or ARENILE_BASE_URL is missing, or the key is not 32 bytes of base64 |
/readyz returns an error |
Database unreachable or migrations out of date: check DATABASE_URL and arenile migrate status |
| The widget does not show on the website | Add the website’s domain to the websites allowed to embed (Public page) |
| Emails do not arrive | Check ARENILE_SMTP_URL, ARENILE_MAIL_FROM, the SPF/DKIM records and the delivery log (Email) |
| All IPs in the logs are the same | Set ARENILE_TRUSTED_PROXIES to the reverse proxy’s network |

