
Deploy LaraPaper | (Just Updated) TRMNL BYOS Server, Self-Hosted E-Ink Display Server, Admin Set at Boot
LaraPaper self-hosted TRMNL BYOS server for e-ink displays, login ready
larapaper
Just deployed
/data
Deploy and Host LaraPaper on Railway
Built for an LLM agent to deploy and use. The deploy form has no fields to fill: the app key, the admin password and the API token are all generated, and the first admin is created at boot from variables, so nobody opens a registration page first. LaraPaper is a self-hosted server for TRMNL e-ink displays (bring your own server): it hosts screens, playlists and plugins, and your TRMNL devices fetch their next image from it.
About Hosting LaraPaper
This template runs one service, larapaper (Laravel with nginx and PHP-FPM), with its SQLite database and the generated screen images on one volume mounted at /data. There is no separate database service to run.
Registration is closed before the first request. Upstream leaves the first-account registration open to whoever reaches the URL first, and ships one application key inside its image. This template's image takes APP_KEY from a generated secret, creates the first admin from ADMIN_EMAIL (admin@ plus the service domain) and ADMIN_PASSWORD, and creates an API token from API_TOKEN, all at boot. After that the /register page answers 404. Change the email or password in the app and the new values stay; the variables only matter on an empty database.
What persists. The database and generated screens live on the volume at /data. Redeploys keep users, devices, playlists, plugins and the API token, and the application key is a stable variable, so existing sessions and encrypted settings keep working.
Pointing a TRMNL device at it. In the device's setup, set the custom server to the public URL of the larapaper service, then add the device in the web interface (sign in with ADMIN_EMAIL and ADMIN_PASSWORD).
Agent contract
- Public URL:
https://RAILWAY_PUBLIC_DOMAIN(the generated domain of thelarapaperservice) - Private URL:
http://larapaper.railway.internal:8080 - Credentials: the variables
ADMIN_EMAILandADMIN_PASSWORD(web sign-in) andAPI_TOKEN(REST API), set on thelarapaperservice - Auth: send
Authorization: Bearerfollowed by theAPI_TOKENvalue andAccept: application/json; without a valid token every/apiuser endpoint answers401 - Health:
GET /healthcheckreturns 200
# needs: SITE_URL (public https URL of the larapaper service) and API_TOKEN (its variable); also curl, sed
AUTH="Authorization: Bearer $API_TOKEN"
curl -s -o /dev/null -w "health: %{http_code}\n" "$SITE_URL/healthcheck"
curl -s -o /dev/null -w "register page (closed): %{http_code}\n" "$SITE_URL/register"
curl -s -H "$AUTH" -H 'Accept: application/json' "$SITE_URL/api/user" | sed -n 's/.*"email":"\([^"]*\)".*/admin: \1/p'
curl -s -o /dev/null -w "read without key: %{http_code}\n" -H 'Accept: application/json' "$SITE_URL/api/plugin_settings"
curl -s -o /dev/null -w "write without key: %{http_code}\n" -X POST -H 'Accept: application/json' "$SITE_URL/api/plugin_settings"
curl -s -o /dev/null -w "write wrong key: %{http_code}\n" -X POST -H 'Authorization: Bearer wrong' -H 'Accept: application/json' "$SITE_URL/api/plugin_settings"
ID=$(curl -s -X POST -H "$AUTH" -H 'Accept: application/json' "$SITE_URL/api/plugin_settings" | sed -n 's/.*"id":"\([^"]*\)".*/\1/p')
echo "plugin created: $ID"
curl -s -H "$AUTH" -H 'Accept: application/json' "$SITE_URL/api/plugin_settings" | sed -n 's/.*"name":"\([^"]*\)".*/listed: \1/p'
curl -s -o /dev/null -w "plugin delete: %{http_code}\n" -X DELETE -H "$AUTH" -H 'Accept: application/json' "$SITE_URL/api/plugin_settings/$ID"
A fresh deploy prints health: 200, register page (closed): 404, the admin email, read without key: 401, write without key: 401, write wrong key: 401, a created plugin id, listed: New TRMNLP Plugin and plugin delete: 204.
Why Deploy LaraPaper on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying LaraPaper on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
- Agent-ready - no deployer fields, a contract block and one script that proves the API token, a write and the refusal without a key.
- Closed from the first request - the admin and the API token come from generated secrets, registration answers 404, and the application key is not shared with other installs.
- Data survives redeploys - the database and generated screens sit on a volume, the application key is stable.
- Pinned - the image is pinned by digest.
- No cloud account for your displays - screens, playlists and device data stay on your own service.
Common Use Cases
- Self-hosted TRMNL server - run your own BYOS server for TRMNL e-ink displays instead of the vendor cloud.
- Home and office dashboards - calendars, weather, transit and task lists rendered to an e-ink screen.
- Custom plugins and recipes - build screens from your own data with the plugin editor and webhooks.
- Agent-driven screens - an agent creates plugins and pushes content through the API token.
Dependencies for LaraPaper Hosting
- Nothing else: SQLite runs inside the service on its volume. A custom domain is optional.
Deployment Dependencies
Template Content
