# How to Deploy CloddsBot Using Docker and systemd in Production

> Deploy CloddsBot in production using Docker or systemd. Learn to containerize with persistent volumes or install as a hardened systemd service for reliable operation.

- Repository: [AL/CloddsBot](https://github.com/alsk1992/CloddsBot)
- Tags: how-to-guide
- Published: 2026-09-11

---

**Deploy CloddsBot in production by either running the Node.js 22-based container with persistent volume mounts for SQLite state, or by installing the compiled TypeScript output as a hardened systemd service with strict sandboxing and journal logging.**

CloddsBot is a Node-based gateway application from the `alsk1992/CloddsBot` repository that bridges AI services and messaging platforms. Whether you choose containerized isolation or native Linux service management, the deployment requires configuring environment variables for API keys, mounting persistent storage for the SQLite database, and exposing the health-check endpoint on port 18789.

## Architecture Overview for Production Deployments

### Multi-Stage Container Build

According to the `Dockerfile` in the repository root, CloddsBot uses a two-stage build process based on `node:22-bookworm-slim`. The `builder` stage compiles TypeScript source files, while the `runner` stage copies only the `dist/` directory and installs production dependencies. This approach minimizes the final image size and attack surface.

### State Persistence Strategy

The runtime expects `CLODDS_STATE_DIR=/data` (defined in the Dockerfile), which stores the SQLite database at `/data/clodds.db`, backup files, and transformer model caches. In both Docker and systemd deployments, this directory must be a persistent host mount (`clodds_data` volume or `/var/lib/clodds`) to prevent data loss during restarts.

### Health Monitoring

The application exposes a `/health` HTTP endpoint on port 18789. Both Docker and systemd can monitor this endpoint to determine service readiness and trigger automatic restarts when the gateway becomes unresponsive.

## Docker Deployment Methods

### Single-Container Deployment

Build the production image from the repository root and run it with explicit environment variables:

```bash
docker build -t clodds .

docker run --rm \
  -p 18789:18789 \
  -e ANTHROPIC_API_KEY=sk-ant-... \
  -e TELEGRAM_BOT_TOKEN=YOUR_TOKEN \
  -e WEBCHAT_TOKEN=optional-token \
  -v clodds_data:/data \
  clodds

```

The `-v clodds_data:/data` mount ensures the SQLite database persists across container restarts inside the named volume mapped to `CLODDS_STATE_DIR`.

### Docker Compose Production Configuration

For multi-container orchestration or simpler management, use the provided [`docker-compose.yml`](https://github.com/alsk1992/CloddsBot/blob/main/docker-compose.yml) structure:

```yaml
services:
  clodds:
    build: .
    ports:
      - "18789:18789"
    env_file:
      - .env
    environment:
      CLODDS_STATE_DIR: /data
      CLODDS_WORKSPACE: /data/workspace
      CLODDS_CONFIG_PATH: /data/clodds.json
    volumes:
      - clodds_data:/data
    restart: unless-stopped

volumes:
  clodds_data:

```

Deploy with:

```bash
docker compose up -d --build

```

The `env_file` directive loads variables from `.env` (based on `.env.example` in the repository), while `restart: unless-stopped` ensures the gateway recovers automatically from crashes.

## Native systemd Deployment

### Service Unit Configuration

For hosts requiring tighter control over user permissions and security hardening, install CloddsBot as a systemd service. Create `/etc/systemd/system/clodds.service`:

```ini
[Unit]
Description=Clodds Gateway
After=network.target

[Service]
Type=simple
User=clodds
Group=clodds
WorkingDirectory=/opt/clodds
EnvironmentFile=/etc/clodds/clodds.env
ExecStart=/usr/bin/node /opt/clodds/dist/index.js
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/clodds
PrivateTmp=true

[Install]
WantedBy=multi-user.target

```

The `ProtectSystem=strict` and `NoNewPrivileges=true` directives sandbox the Node.js process according to production hardening guidelines in [`docs/DEPLOYMENT.md`](https://github.com/alsk1992/CloddsBot/blob/main/docs/DEPLOYMENT.md).

### Host Preparation

Prepare the system user and directories before enabling the service:

```bash
sudo useradd -r -s /sbin/nologin clodds

sudo mkdir -p /opt/clodds /var/lib/clodds /etc/clodds
sudo chown clodds:clodds /var/lib/clodds

sudo cp -r dist/* /opt/clodds/
sudo cp .env /etc/clodds/clodds.env
sudo chmod 600 /etc/clodds/clodds.env

sudo systemctl daemon-reload
sudo systemctl enable clodds
sudo systemctl start clodds

```

The service executes [`/opt/clodds/dist/index.js`](https://github.com/alsk1992/CloddsBot/blob/main//opt/clodds/dist/index.js) directly—the same compiled entry point used by the Docker container—while writing logs to the systemd journal.

## Environment Configuration and Secrets Management

### Required Variables

Both deployment methods require identical environment variables defined in `.env.example`:

- `ANTHROPIC_API_KEY` – AI service authentication
- `TELEGRAM_BOT_TOKEN` – Messaging platform integration
- `WEBCHAT_TOKEN` – Optional web interface access
- `CLODDS_STATE_DIR` – Path to SQLite storage (`/data` in containers, `/var/lib/clodds` for systemd)

### Securing Credentials

In systemd deployments, store the environment file at `/etc/clodds/clodds.env` with permissions `600` (readable only by root and the `clodds` user). Reference this file in the systemd unit via the `EnvironmentFile` directive. Docker deployments should use Docker secrets or mounted env files with restricted host permissions rather than inline `-e` flags in production scripts.

## Summary

- CloddsBot uses **Node.js 22-bookworm-slim** for minimal container images and supports direct execution via [`dist/index.js`](https://github.com/alsk1992/CloddsBot/blob/main/dist/index.js) for systemd.
- **Persistent state** requires mounting `CLODDS_STATE_DIR` (containing `clodds.db`) to either a Docker named volume or `/var/lib/clodds` on the host.
- The **health endpoint** on port 18789 enables automated monitoring in both Docker and systemd configurations.
- **systemd hardening** options like `ProtectSystem=strict` and `NoNewPrivileges=true` provide security parity with container sandboxing.
- Environment variables configure AI credentials and storage paths; systemd deployments use `EnvironmentFile` while Docker uses `.env` files or `-e` flags.

## Frequently Asked Questions

### What Node.js version does CloddsBot require for production?

CloddsBot requires **Node.js 22** (specifically the `node:22-bookworm-slim` image in Docker). The `Dockerfile` uses a multi-stage build where the `builder` stage compiles TypeScript and the `runner` stage executes the compiled [`dist/index.js`](https://github.com/alsk1992/CloddsBot/blob/main/dist/index.js) file.

### Where does CloddsBot store SQLite data in production?

The application stores its SQLite database at `$CLODDS_STATE_DIR/clodds.db`, which defaults to `/data/clodds.db` inside containers. For production, mount a persistent volume to `/data` in Docker or set `ReadWritePaths=/var/lib/clodds` in the systemd service unit.

### How do I secure the Telegram bot token when deploying with systemd?

Place the token in `/etc/clodds/clodds.env` with permissions set to `600` (owner read/write only). Reference this file in the systemd unit via the `EnvironmentFile` directive. The service runs as a dedicated `clodds` user with `NoNewPrivileges=true` to prevent credential leaks.

### Can I run CloddsBot on a host without Docker?

Yes. Compile the TypeScript source with `npm run build`, copy the `dist/` directory to `/opt/clodds/`, and run [`dist/index.js`](https://github.com/alsk1992/CloddsBot/blob/main/dist/index.js) directly via the systemd service unit. This method provides tighter integration with host logging (journald) and security modules (AppArmor/SELinux).