簡體   English   中英

如何從 Dockerfile 或 docker-compose 運行 knex 遷移

[英]How to run knex migrations from Dockerfile or docker-compose

我有 Dockerfile 與 API 和 MySQL 數據庫一起使用,它應該進行遷移:

FROM node

WORKDIR /api

COPY . .

RUN npm install

EXPOSE 3001

VOLUME [ "/api/node_modules" ]

CMD [ "npm", "start" ]

此外,還有一個 docker-compose 文件,其中我將數據庫作為服務:

  db:
    image: mysql
    container_name: database
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_PASSWORD: password
      MYSQL_DATABASE: testdb

問題是,我不知道如何運行遷移。 我應該從 docker-compose 文件還是 Dockerfile 執行它?

我試圖在 Dockerfile 中做這樣的事情,但它似乎不起作用:

...
CMD [ "knex", "migrate:latest" ]
...

或者:

...
RUN knex migrate:latest
...

我解決了這個問題,可能是以愚蠢的方式,但它有效。 所以,我所做的只是在我的 API 容器上添加了這個:

restart: on-failure
command: npm run knex

現在,它只是重新啟動容器,直到連接到數據庫並執行所有遷移。

如果您想水平擴展應用程序,鏈接命令或使用和入口點不是最佳選擇。

然后所有副本將同時進行遷移。 它可能不會引起真正的問題,但它仍然不是完美的 IMO。

相反,這應該單獨處理,在實際需要時作為一次性命令。 例如,在 Kubernetes 中,如果數據庫架構實際上已更改,那么與您的應用程序版本一起運行專用遷移作業會很好。

使用 compose,沒有作業,但您可以實現類似的行為。

services:
  migration:
    image: busybox
    command: sh -c 'echo "running migration..."; sleep 20; echo "migration completed"'
  app:
    image: busybox
    command: echo "app started"
    depends_on:
      migration:
        condition: service_completed_successfully
    deploy:
      replicas: 3

現在,您只需執行一次遷移,所有 3 個應用程序副本都會等待遷移完成,然后再啟動。

$ docker compose up
Attaching to app_1, app_2, app_3, migration_1
migration_1  | running migration...
migration_1  | migration completed
migration_1 exited with code 0
app_2        | app started
app_3        | app started
app_1        | app started

在您的情況下,您將使用從 Dockerfile 構建的相同映像用於遷移和應用程序服務。 在遷移服務中使用knex migrate ,在應用服務中使用npm run start

如果您需要遷移甚至等待數據庫,depends_on 可能還不夠,除非您構建反映數據庫是否實際准備好接受連接的運行狀況檢查。 如果您有健康檢查,那么您可以使用條件service_healthy

例如,你可以像這樣做圓頂。

services:
  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: "root"
      MYSQL_DATABASE: "wordpress"
      MYSQL_USER: "wordpressuser"
      MYSQL_PASSWORD: "wordpresspassword"
    healthcheck:
      test: mysqladmin -u root --password=$$MYSQL_ROOT_PASSWORD ping
      interval: 30s
      timeout: 10s
      retries: 10

  migration:
    image: busybox
    command: sh -c 'echo "running migration..."; sleep 20; echo "migration completed"'
    depends_on:
      db:
        condition: service_healthy

  app:
    image: busybox
    command: echo "app started"
    depends_on:
      migration:
        condition: service_completed_successfully
    deploy:
      replicas: 3

您可以通過執行容器檢查來檢查日志。

$ docker inspect sample_db_1 --format \
  '{{range .State.Health.Log}}{{.End}} | Exit Code: {{.ExitCode}} | {{.Output}}{{end}}'
2022-01-30 12:53:43.749365 +0000 UTC | Exit Code: 0 | mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqld is alive

如果您不想使用健康檢查,也可以使用第三方解決方案,例如https://github.com/Eficode/wait-for

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM