等待 Docker 个容器准备就绪

Waiting for a Docker container to be ready

我有以下 docker-compose.yml:

version: '2'
services:
  server:
    build: .
    command: ["./setup/wait-for-postgres.sh", "tide_server::5432", "cd /app", "npm install", "npm run start"]
    ports:
      - 3030:3030
    links:
      - database
    depends_on:
      - database
  database:
    image: postgres
    environment:
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=postgres"
      - "POSTGRES_DB=tide_server"
    ports:
      - 5432:5432

我尝试按照此 tutorial 并使用以下 shell 脚本来确定 postgres 何时准备就绪。

#!/bin/bash
# wait-for-postgres.sh

set -e

host=""
shift
cmd="$@"

until psql -h "$host" -U "postgres" -c '\l'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"
exec $cmd

我的节点 Dockerfile 很小,但我添加了它以供参考:

FROM node:latest

ADD . /app

WORKDIR /app

EXPOSE 3030

现在,当我尝试 运行 docker-compose up 时,我得到以下信息(在 postgres 容器准备就绪后:

server_1    | Postgres is unavailable - sleeping
server_1    | ./setup/wait-for-postgres.sh: line 10: psql: command not found
server_1    | Postgres is unavailable - sleeping
server_1    | ./setup/wait-for-postgres.sh: line 10: psql: command not found
server_1    | Postgres is unavailable - sleeping
server_1    | ./setup/wait-for-postgres.sh: line 10: psql: command not found
server_1    | Postgres is unavailable - sleeping
server_1    | ./setup/wait-for-postgres.sh: line 10: psql: command not found

现在我不确定这是否是链接问题,或者我的脚本有问题,但我已经尝试了我能想到的所有变体,但没有成功/

当您在 docker-compose.yml 中声明 command 时,命令本身在其声明开始的容器中执行。明白我的意思了吗?

您的 ./setup/wait-for-postgres.sh 正在容器中执行,该容器没有安装 postgres。而且你无法更改它。

但是不,实际上你可以。 运行 postgres 容器中的脚本。但是,如果您在 database 部分定义 command,它将覆盖 postgres:latest 中定义的默认 CMD,即 CMD ["postgres"].

这意味着,您必须稍微重写您的脚本:

#!/bin/bash
# wait-for-postgres.sh

set -e

host=""
shift
cmd="$@"

postgres

until psql -h "$host" -U "postgres" -c '\l'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"
exec $cmd

这将成功等待 Postgres 启动。 (特别是第 6 行)

services:
  practice_docker: 
    image: dockerhubusername/practice_docker
    ports: 
      - 80:3000
    command: bash -c 'while !</dev/tcp/db/5432; do sleep 1; done; npm start'
    depends_on:
      - db
    environment:
      - DATABASE_URL=postgres://postgres:password@db:5432/practicedocker
      - PORT=3000   
  db:
    image: postgres
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=practicedocker