Абсолютно лучший способ управлять сложными командами запуска, подобными этим, - это (а) записать их в виде сценариев оболочки и (б) запекать их в ваше Docker изображение.
Например, я могу переосмыслить процедура запуска, которую вы написали в виде псевдокода, например:
1. cd into the wait-for-it directory and run the wait-for-it script
2. Do the thing the container was originally going to do
Я могу перевести это в скрипт оболочки:
#!/bin/sh
(cd /app/wait-for-it && ./wait-for-it.sh "$DB_HOST_PORT")
exec "$@"
Затем я могу использовать этот скрипт как ENTRYPOINT
в моем изображении , Он запускает команду cd
в подоболочке, поэтому он возвращается в исходный каталог на следующей строке; строка exec "$@"
запускает то, что было передано как команда. Конец вашего Dockerfile
будет выглядеть так:
COPY entrypoint.sh /app
RUN chmod +x entrypoint.sh
WORKDIR /app/api
ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["yarn", "start"]
Тогда мне вообще не нужно вручную переопределять эти настройки в docker-compose.yml
; единственное, что мне нужно сделать, это указать местоположение базы данных в качестве переменной среды.
version: '3'
services:
myapp:
build: .
environment:
- DB_HOST_PORT=postgres:5432
ports:
- '3000:3000'
postgres:
image: postgres:12
Если бы я хотел выполнить какую-то другую команду:
docker-compose run myapp yarn migrate
Это все равно бы подождать база данных будет доступна, но затем выполните альтернативную команду.