# Installing and Updating an Extension

ClickHouse supports <span class="s1">**custom extensions**</span> via \[User Defined Functions (UDFs)\], external dictionaries, and shared libraries that extend its core capabilities with custom logic, formats, or integrations. These behave similarly to modules or plugins in other systems and must be configured at server startup. Common examples include integration with geospatial libraries, custom UDFs, or external dictionary sources like MySQL or HTTP.

In Elestio-hosted ClickHouse instances or any Docker Compose-based setup, extensions can be added by mounting external libraries or configuration files and referencing them in <span class="s3">config.xml</span> or <span class="s3">users.xml</span>. This guide walks through how to install, load, and manage ClickHouse extensions using Docker Compose along with best practices and common troubleshooting steps.

## **Installing and Enabling ClickHouse Extensions**

ClickHouse extensions are typically compiled as shared objects (<span class="s3">.so</span>) files or defined as configuration files for dictionaries or formats. These files must be mounted into the container and referenced explicitly in the server’s configuration files.

#### **Example: Load Custom Shared Library UDF**

Suppose you have a compiled UDF called `<span class="s3">libexample_udf.so</span>`. To include it in a Docker Compose setup:

##### **Update docker-compose.yml**

Mount the shared library into the container:

```yaml
services:
  clickhouse:
    image: clickhouse/clickhouse-server:latest
    volumes:
      - ./modules/libexample_udf.so:/usr/lib/clickhouse/user_defined/libexample_udf.so
      - ./configs/config.xml:/etc/clickhouse-server/config.xml
    ports:
      - "8123:8123"
      - "9000:9000"
```

- `<span class="s1">./modules/libexample_udf.so</span>`: local path to the shared library on the host.
- `<span class="s1">/usr/lib/clickhouse/user_defined/</span>`: default directory for user libraries inside the container.

Make sure the file exists before running Docker Compose.

##### **Configure config.xml to Load the UDF**

In your custom <span class="s2">config.xml</span>:

```xml
<user_defined>
    <function>
        <name>example_udf</name>
        <type>udf</type>
        <library>libexample_udf.so</library>
    </function>
</user_defined>
```

> The library path must match the volume mount location.

##### **Restart the ClickHouse Service**

After updating the Compose and configuration files, restart the service:

```
docker-compose down
docker-compose up -d
```

This will reload ClickHouse with the specified UDF.

##### **Verify the Extension is Loaded**

Connect using the ClickHouse CLI or HTTP interface and run:

```
SELECT example_udf('test input');
```

If successful, the function will return expected results from the loaded library. You can also confirm the server loaded your shared library by inspecting logs:

```
docker-compose logs clickhouse
```

Look for lines that indicate the library was found and loaded.

## **Managing External Dictionaries**

ClickHouse supports loading external data sources (like MySQL, HTTP APIs, or files) as dictionaries

##### **Mount Dictionary Configuration**

<span class="s2">In </span>docker-compose.yml<span class="s2">:</span>

```
volumes:
  - ./configs/dictionaries/:/etc/clickhouse-server/dictionaries/
```

##### **Reference in config.xml**

```xml
<dictionaries_config>/etc/clickhouse-server/dictionaries/*.xml</dictionaries_config>
```

Example dictionary file (<span class="s1">mysql\_dictionary.xml</span>):

```xml
<dictionary>
  <name>mysql_dict</name>
  <source>
    <mysql>
      <host>mysql-host</host>
      <user>root</user>
      <password>password</password>
      <db>test</db>
      <table>cities</table>
    </mysql>
  </source>
  <layout><flat /></layout>
  <structure>
    <id>id</id>
    <attribute>
      <name>name</name>
      <type>String</type>
    </attribute>
  </structure>
</dictionary>
```

Use the dictionary in queries:

```
SELECT dictGetString('mysql_dict', 'name', toUInt64(42));
```

## **Updating or Removing Extensions**

ClickHouse doesn’t support unloading UDFs or dictionaries at runtime. To modify or remove an extension:

**1. Stop the container**<span class="s1">:</span>

```
docker-compose down
```

**2. Edit config files**<span class="s1">:</span>

- Replace or remove the <span class="s1">&lt;function&gt;</span> entry in <span class="s1">config.xml</span> or dictionary config.
- Replace or remove the <span class="s1">.so</span> file if applicable.

**3. Restart the container**<span class="s1">:</span>

```
docker-compose up -d
```

> Always test changes in staging before deploying to production.

## **Troubleshooting Common Extension Issues**

<table border="1" id="bkmrk-issue-cause-resoluti" style="border-collapse: collapse; border-color: rgb(0, 0, 0);"><thead><tr><th style="border-color: rgb(0, 0, 0);">**Issue**

</th><th style="border-color: rgb(0, 0, 0);">**Cause**

</th><th style="border-color: rgb(0, 0, 0);">**Resolution**

</th></tr></thead><tbody><tr><td style="border-color: rgb(0, 0, 0);">ClickHouse fails to start

</td><td style="border-color: rgb(0, 0, 0);">Invalid config or missing <span class="s1">.so</span> file

</td><td style="border-color: rgb(0, 0, 0);">Run <span class="s1">docker-compose logs clickhouse</span> and fix missing files or XML syntax

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">UDF not recognized

</td><td style="border-color: rgb(0, 0, 0);">Wrong library path or missing permissions

</td><td style="border-color: rgb(0, 0, 0);">Ensure volume mount is correct and file is executable inside container

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Dictionary not available

</td><td style="border-color: rgb(0, 0, 0);">Config file not found or misconfigured XML

</td><td style="border-color: rgb(0, 0, 0);"><span class="s1">Double-check </span>dictionaries\_config<span class="s1"> and validate with </span>SHOW DICTIONARIES

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Segmentation fault

</td><td style="border-color: rgb(0, 0, 0);">Invalid shared library or ABI mismatch

</td><td style="border-color: rgb(0, 0, 0);">Recompile UDF for correct platform, verify against installed ClickHouse version

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Query fails silently

</td><td style="border-color: rgb(0, 0, 0);">Dictionary or UDF not fully loaded

</td><td style="border-color: rgb(0, 0, 0);">Recheck server logs for errors during startup

</td></tr></tbody></table>

## **Security Considerations**

ClickHouse extensions especially shared libraries run with the same privileges as the ClickHouse server. Be cautious:

- Only load trusted <span class="s1">.so</span> files from verified sources.
- Ensure <span class="s1">clickhouse</span> user has restricted permissions inside the container.
- Never expose dictionary or UDF paths to writable directories from external systems.

Avoid using custom UDFs or dictionaries from unknown sources in production environments without a thorough code review.