> ## Documentation Index > Fetch the complete documentation index at: https://bunny.net/docs/llms.txt > Use this file to discover all available pages before exploring further. # ClickHouse > Deploy ClickHouse to Magic Containers This guide walks you through deploying ClickHouse to Magic Containers, either as a standalone container or as part of a [multi-container](https://bunny.net/docs/magic-containers/multi-container.md) app alongside your application. > [!TIP] > > Don't have a bunny.net account yet? [Sign up](https://dash.bunny.net/auth/register) and enable Magic Containers to get started. ## Quickstart **1. Create a new app** Go to the [bunny.net dashboard](https://dash.bunny.net), select **Magic Containers**, and click **Add App**. Select **Single region deployment**. > [!WARNING] > > Databases should use single region deployment with a single instance. Each pod gets its own dedicated volume with no data replication — this applies both across regions and within the same region. Scaling to multiple pods or regions would result in separate, isolated databases each with their own data. **2. Add the ClickHouse container** Click **Add Container** and configure the image: * **Registry**: Docker Hub * **Image**: `clickhouse/clickhouse-server` * **Tag**: `latest` Magic Containers will automatically detect the required endpoint and environment variables for the image. Configure the environment variables as needed: * `CLICKHOUSE_DB` = `app` * `CLICKHOUSE_USER` = `app` * `CLICKHOUSE_PASSWORD` = a strong password * `CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT` = `1` **3. Add persistent volumes** In the **Volumes** section of the container settings, add two volumes: * **Name**: `clickhouse-data`, **Mount path**: `/var/lib/clickhouse` * **Name**: `clickhouse-logs`, **Mount path**: `/var/log/clickhouse-server` This ensures your database files and logs persist across restarts and redeployments. Without volumes, all data is lost when the container stops. See [persistent volumes](https://bunny.net/docs/magic-containers/persistent-volumes.md) for more details on volume behavior and pricing. **4. Deploy** Review your settings and click **Confirm and Create**. > [!NOTE] > > Always set a strong `CLICKHOUSE_PASSWORD`, even if ClickHouse is not exposed > externally. Other containers in the same pod can access the network, and a > password protects against accidental or unauthorized access. ## Environment variables The official ClickHouse image supports these environment variables: | Variable | Description | Default | | - | - | - | | `CLICKHOUSE_DB` | Default database created on start | `default` | | `CLICKHOUSE_USER` | Username to create | `default` | | `CLICKHOUSE_PASSWORD` | Password for the user | - | | `CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT` | Enable SQL-driven access management | `0` | ## Connect from your app In a [multi-container](https://bunny.net/docs/magic-containers/multi-container.md) setup, your app and ClickHouse share the same localhost network. ClickHouse exposes two interfaces: * **HTTP**: port `8123` * **Native**: port `9000` > [tab] HTTP > > ``` > http://app:YOUR_PASSWORD@127.0.0.1:8123/?database=app > ``` > [tab] Node.js > > ```javascript theme={null} > import { createClient } from "@clickhouse/client"; > > const client = createClient({ > url: "http://127.0.0.1:8123", > username: "app", > password: process.env.CLICKHOUSE_PASSWORD, > database: "app", > }); > > const result = await client.query({ query: "SELECT now()" }); > ``` > [tab] Go > > ```go theme={null} > import "github.com/ClickHouse/clickhouse-go/v2" > > conn, err := clickhouse.Open(&clickhouse.Options{ > Addr: []string{"127.0.0.1:9000"}, > Auth: clickhouse.Auth{ > Database: "app", > Username: "app", > Password: os.Getenv("CLICKHOUSE_PASSWORD"), > }, > }) > if err != nil { > log.Fatal(err) > } > defer conn.Close() > ``` > [tab] Python > > ```python theme={null} > import clickhouse_connect > > client = clickhouse_connect.get_client( > host="127.0.0.1", > port=8123, > username="app", > password=os.environ["CLICKHOUSE_PASSWORD"], > database="app", > ) > > result = client.query("SELECT now()") > ``` ## Multi-container example A typical setup pairs ClickHouse with your application. When configuring the app, add two containers: ### App container * **Image**: your app image (e.g. `ghcr.io//my-app:latest`) * **Endpoint**: the port your app listens on * **Environment variables**: * `CLICKHOUSE_PASSWORD` = a strong password ### ClickHouse container * **Image**: `clickhouse/clickhouse-server:latest` * **Volumes**: `/var/lib/clickhouse` and `/var/log/clickhouse-server` * **Environment variables**: * `CLICKHOUSE_DB` = `app` * `CLICKHOUSE_USER` = `app` * `CLICKHOUSE_PASSWORD` = a strong password * `CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT` = `1` > [!NOTE] > > Both containers share the same localhost network, so your app connects to > ClickHouse at `127.0.0.1:8123` (HTTP) or `127.0.0.1:9000` (native). See > [multi-container apps](https://bunny.net/docs/magic-containers/multi-container.md) for more details. ## External access To connect to ClickHouse from outside Magic Containers (e.g. from your local terminal), add either a [CDN or Anycast endpoint](https://bunny.net/docs/magic-containers/endpoints.md). CDN endpoints work for ClickHouse's HTTP interface only; Anycast endpoints support both HTTP and the native protocol. ### Anycast endpoint 1. Go to your app's **Endpoints** tab and click **Add New Endpoint** 2. Select **Anycast** as the type 3. Set **Container Port** to `8123` 4. Set **Exposed Port** to `8123` 5. Click **Add Endpoint** Then connect using the Anycast IP and the **exposed port**: ```bash theme={null} curl "http://:/?query=SELECT+1&user=app&password=YOUR_PASSWORD" ``` Or using the ClickHouse client: ```bash theme={null} clickhouse-client --host --port --user app --password YOUR_PASSWORD ``` > [!NOTE] > > The exposed port and container port may differ. When connecting externally, > always use the exposed port shown in your endpoint configuration. > [!NOTE] > > The `clickhouse-client` uses the native protocol (port `9000`). If you want to > use the native client externally, add a second Anycast endpoint for port > `9000`. ### CDN endpoint A CDN endpoint exposes ClickHouse's HTTP interface through bunny.net's edge network at a `b-cdn.net` hostname, giving you HTTPS out of the box. 1. Go to your app's **Endpoints** tab and click **Add New Endpoint** 2. Select **CDN** as the type 3. Set **Container Port** to `8123` 4. Click **Add Endpoint** Then connect using the assigned hostname. Replace `username` and `password` with your `CLICKHOUSE_USER` and `CLICKHOUSE_PASSWORD`, and `database` with your `CLICKHOUSE_DB`. > [tab] Query > > ```bash theme={null} > curl -u 'username:password' \ > 'https://mc-abc123xyz0.b-cdn.net/?query=SELECT+1' > ``` > [tab] Create > > ```bash theme={null} > curl -u 'username:password' \ > 'https://mc-abc123xyz0.b-cdn.net/?database=database' \ > --data-binary " > CREATE TABLE IF NOT EXISTS events ( > ts DateTime, > user_id UInt64, > event String, > value Float64 > ) > ENGINE = MergeTree() > ORDER BY (ts, user_id) > " > ``` > [tab] Insert > > ```bash theme={null} > curl -u 'username:password' \ > 'https://mc-abc123xyz0.b-cdn.net/?database=database&query=INSERT+INTO+events+FORMAT+JSONEachRow' \ > --data-binary ' > {"ts":"2026-04-20 10:00:00","user_id":1,"event":"view","value":1.0} > {"ts":"2026-04-20 10:01:00","user_id":2,"event":"click","value":2.5} > {"ts":"2026-04-20 10:02:00","user_id":1,"event":"view","value":1.0} > ' > ``` > [tab] Aggregate > > ```bash theme={null} > curl -u 'username:password' \ > 'https://mc-abc123xyz0.b-cdn.net/?database=database' \ > --data-binary " > SELECT event, count() AS n, sum(value) AS total > FROM events > GROUP BY event > ORDER BY n DESC > FORMAT PrettyCompact > " > ``` > [!WARNING] > > CDN endpoints are publicly reachable with no authentication at the edge — > anyone who knows the hostname can reach ClickHouse, and only the database's > basic auth stands in the way. Always set a strong `CLICKHOUSE_PASSWORD` > (never leave it as `clickhouse/clickhouse`), especially with > `CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1` enabled. > [!NOTE] > > CDN endpoints only expose the HTTP interface (port `8123`). The native > protocol (port `9000`) and clients that depend on it — including > `clickhouse-client` without `--secure` and most BI tools' native drivers — > won't work. Use HTTP-based drivers, or add an Anycast endpoint for port > `9000`. > [!WARNING] > > Exposing your database to the internet means anyone with the credentials can > connect. Use a strong password and consider removing the endpoint when > external access is no longer needed. This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.