![](/img/trans.png)
[英]Docker-Compose : Multiple services from local images with the same Dockerfile
[英]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.