2

I'm working on a project where my Rust application is containerized using Docker. I've encountered an issue where the Rust program can only connect to the PostgreSQL database when the container is run with the host networking mode. Here are the details of my setup and what I've tried so far:

Docker Compose Setup

I have the following services defined in my docker-compose.yml:

version: "3.8"

services:
  sensor-db:
    image: postgres:14-alpine
    restart: unless-stopped
    volumes:
      - ./configuration/sensordb/initdb:/docker-entrypoint-initdb.d
      - ./sensor-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=xxx

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redisdata:/data

  chirpstack-cim-integration:
    image: xxx/chirpstack-cim-integration/chirpstack-cim-integration:latest
    restart: unless-stopped
    environment:
      - REDIS_CONNECTION=redis://redis:6379
      - PG_CONNECTION=postgres://sensor_db:sensor_db@sensor-db:5432/sensor_db?sslmode=disable
    depends_on:
      - sensor-db
      - redis

Findings

The docker-compose configuration above does not allow a successful client connection from my application (chirpstack-cim-integration) to the other containers hosting PostgreSQL and Redis. For debugging, I overrode the entrypoint to ping the other containers to ensure the network was correctly set up. I was able to ping every container, indicating that the network configuration is fine.

I also installed postgresql-client inside my "chirpstack-cim-integration" container and successfully connected to "sensor-db" using the sensor-db hostname and credentials.

The connection problems only occur when my Rust program tries to connect to the PostgreSQL or Redis containers. It cannot even handle direct container IPs as hosts, bypassing Docker DNS.

The only working setup is using the host network, as shown in the workaround section. Somehow, my Rust application is only able to handle external, non-Docker IPs.

Workaround

I am able to run my program when using the host networking mode. Working docker-compose (only changed lines):

chirpstack-cim-integration:
  ...
  environment:
    - REDIS_CONNECTION=redis://localhost:6379
    - PG_CONNECTION=postgres://sensor_db:sensor_db@localhost:5432/sensor_db?sslmode=disable
  network_mode: "host"

sensor-db:
  ports:
    - 5432:5432

redis:
  ports:
    - 6379:6379

Rust Connection

Nothing special here, I cannot imagine that something in the connection function would cause docker-network IPs to be unreachable.

pub fn pg_establish_connection(config: &str) -> BoxFuture<ConnectionResult<AsyncPgConnection>> {
    async {

        let (client, connection) = tokio_postgres::connect(config, NoTls)
            .await
            .map_err(PgConnectionError::TokioPostgresError)?;

        tokio::spawn(async move {
            if let Err(e) = connection.await {
                error!("Connection error: {}", e);
            }
        });

        let async_connection = AsyncPgConnection::try_from(client).await?;

        Ok(async_connection)
    }.boxed()
}

The connection string from the environment is also delivered properly to the function. I tried it with the machine NIC IP rather than "localhost", this also works.

TL;DR

The Rust program cannot connect to PostgreSQL over the Docker network, even though other tools (like postgresql-client) in the same container can. This forces me to use the host networking mode, which I want to avoid due to security concerns.

Any insights or suggestions would be greatly appreciated!

1
  • I'd create another container inside that docker compose file, connect to it like docker exec -it other-container-name bash then probe the postgres container with nmap, telnet, and psql. If the rust docker image is not too stripped down, you could do the same from that running container. Commented Jun 21, 2024 at 17:56

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.