xhostd
Sign in Start building
← Solutions

Run a bot or data tool on xhostd

Run a chat bot or data tool on xhostd: a background worker with Postgres, secrets in the environment, logs to watch it, and a plan sized to fit.

A bot answers messages. A data tool fetches, cleans, and serves information. Both share a shape: a loop that runs all the time, a small database, and a few secrets. This article shows how to run that shape on xhostd, and what to watch once it runs.

You need an xhostd account and an AI coding agent connected to it. If you have not connected one yet, start with the getting started guide.

Choose the shape of the app

Decide first whether the tool serves web requests.

  • A worker runs a loop and serves no page. A bot that listens to a message service is a worker.
  • A web app serves a page or an API. A data tool that people open in a browser is a web app.
  • Both run as separate apps when you need both, and each app has its own channels.

A worker runs on the app template, and it serves no HTTP. Its channel keeps an HTTPS address, and that address returns an error, which is expected. The output of a worker is its log.

Step 1: ask your agent for the app

Give the agent a clear brief. For example:

Build a Python worker that checks a data source every 10 minutes,
stores new rows in Postgres, and logs one line per check.
Deploy it to xhostd as a background worker.

The agent creates the app, commits the code, and deploys it. The worker recipe shows the files it needs.

Step 2: tell the platform the worker is ready

Every deploy runs a health check. A web app passes when it answers a request. A worker binds no port, so it signals readiness another way: it creates the file named in $XHOSTD_READY_FILE once its configuration is valid. Ask your agent to do this after it reads its settings, so a bad setting stops the worker and fails the deploy.

Flush every log line. Python buffers output that does not go to a terminal, and a worker that does not flush looks silent in the runtime log.

Step 3: keep state in Postgres

The container's local disk does not survive a redeploy. Each deploy builds a new container and discards the old one. Keep anything that must last in the database, or in object storage for files.

Each channel that runs code has its own Postgres database, and your code reads its connection details from the environment. The Postgres recipe covers migrations and the snapshot xhostd takes before every deploy.

Step 4: keep secrets out of the code

A bot has tokens and a data tool has keys. Ask your agent to set them as environment variables for the channel. Values are encrypted at rest and added when the container starts. They are never built into the image. Store each token and key as a secret: the agent sets the secret flag, and the console has a Store as a secret checkbox. Your agent can set a secret, and it cannot read one back unless you allow that in the console. A plain variable is the default kind, and your agent can read its value, so never store a token as one.

Step 5: test before production

Ask your agent for a second channel, deploy the change there, and read the log. A preview channel has its own empty database, so a test cannot touch real data. When it behaves, deploy the same commit to prod. See Preview and staging environments on xhostd.

Step 6: watch it run

A worker has no page to open, so use the tools that report on it.

  • Runtime log. Your agent reads it, and the console shows a recent part of it.
  • Health. The console shows findings about the channel and what to do about them.
  • Usage. The console shows your account's resources against your plan.

Choose a plan

A small worker and a small database fit in a small plan. Start on Basic, watch Usage for a few days, and upgrade when a limit tells you to. The pricing page states what each plan holds.

Nothing is metered per request. The plan sets the resources, and a busy day does not raise the price.