Home  >  Article  >  Backend Development  >  How to connect to CockroachDB using docker-compose?

How to connect to CockroachDB using docker-compose?

王林
王林forward
2024-02-15 12:03:09975browse

如何使用 docker-compose 连接到 CockroachDB?

php editor Strawberry will introduce how to use docker-compose to connect to CockroachDB. Docker-compose is a tool for defining and running multiple Docker containers, and CockroachDB is a distributed relational database management system. By using docker-compose, we can easily create and manage CockroachDB containers and connect them with other containers. In this article, we'll detail how to configure your docker-compose file to connect to CockroachDB and provide some practical tips and considerations. Whether you are a beginner or an experienced developer, this article will provide you with useful guidance to help you quickly get started using docker-compose to connect to CockroachDB.

Question content

I have a docker-compose file where I deploy the database and go application locally

services:
      node_1:
          container_name: node_1
          image: cockroachdb/cockroach:latest
          command: start --insecure
          ports:
              - "26258:26258"
              - "8081:8081"
          networks:
            - network_cockroachdb 
      node_2:
          container_name: node_2
          image: cockroachdb/cockroach:latest
          hostname: node_2
          ports:
            - "26257:26257"
            - "8080:8080"
          command: start --insecure --join=node_1
          networks:
            - network_cockroachdb 
          network_mode: 'host'
      app:
          build: .
          ports:
            - "12121:12121"
          environment:
            app_port: '12121'
            db_host: "node_2"
            db_port: 26257
            db_user: root
            db_password: 123
            db_database: mydb
          depends_on:
            - node_2
          links:
            - node_2
          networks:
            - network_cockroachdb 
    networks:
        network_cockroachdb:
            driver: bridge

Go to file:

func main() {  
    port, _ := strconv.Atoi(os.Getenv("db_port"))

    dbConfig := storage.ConnectionConfig{
        Host:     os.Getenv("db_host"),
        Port:     port,
        User:     os.Getenv("db_user"),
        Password: os.Getenv("db_password"),
        DBName:   os.Getenv("db_database"),
        SSLMode:  "verify-full",
    }

    log.Println("url: ", dbConfig.String())

    db, err := storage.NewCockroachDB(context.Background(), dbConfig)

    if err != nil {
        log.Fatal(err)
    }
}

The connection to the database is established. But the connection failed, and the wrong port was forwarded: instead of 26257, it was 26258. how to solve this problem?

Solution

  1. Do not use links; this feature has been deprecated for many years and is retained only for backward compatibility. Docker maintains DNS for containers, so you only need to use the service name as the hostname when establishing a connection.

  2. You cannot use port forwarding with network_mode: host.

  3. Your use of depends_on is effectively a no-op; your application is likely trying to connect to the database before the database is ready to handle the connection.

    In fact, your database cluster will not accept connections until you run cockroach init, so you definitely will encounter this problem.

  4. Your compose file will fail to start node_1 with the following error:

    * ERROR: ERROR: no --join flags provided to 'cockroach start'
    * HINT: Consider using 'cockroach init' or 'cockroach start-single-node' instead
    *
    ERROR: no --join flags provided to 'cockroach start'
    HINT: Consider using 'cockroach init' or 'cockroach start-single-node' instead
    Failed running "start"
  5. Your node_1 port forwarding is incorrect; nothing in the container is listening on port 8081. You may want something like:

    ports:
      - 8081:8080

Finally, you didn't indicate where the storage module in your example code comes from, so I can't use it for testing. I wrote this test program which includes a loop waiting for the database to accept the connection:

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"

    pgx "github.com/jackc/pgx/v4"
)

func main() {
    connectionString := os.Getenv("db_uri")

    if connectionString == "" {
        connectionString = fmt.Sprintf("postgresql://%s@%s:%s/%s?sslmode=disable",
            os.Getenv("db_user"),
            os.Getenv("db_host"),
            os.Getenv("db_port"),
            os.Getenv("db_database"),
        )
    }

    var conn *pgx.Conn
    var err error

    for {
        conn, err = pgx.Connect(context.Background(), connectionString)
        if err == nil {
            break
        }

        log.Printf("connection failed (%v); will retry...", err)
        time.Sleep(1 * time.Second)
    }
    log.Printf("connected to database")

    var value int
    if err := conn.QueryRow(context.Background(), "select 1").Scan(&value); err != nil {
        panic(err)
    }

    fmt.Printf("All done.\n")
}

If we solve all the above problems and clean the compose file, we will end up with:

services:
  node_1:
    image: cockroachdb/cockroach:latest
    ports:
      - "8080:8080"
    command:
      - start
      - --insecure
      - --join=node_1,node_2

  node_2:
    image: cockroachdb/cockroach:latest
    ports:
      - "8081:8080"
    command:
      - start
      - --insecure
      - --join=node_1,node_2

  app:
    build: .
    environment:
      db_host: "node_2"
      db_port: 26257
      db_user: root
      db_password: 123
      db_database: mydb

Note that this configuration intentionally does not publish the database port on the host, as this is not required for applications to access the database.

When we docker write this configuration, we will see the following from the database service:

* INFO: initial startup completed.
* Node will now attempt to join a running cluster, or wait for `cockroach init`.
* Client connections will be accepted after this completes successfully.
* Check the log file(s) for progress.

and the following in the sample application (we expect):

2023/09/01 12:53:20 connection failed (failed to connect to `host=node_2 user=root database=mydb`: dial error (dial tcp 10.89.1.46:26257: connect: connection refused)); will retry...

We need to initialize the database:

docker compose exec node_1 ./cockroach init --insecure --host=node_1

Afterwards we see the following from the database service:

CockroachDB node starting at 2023-09-01 12:54:38.494304014 +0000 UTC m=+77.639236046 (took 77.4s)
[...]

The sample application is able to connect and execute queries:

2023/09/01 12:54:38 connected to database
All done.

The web UI for these nodes will be exposed on host ports 8080 and 8081.

Finally, you may want to create volumes to hold your database data. See e.g. this documentmounting volumes.

The above is the detailed content of How to connect to CockroachDB using docker-compose?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete