等待Docker容器准备好

时间:2017-05-16 10:01:28

标签: postgresql docker docker-compose dockerfile linker-errors

我有以下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="$1"
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

现在我不确定这是否是一个链接问题,或者我的脚本出了什么问题但是我已经尝试了我能想到的每一个变化并且没有运气得到这个/

2 个答案:

答案 0 :(得分:3)

这将成功等待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

答案 1 :(得分:2)

当你在command中声明docker-compose.yml时,命令本身会在声明开始的容器中执行。赶上我的漂移?

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

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

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

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

set -e

host="$1"
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