> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fs.soquincy.qzz.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Hosting Freesona: Local, Docker, Railway, and Render

> Deploy Freesona locally with setup scripts, containerize it with Docker, or push it to Railway or Render for managed cloud hosting.

Freesona runs wherever Python runs. You can spin it up on your own machine in minutes with the included setup scripts, containerize it with the provided Dockerfile, or push it to a managed platform like Railway or Render. Pick the approach that matches your infrastructure — the bot behaves identically across all of them.

<Tabs>
  <Tab title="Local">
    Use the included setup scripts for a guided local setup. The scripts handle everything from `.env` creation to launching the bot.

    **Linux / macOS**

    ```bash theme={null}
    bash scripts/setup_local.sh
    ```

    **Windows**

    ```bat theme={null}
    scripts\setup_local.cmd
    ```

    **What the scripts do:**

    1. Create `.env` from `.env.sample` on first run — open it and fill in your real Discord IDs and provider keys before continuing.
    2. Validate `BOT_TOKEN`, `CHANNEL_ID`, `AI_PROVIDER`, and the matching provider API key (e.g., `GOOGLE_API_KEY` for Gemini, `OPENAI_API_KEY` for OpenAI).
    3. Create a `.venv` virtual environment and install dependencies from `requirements.txt`.
    4. Run `scripts/check_project.py` to verify syntax and config.
    5. Launch the bot with `python main.py`.

    If you already have a configured `.env` and just want to start the bot manually, run:

    ```bash theme={null}
    python main.py
    ```

    <Note>
      The local setup scripts are for manual hosting only — do not use them for Docker or cloud platforms. On Docker, Railway, and Render, the platform owns the bootstrap process.
    </Note>
  </Tab>

  <Tab title="Docker">
    A `Dockerfile` is included. It uses the official `python:3.13-slim` image and installs `ffmpeg` and Node.js alongside the Python dependencies, so `~download`, `~audio`, and `~separate` work out of the box.

    **Build and run:**

    ```bash theme={null}
    docker build -t freesona .
    docker run -d --env-file .env --name freesona freesona
    ```

    **Mount a volume for persistence:**

    Without a volume, `config.json`, `memory.db`, `warnings.db`, and other storage files are lost when the container is replaced. Mount a local directory at `/data` to persist them:

    ```bash theme={null}
    docker run -d \
      --env-file .env \
      -v $(pwd)/data:/data \
      --name freesona freesona
    ```

    Then point the file-path variables in your `.env` at `/data/`:

    ```dotenv theme={null}
    CONFIG_FILE_PATH=/data/config.json
    MEMORY_FILE_PATH=/data/memory.db
    WARNINGS_FILE_PATH=/data/warnings.db
    ANNIVERSARIES_FILE_PATH=/data/anniversaries.db
    AI_PERSONA_JSON_FILE=/data/persona.json
    AI_PERSONAS_FILE=/data/personas.json
    ```

    The container exposes port `10000` for the built-in health check and MVSEP webhook endpoints. Override the port with `HTTP_PORT` in `.env` if needed.
  </Tab>

  <Tab title="Railway">
    Railway detects the included `Dockerfile` automatically. Fork the repo, connect it to a Railway project, and follow these steps:

    <Steps>
      <Step title="Fork the repo and connect it to Railway">
        Fork `soquincy/Freesona` on GitHub, then create a new Railway project and select **Deploy from GitHub repo**, pointing it at your fork.
      </Step>

      <Step title="Add environment variables">
        Open the **Variables** panel and add all required `.env` values — at minimum `BOT_TOKEN`, `CHANNEL_ID`, `AI_PROVIDER`, and the matching provider API key.
      </Step>

      <Step title="Mount a volume at /data">
        In the Railway service settings, add a **Volume** and mount it at `/data`. This keeps your config and database files alive across deploys.
      </Step>

      <Step title="Set file path variables to /data/">
        Add these to the Variables panel so Freesona writes its state files to the mounted volume:

        ```dotenv theme={null}
        CONFIG_FILE_PATH=/data/config.json
        MEMORY_FILE_PATH=/data/memory.db
        WARNINGS_FILE_PATH=/data/warnings.db
        ANNIVERSARIES_FILE_PATH=/data/anniversaries.db
        AI_PERSONA_JSON_FILE=/data/persona.json
        AI_PERSONAS_FILE=/data/personas.json
        ```
      </Step>

      <Step title="Deploy">
        Trigger a deploy. Railway builds the `Dockerfile` and starts the bot. Check the deployment logs to confirm the bot connects to Discord.
      </Step>
    </Steps>

    <Warning>
      Without a persistent volume, `config.json`, `memory.db`, and `warnings.db` are lost on every redeploy. Your prefix, enabled modules, autonomy settings, conversation channel, warning history, and all long-term user memory will be wiped.
    </Warning>
  </Tab>

  <Tab title="Render">
    Render can run Freesona as a Web Service using the included `Dockerfile`. Use a Render Disk for persistent storage.

    <Steps>
      <Step title="Fork the repo and create a Web Service">
        Fork `soquincy/Freesona` on GitHub, then create a new **Web Service** on Render and connect it to your fork. Render will detect the `Dockerfile` automatically.
      </Step>

      <Step title="Set environment variables">
        Open the **Environment** page for the service and add all required variables — `BOT_TOKEN`, `CHANNEL_ID`, `AI_PROVIDER`, and your provider API key.
      </Step>

      <Step title="Create a Disk mounted at /data">
        In the service settings, add a **Disk** and set the mount path to `/data`. This persists your storage files across deploys and restarts.
      </Step>

      <Step title="Set file path variables to /data/ paths">
        Add the following to the Environment page:

        ```dotenv theme={null}
        CONFIG_FILE_PATH=/data/config.json
        MEMORY_FILE_PATH=/data/memory.db
        WARNINGS_FILE_PATH=/data/warnings.db
        ANNIVERSARIES_FILE_PATH=/data/anniversaries.db
        AI_PERSONA_JSON_FILE=/data/persona.json
        AI_PERSONAS_FILE=/data/personas.json
        ```
      </Step>

      <Step title="Deploy">
        Trigger a deploy. Confirm the bot comes online by checking the Render service logs.
      </Step>
    </Steps>
  </Tab>
</Tabs>

## Persistence

Freesona uses a small set of files to store all runtime state. Keep these files on a persistent volume in any cloud environment:

| File               | Contents                                                               |
| ------------------ | ---------------------------------------------------------------------- |
| `config.json`      | Prefix, channel IDs, autonomy settings, module enabled/disabled states |
| `persona.json`     | Active persona fields (core, background, beliefs, style, instructions) |
| `personas.json`    | Saved persona presets                                                  |
| `memory.db`        | Long-term user facts, keyed by `guild_id + user_id`                    |
| `warnings.db`      | Moderation warnings with per-guild hex IDs and timestamps              |
| `anniversaries.db` | User-claimed anniversary entries                                       |
| `.chroma/`         | ChromaDB vector store for knowledge base retrieval (optional)          |

On a local setup these files live in the project folder. On Docker, Railway, or Render, point all `*_FILE_PATH` environment variables at your `/data/` mount to ensure they survive restarts and redeployments.
