I have a docker-compose file in which I locally deploy the database and the application on go
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 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)
}
}
in which the connection to the database is made. But the connection fails, and the wrong port is forwarded: instead of 26257, 26258 is forwarded. How to fix this?
Don't use
links; this feature has been deprecated for years now and is only maintained for backwards compatibility. Docker maintains DNS for containers so you can simply use the service name as a hostname when establishing connections.You cannot combine port forwarding with
network_mode: host.Your use of
depends_onis effectively a no-op; there's a good chance your application is trying to connect to the database before the database is ready to handle connections.In fact, your database cluster will not accept connections until you run
cockroach init, so you are definitely hitting this issue.Your compose file will fail to start
node_1with the following error:Your port forwarding for
node_1is incorrect; there is nothing in the container listening on port 8081. You would want something like:Lastly, you don't indicate where the
storagemodule in your sample code comes from, so I wasn't able to use it for testing things. I wrote this test program instead, which includes a loop to wait for the database to accept connections:If we fix all of the above problems and generally clean up the compose file, we end up with:
Note that this configuration intentionally does not publish the database ports on the host, since this isn't required in order for the application to access the database.
When we
docker compose upthis configuration, we'll see the following from the database services:And the following from the example application (which we expect):
We need to initialize the database:
After which we see the following from the database services:
And the sample application is able to connect and perform a query:
The web UI for these nodes will be exposed on host ports
8080and8081.Lastly, you will probably want to create volumes to persist the database data. See e.g. this documentation for where to mount the volumes.