如何在docker-compose中运行golang-migrate?

10
在golang-migrate的文档中,指出您可以运行此命令以在一个文件夹中运行所有迁移。
docker run -v {{ migration dir }}:/migrations --network host migrate/migrate
    -path=/migrations/ -database postgres://localhost:5432/database up 2

如何根据新的docker-compose语法来做到这一点,新的语法不鼓励使用--network参数?

更重要的是:如何连接到另一个容器中运行的数据库,而不是在本地主机中运行的数据库?

3个回答

19
将以下内容添加到您的docker-compose.yml文件中即可完成设置:
    db:
        image: postgres
        networks:
            new:
                aliases:
                    - database
        environment:
            POSTGRES_DB: mydbname
            POSTGRES_USER: mydbuser
            POSTGRES_PASSWORD: mydbpwd
        ports:
            - "5432"
    migrate:
        image: migrate/migrate
        networks:
            - new
        volumes:
            - .:/migrations
        command: ["-path", "/migrations", "-database",  "postgres://mydbuser:mydbpwd@database:5432/mydbname?sslmode=disable", "up", "3"]
        links: 
            - db
networks:
      new:

不要使用 docker run--network host 选项,而是设置一个名为 new 的网络。在该网络中的所有服务都可以通过一个定义好的别名相互访问(在上面的示例中,您可以通过 database 别名访问 db 服务)。然后,您可以像使用 localhost 一样使用该别名来替代 IP 地址。这就解释了该连接字符串:

"postgres://mydbuser:mydbpwd@database:5432/mydbname?sslmode=disable"

你好,有没有一种方法可以添加一个脚本来等待Postgres数据库就绪?因为如果按照原样运行该docker-compose文件,第一次运行时会收到连接被拒绝的错误。migrate_1 | error: dial tcp 172.22.0.2:5432: connect: connection refused - tul1
@tul1,这里有。请查看:https://docs.docker.com/compose/startup-order/ - Federico
它不起作用是因为来自dockerhub的migrate/migrate docker运行“migrate”命令。在此之前注入命令是不可能的吗? - tul1
1
我找到了自己问题的答案并已经发布在下面。 :) - tul1

6

@Federico提供的答案一开始对我有用,但后来我发现在新环境中第一次运行docker-compose时出现了connect: connection refused,但第二次没有。这意味着迁移容器在数据库准备好处理操作之前就已经运行了。由于 docker-hub 中的 migrate/migrate 在每次运行时都会运行“migration”命令,因此无法添加 wait_for_it.sh 脚本以等待数据库准备就绪。因此我们必须添加 depends_onhealthcheck 标签来管理执行顺序。 这是我的 Docker 文件:

version: '3.3'
services:
  db:
    image: postgres
    networks:
      new:
        aliases:
          - database
    environment:
      POSTGRES_DB: mydbname
      POSTGRES_USER: mydbuser
      POSTGRES_PASSWORD: mydbpwd
    ports:
      - "5432"
    healthcheck:
      test: pg_isready -U mydbuser -d mydbname
      interval: 10s
      timeout: 3s
      retries: 5

  migrate:
    image: migrate/migrate
    networks:
      - new
    volumes:
      - .:/migrations
    command: ["-path", "/migrations", "-database",  "postgres://mydbuser:mydbpwd@database:5432/mydbname?sslmode=disable", "up", "3"]
    links: 
      - db
    depends_on:
      - db
networks:
      new:

5
从Compose文件格式版本2开始,您不需要设置网络。
docker网络文档所述,默认情况下,Compose为您的应用程序设置单个网络。每个服务的容器都加入默认网络,并可以被该网络上的其他容器访问,并且它们可以通过与容器名称相同的主机名发现彼此。
因此,在您的情况下,可以这样做:
version: '3.8'
services:
   #note this databaseservice name is what we will use instead
   #of localhost when using migrate as compose assigns
   #the service name as host
   #for example if we had another container in the same compose
   #that wnated to access this service port 2000 we would have written
   # databaseservicename:2000
  databaseservicename:
    image: postgres:13.3-alpine

    restart: always

    ports:
      - "5432"

    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_USER: username
      POSTGRES_DB: database

    volumes:
      - pgdata:/var/lib/postgresql/data

    #if we had another container that wanted to access migrate container at let say
    #port 1000
    #and it's in the same compose file  we would have written migrate:1000
  migrate:
    image: migrate/migrate

    depends_on:
      - databaseservicename

    volumes:
      - path/to/you/migration/folder/in/local/computer:/database
    # here instead of localhost as the host we use databaseservicename as that is the name we gave to the postgres service
    command:
      [ "-path", "/database", "-database",  "postgres://databaseusername:databasepassword@databaseservicename:5432/database?sslmode=disable", "up" ]
volumes:
  pgdata:


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