如何使用 go with docker 等待 postgres 数据库?
How to wait postgres db using go with docker?
我通过 docker-compose 使用 postgres 部署了一个 go with gorm 应用程序。
我通过另一个容器服务进行了数据库创建和数据迁移。这里只列出了应用和数据库容器问题。
docker-compose.yml
app:
build: ./app
command: ["/bin/wait-for-it.sh", "db:5432", "--", "/bin/main"]
volumes:
- ./app/:/app/
ports:
- 8080:8080
environment:
- DB_USER=postgres
- DB_NAME=mydb
- DB_PASS=password
depends_on:
- db
links:
- db
db:
image: postgres:13-alpine
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
Docker 文件
FROM golang:1.16.3-alpine3.13 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main
FROM alpine:3.13
RUN apk update && apk --no-cache add bash
COPY --from=builder /app /bin/.
RUN ["chmod", "+x", "/bin/wait-for-it.sh"]
db/db.go
package db
import (
"fmt"
"os"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
var (
db *gorm.DB
)
func Init() {
conn := fmt.Sprintf("host=db port=5432 user=%s password=%s dbname=%s sslmode=disable", os.Getenv("DB_USER"), os.Getenv("DB_PASS"), os.Getenv("DB_NAME"))
_, err := gorm.Open(postgres.Open(conn), &gorm.Config{})
if err != nil {
panic(err)
}
}
func GetDB() *gorm.DB {
return db
}
models/post.go
package models
type Post struct {
ID int `json:"id" gorm:"primary_key"`
Title string `json:"title"`
Body string `json:"body"`
}
main.go
1 │ package main
2 │
3 │ import (
4 │ "app/db"
5 │ "app/models"
6 │ "fmt"
7 │ )
8 │
9 │ func main() {
10 │ db.Init()
11 │
12 │ db := db.GetDB()
13 │
14 │ var posts []models.Post
15 │ db.Find(&posts)
16 │ fmt.Println(posts)
17 │ }
当开始构建docker-compose 时,它首先尝试连接数据库,但似乎数据库还无法访问。即使添加 wait-for-it 也不起作用。
app_1 | wait-for-it.sh: waiting 15 seconds for db:5432
db_1 |
db_1 | PostgreSQL Database directory appears to contain a database; Skipping initialization
db_1 |
app_1 | wait-for-it.sh: db:5432 is available after 0 seconds
db_1 | 2021-06-02 03:53:03.731 UTC [1] LOG: starting PostgreSQL 13.2 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.2.1_pre1) 10.2.1 20201203, 64-bit
db_1 | 2021-06-02 03:53:03.731 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
app_1 | panic: runtime error: invalid memory address or nil pointer dereference
app_1 | [signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x59c446]
app_1 |
app_1 | goroutine 1 [running]:
app_1 | gorm.io/gorm.(*DB).getInstance(0x0, 0xc000026038)
app_1 | /go/pkg/mod/gorm.io/gorm@v1.21.10/gorm.go:355 +0x26
app_1 | gorm.io/gorm.(*DB).Find(0x0, 0x868220, 0xc00000c018, 0x0, 0x0, 0x0, 0xc000094058)
app_1 | /go/pkg/mod/gorm.io/gorm@v1.21.10/finisher_api.go:159 +0x2f
app_1 | main.main()
app_1 | /app/main.go:15 +0x7f
db_1 | 2021-06-02 03:53:03.731 UTC [1] LOG: listening on IPv6 address "::", port 5432
db_1 | 2021-06-02 03:53:03.734 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1 | 2021-06-02 03:53:03.741 UTC [22] LOG: database system was shut down at 2021-06-02 03:52:34 UTC
db_1 | 2021-06-02 03:53:03.747 UTC [1] LOG: database system is ready to accept connections
myapp_app_1 exited with code 2
如何正确设置?
/app/main.go:15
有什么不对的吗?它应该可以正常工作并获取数据。
您需要在命令中添加等待时间:
command: ["/bin/wait-for-it.sh", "db:5432", "-t", "600000000", "--", "/bin/main"]
这里是最长等待时间,应用程序 /bin/main
将在数据库启动和 运行ning 后立即执行。
当你 运行 没有 -t
时默认为 15 秒
更多信息Here
我通过 docker-compose 使用 postgres 部署了一个 go with gorm 应用程序。
我通过另一个容器服务进行了数据库创建和数据迁移。这里只列出了应用和数据库容器问题。
docker-compose.yml
app:
build: ./app
command: ["/bin/wait-for-it.sh", "db:5432", "--", "/bin/main"]
volumes:
- ./app/:/app/
ports:
- 8080:8080
environment:
- DB_USER=postgres
- DB_NAME=mydb
- DB_PASS=password
depends_on:
- db
links:
- db
db:
image: postgres:13-alpine
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
Docker 文件
FROM golang:1.16.3-alpine3.13 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main
FROM alpine:3.13
RUN apk update && apk --no-cache add bash
COPY --from=builder /app /bin/.
RUN ["chmod", "+x", "/bin/wait-for-it.sh"]
db/db.go
package db
import (
"fmt"
"os"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
var (
db *gorm.DB
)
func Init() {
conn := fmt.Sprintf("host=db port=5432 user=%s password=%s dbname=%s sslmode=disable", os.Getenv("DB_USER"), os.Getenv("DB_PASS"), os.Getenv("DB_NAME"))
_, err := gorm.Open(postgres.Open(conn), &gorm.Config{})
if err != nil {
panic(err)
}
}
func GetDB() *gorm.DB {
return db
}
models/post.go
package models
type Post struct {
ID int `json:"id" gorm:"primary_key"`
Title string `json:"title"`
Body string `json:"body"`
}
main.go
1 │ package main
2 │
3 │ import (
4 │ "app/db"
5 │ "app/models"
6 │ "fmt"
7 │ )
8 │
9 │ func main() {
10 │ db.Init()
11 │
12 │ db := db.GetDB()
13 │
14 │ var posts []models.Post
15 │ db.Find(&posts)
16 │ fmt.Println(posts)
17 │ }
当开始构建docker-compose 时,它首先尝试连接数据库,但似乎数据库还无法访问。即使添加 wait-for-it 也不起作用。
app_1 | wait-for-it.sh: waiting 15 seconds for db:5432
db_1 |
db_1 | PostgreSQL Database directory appears to contain a database; Skipping initialization
db_1 |
app_1 | wait-for-it.sh: db:5432 is available after 0 seconds
db_1 | 2021-06-02 03:53:03.731 UTC [1] LOG: starting PostgreSQL 13.2 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.2.1_pre1) 10.2.1 20201203, 64-bit
db_1 | 2021-06-02 03:53:03.731 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
app_1 | panic: runtime error: invalid memory address or nil pointer dereference
app_1 | [signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x59c446]
app_1 |
app_1 | goroutine 1 [running]:
app_1 | gorm.io/gorm.(*DB).getInstance(0x0, 0xc000026038)
app_1 | /go/pkg/mod/gorm.io/gorm@v1.21.10/gorm.go:355 +0x26
app_1 | gorm.io/gorm.(*DB).Find(0x0, 0x868220, 0xc00000c018, 0x0, 0x0, 0x0, 0xc000094058)
app_1 | /go/pkg/mod/gorm.io/gorm@v1.21.10/finisher_api.go:159 +0x2f
app_1 | main.main()
app_1 | /app/main.go:15 +0x7f
db_1 | 2021-06-02 03:53:03.731 UTC [1] LOG: listening on IPv6 address "::", port 5432
db_1 | 2021-06-02 03:53:03.734 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1 | 2021-06-02 03:53:03.741 UTC [22] LOG: database system was shut down at 2021-06-02 03:52:34 UTC
db_1 | 2021-06-02 03:53:03.747 UTC [1] LOG: database system is ready to accept connections
myapp_app_1 exited with code 2
如何正确设置?
/app/main.go:15
有什么不对的吗?它应该可以正常工作并获取数据。
您需要在命令中添加等待时间:
command: ["/bin/wait-for-it.sh", "db:5432", "-t", "600000000", "--", "/bin/main"]
这里是最长等待时间,应用程序 /bin/main
将在数据库启动和 运行ning 后立即执行。
当你 运行 没有 -t
时默认为 15 秒
更多信息Here