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.
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?
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.
You cannot use port forwarding with network_mode: host
.
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.
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"
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!