Search code examples
node.jsdockerclickhouse

Can not connect with click-house running inside docker with nodejs


I have downloaded this click-house docker image https://hub.docker.com/r/clickhouse/clickhouse-server/

I started click-house server with the following command

docker run  --network=host --name some-clickhouse-server --ulimit nofile=262144:262144 clickhouse/clickhouse-server

I connected with clickhouse with the following command

docker exec -it some-clickhouse-server clickhouse-client

Output of the above command

ClickHouse client version 24.1.5.6 (official build).
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 24.1.5.

Warnings:
 * Delay accounting is not enabled, OSIOWaitMicroseconds will not be gathered. Check /proc/sys/kernel/task_delayacct

As you can see in the above command click house is using port 9000.

Problem

AS per the docs, click-house has HTTP Interface which listens on port 8123 by default. I tried to access 8123 port using my browser, but i got the following error.

Same is true for port 9000 as well.

enter image description here

I am using host network in docker, so I should be able to connect this interface from my browser.

Same is happening for nodejs as well

const { ClickHouse } = require("clickhouse");
const clickhouse = new ClickHouse({
  url: "http://localhost",
  port: 9000,
});


Getting the following error on terminal

Error inserting row: Error: connect ECONNREFUSED ::1:9000
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1532:16) {
  errno: -61,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '::1',
  port: 9000
}

Here is docs for nodejs client.

What could be the wrong?


Solution

  • Host networking only "works" in one specific host-OS configuration (running Docker engine without Docker Desktop on a native-Linux system). It generally disables Docker's networking layer and with it some key features, like connecting to other containers by name and the ability to hide or remap ports on the hosts. For most cases I'd recommend avoiding host networking.

    The standard way to get access to a container's port is by publishing a port using a docker run -p option. In your example the container seems to listen on ports 8123 and 9000, so you'd need two -p options

    docker run -p 8123:8123 -p 9000:9000 ...
    # without `--network=host`
    

    In those options the second port numbers are the port inside the container, and must match what the server process inside the container is using. The first port number is the host port and can be any port that's not already in use. In your browser or in client code running directly on the host, you'd use the first port number.

    Docker documentation mentions "exposing" ports as well; this is an obsolete option from first-generation Docker networking and does nothing in modern Docker. Port mapping and host networking aren't compatible and you should get a warning if you have both --net host and a -p option; make sure you remove the --network=host setting.