使用docker-compose连接Go和PostgreSQL

5

我想要通过docker-compose来连接一个Go语言和PostgreSQL容器。

以下是我的docker-compose.yml文件:

version: '2'
services:
    postgres:
        image: postgres
        ports:
            - "5432"
        environment:
            - POSTGRES_PASSWORD=postgres
    server:
        build: ./server
        command: gin
        volumes:
            - ./server:/go/src/app
        ports:
            - "8080:3000"

起初我尝试在docker-compose.yml中使用links命令,但是这并没有在服务器容器中创建任何环境变量,这让我感到非常困惑。(它应该会创建 SOMETHINGSOMETHING_PORT_5432_TCP_ADDR 和 SOMETHINGSOMETHING_5432_TCP_PORT,不是吗?)
然后我在某个地方读到可以直接使用http://postgres作为主机,所以我尝试了一下。现在我的main.go看起来是这样的(注意:我正在使用Gorp作为“ORM”):
func main() {

    dbinfo := fmt.Sprintf("user=%s password=%s host=%s dbname=%s sslmode=disable",
        "postgres",
        os.Getenv("DB_ENV_POSTGRES_PASSWORD"),
        "http://postgres",
        DB_NAME,
    )

    db, err := sql.Open("postgres", dbinfo)

    checkErr(err, "sql.Open failed")


    // construct a gorp DbMap
    dbmap := &gorp.DbMap{Db: db, Dialect: gorp.PostgresDialect{}}

    // add a table, setting the table name to 'posts' and
    // specifying that the Id property is an auto incrementing PK
    dbmap.AddTableWithName(Todo{}, "todos").SetKeys(true, "Id")

    // create the table. in a production system you'd generally
    // use a migration tool, or create the tables via scripts
    err = dbmap.CreateTablesIfNotExists()
    checkErr(err, "Create tables failed")

    http.HandleFunc("/", handler)
    http.ListenAndServe(":3001", nil)
}

这是一个关于docker-compose up详细日志的记录(我在端口5432上遇到了连接被拒绝的问题)。
←[36mserver_1    |←[0m [gin] listening on port 3000
←[33mpostgres_1  |←[0m The files belonging to this database system will be owned by user "postgres".
←[33mpostgres_1  |←[0m This user must also own the server process.
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m The database cluster will be initialized with locale "en_US.utf8".
←[33mpostgres_1  |←[0m The default database encoding has accordingly been set to "UTF8".
←[33mpostgres_1  |←[0m The default text search configuration will be set to "english".
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m Data page checksums are disabled.
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m fixing permissions on existing directory /var/lib/postgresql/data ... ok
←[33mpostgres_1  |←[0m creating subdirectories ... ok
←[33mpostgres_1  |←[0m selecting default max_connections ... 100
←[33mpostgres_1  |←[0m selecting default shared_buffers ... 128MB
←[33mpostgres_1  |←[0m selecting dynamic shared memory implementation ... posix
←[33mpostgres_1  |←[0m creating configuration files ... ok
←[33mpostgres_1  |←[0m creating template1 database in /var/lib/postgresql/data/base/1 ... ok
←[33mpostgres_1  |←[0m initializing pg_authid ... ok
←[33mpostgres_1  |←[0m initializing dependencies ... ok
←[33mpostgres_1  |←[0m creating system views ... ok
←[33mpostgres_1  |←[0m loading system objects' descriptions ... ok
←[33mpostgres_1  |←[0m creating collations ... ok
←[33mpostgres_1  |←[0m creating conversions ... ok
←[33mpostgres_1  |←[0m creating dictionaries ... ok
←[33mpostgres_1  |←[0m setting privileges on built-in objects ... ok
←[33mpostgres_1  |←[0m creating information schema ... ok
←[33mpostgres_1  |←[0m loading PL/pgSQL server-side language ... ok
←[33mpostgres_1  |←[0m vacuuming database template1 ... ok
←[33mpostgres_1  |←[0m copying template1 to template0 ... ok
←[33mpostgres_1  |←[0m copying template1 to postgres ... ok
←[33mpostgres_1  |←[0m syncing data to disk ... ok
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m WARNING: enabling "trust" authentication for local connections
←[33mpostgres_1  |←[0m You can change this by editing pg_hba.conf or using the option -A, or
←[33mpostgres_1  |←[0m --auth-local and --auth-host, the next time you run initdb.
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m Success. You can now start the database server using:
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m     pg_ctl -D /var/lib/postgresql/data -l logfile start
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m waiting for server to start....LOG:  database system was shut down at 2016-08-19 18:31:55 UTC
←[33mpostgres_1  |←[0m LOG:  MultiXact member wraparound protections are now enabled
←[33mpostgres_1  |←[0m LOG:  database system is ready to accept connections
←[33mpostgres_1  |←[0m LOG:  autovacuum launcher started
←[33mpostgres_1  |←[0m  done
←[33mpostgres_1  |←[0m server started
←[33mpostgres_1  |←[0m ALTER ROLE
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m /docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m LOG:  received fast shutdown request
←[33mpostgres_1  |←[0m LOG:  aborting any active transactions
←[33mpostgres_1  |←[0m LOG:  autovacuum launcher shutting down
←[33mpostgres_1  |←[0m LOG:  shutting down
←[33mpostgres_1  |←[0m waiting for server to shut down....LOG:  database system is shut down
←[33mpostgres_1  |←[0m  done
←[33mpostgres_1  |←[0m server stopped
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m PostgreSQL init process complete; ready for start up.
←[33mpostgres_1  |←[0m
←[33mpostgres_1  |←[0m LOG:  database system was shut down at 2016-08-19 18:31:57 UTC
←[33mpostgres_1  |←[0m LOG:  MultiXact member wraparound protections are now enabled
←[33mpostgres_1  |←[0m LOG:  database system is ready to accept connections
←[33mpostgres_1  |←[0m LOG:  autovacuum launcher started
←[36mserver_1    |←[0m 2016/08/19 18:32:05 Create tables failed dial tcp [::1]:5432: getsockopt: connection refused
←[36mserver_1    |←[0m 2016/08/19 18:32:05 http: proxy error: dial tcp [::1]:3001: getsockopt: connection refused
←[36mserver_1    |←[0m 2016/08/19 18:32:05 Create tables failed dial tcp [::1]:5432: getsockopt: connection refused
←[36mserver_1    |←[0m 2016/08/19 18:32:05 http: proxy error: dial tcp [::1]:3001: getsockopt: connection refused

所以我的问题是,我该如何让它们彼此通信,我在这里做错了什么?

尝试使用 sql.Open("postgres", "postgres://postgres/yourdbname") - Plato
2个回答

6

这是一个关于Docker网络的问题。您可以在此处了解更多信息。

Docker DNS会完成所有繁重的工作,因此您可以通过compose文件中给它命名的名称来访问每个容器。

通常情况下,Postgres的URL如下:

postgresql://user:password@ip:port/database

所以对于您来说,这将是类似的内容。
db, err := sql.Open("postgres", "postgresql://user:password@postgres/mydatabase)

请注意,如果Postgres在标准端口(5432)上,则无需使用端口号。

1
谢谢,这很有帮助 :) - xtrinch
@Nirri,您是否介意将此答案接受为正确答案? - CESCO

1

事实证明,我实际上没有将容器连接起来,os.Getenv("DB_ENV_POSTGRES_PASSWORD") 产生了一个空字符串。在 docker-compose.yml 中向服务器容器添加了一个带有密码的环境变量,现在我可以连接到我的数据库了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接