web-dev-qa-db-ja.com

別のコンテナからpostgresqlコンテナに接続する(Docker)

私はこれをフォローしようとしています tutorial そしてpostgresqlコンテナをセットアップします。

私は次のスクリプトを持っています:

#!/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

そして次のdocker-compose.yml

version: '2'
services:
  server:
    build: .
    ports:
      - 3030:3030
    depends_on:
      - database
    command: ["./setup/wait-for-postgres.sh", "localhost:5432", "--", "node", "src"]
  database:
    image: postgres
    environment:
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=postgres"
      - "POSTGRES_DB=tide_server"
    ports:
      - 5432:5432

問題は、docker-compose upを実行すると、次のエラーが発生することです。

server_1    | Postgres is unavailable - sleeping
server_1    | psql: could not translate Host name "192.168.64.2:5432" to address: Name or servi
ce not known
server_1    | Postgres is unavailable - sleeping
server_1    | psql: could not translate Host name "192.168.64.2:5432" to address: Name or servi
ce not known
server_1    | Postgres is unavailable - sleeping
server_1    | psql: could not translate Host name "192.168.64.2:5432" to address: Name or servi
ce not known

ホストをdatabaselocalhost0.0.0.0に設定しようとしましたが、コンテナのIPでさえ機能しません。それがどうあるべきか、どのようにデバッグするのかわかりません。 、docker-composeがコンテナをどのようにリンクするかは100%わかりません。

8
Otis Wright

reduce_onは使用しないでください。 「リンク」で試してみてください

    version: '2'
    services:
      server:
        build: .
        ports:
          - 3030:3030
        links:
          - database
        #environment could be usefull too
        environment:
            DATABASE_Host: database
        command: ["./setup/wait-for-postgres.sh", "localhost:5432", "--", "node", "src"]
      database:
        image: postgres
        environment:
          - "POSTGRES_USER=postgres"
          - "POSTGRES_PASSWORD=postgres"
          - "POSTGRES_DB=tide_server"
        ports:
          - 5432:5432

詳細については https://docs.docker.com/compose/compose-file/#links

2
Gabbax0r

ここでの問題はホスト自体です。

psql -h "$ Host" -U "" -c '\ l'

間違ったホスト名「localhost:5432」/「192.168.64.2:5432」を渡しています

私がしたことは、localhost:5432:DB:USER:PASSWORDを持つ〜/ .pgpassをセットアップすることです

「localhost:5432」を渡す代わりに、ポートを省略します。 「localhost」を使用するだけです

これは私のために働きます...

1
Rodel

答えるのに古いスレッドかもしれませんが、私は次のdocker-composeファイルでdepends_onを使用しています

version: '3.4'

volumes:
  postgres_data:
      driver: local

services:
  postgres:
      image: postgres
      volumes:
        - ./postgres_data:/var/lib/postgresql:rw
        - ./deployments:/opt/jboss/wildfly/standalone/deployments:rw
      environment:
        POSTGRES_DB: keycloak
        POSTGRES_USER: keycloak
        POSTGRES_PASSWORD: password
      ports:
        - 5432:5432
   keycloak:
      image: jboss/keycloak
      environment:
        POSTGRES_ADDR: postgres
        POSTGRES_DATABASE: keycloak
        POSTGRES_USER: keycloak
        POSTGRES_PASSWORD: password
        KEYCLOAK_USER: admin
        KEYCLOAK_PASSWORD: Pa55w0rd
      ports:
        - 8080:8080
        - 9990:9990
      depends_on:
        - postgres
1
Rodel

チュートリアルはいくつかのことをスキップし、wait-for-it.shスクリプトについて言及しているという点で混乱していますが、hostname:portを1つの引数として渡した場合は機能しない非常に単純化されたバージョンを示しています。

これを機能させるのに問題がありました。将来の私と他の人の両方のために、以下の手順を追加します。私はこれをMacOSで行い、dockerとdocker-composeの両方とnodejsをインストールしました。

私はあなたのノードアプリを手元に持っていないので、ここで説明されているものを使用しました https://nodejs.org/de/docs/guides/nodejs-docker-webapp/

私は次のディレクトリ構造を持っています:

/src/package.json
/src/server.js
/.pgpass
/docker-compose.yml
/Dockerfile
/wait-for-postgres.sh

これらのファイルの内容は以下のとおりです。

ステップ

  1. ./srcディレクトリから$ npm installを実行します(package-lock.jsonを作成します)
  2. $ chmod 600 .pgpassでpgpass権限を修正
  3. スクリプトを実行可能にする$ chmod +x wait-for-postgres.sh
  4. ルートディレクトリから$ docker-compose up

Postgresイメージをプルし、ノードアプリコンテナを構築します。それが完了すると、postgresを待機し、postgresが起動すると、準備ができていることがわかります。

ファイル

srcファイルは上記のノードjs dockerizeリンクとまったく同じです

/src/package.json

{
    "name": "docker_web_app",
    "version": "1.0.0",
    "description": "Node.js on Docker",
    "author": "First Last <[email protected]>",
    "main": "server.js",
    "scripts": {
      "start": "node server.js"
    },
    "dependencies": {
      "express": "^4.16.1"
    }
  }

/src/server.js

'use strict';

const express = require('express');

// Constants
const PORT = 8080;
const Host = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
  res.send('Hello world\n');
});

app.listen(PORT, Host);
console.log(`Running on http://${Host}:${PORT}`);

.pgpass

これはusername:password postgres:postgresを使用し、純粋に開発デモを目的としています。実際には、シークレット管理の他の方法を使用し、pgpassファイルをバージョン管理にコミットすることは決してありません

#Host:port:db:user:pass
db:5432:*:postgres:postgres

docker-compose.yml

  • wait-for-postgres.shスクリプトを管理対象ボリュームとして追加しました。元の質問では、奇妙なアプリsrcにバンドルされていました。
  • また、ルートユーザーのホームディレクトリに.pgpassファイルをマウントしました。このファイルは、psqlが自動パスワード補完を検索します。これを提供する方法がない場合は、エラーが発生します。

    psql:fe_sendauth:パスワードが指定されていません

  • serverコンテナのコマンドがdatabaseを参照していることに注意してください。これはpostgresコンテナの有効なdocker-compose内部DNS名です。

version: '2'
services:

  server:
    build: .
    ports:
      - 3030:3030
    depends_on:
      - database
    volumes:
      - ./wait-for-postgres.sh:/usr/app/setup/wait-for-postgres.sh
      - ./.pgpass:/Users/root/.pgpass
    command: ["/usr/app/setup/wait-for-postgres.sh", "database", "--", "node", "src"]

  database:
    image: postgres
    environment:
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=postgres"
      - "POSTGRES_DB=tide_server"
    ports:
      - 5432:5432

Dockerfile

  • これをnodejsチュートリアルから変更し、Debianの「バスター」バージョンに固定し、そのスクリプトに必要なpsqlもインストールしました。
FROM node:10-buster

RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8

RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main" > /etc/apt/sources.list.d/pgdg.list && \
    wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -


RUN apt-get -y update - && \
    apt-get -y install libpq-dev && \
    apt-get -y install postgresql-client-11

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ]

wait-for-postgres.sh

  • 「shellcheck」リンターを実行したところ、いくつかの点で不満があったため、スクリプトをわずかに変更しました。このスクリプトはdockerチュートリアルページからのものだと思います。
#!/bin/bash
# wait-for-postgres.sh

set -e

Host="$1"
shift
cmd="$*"

export PGPASSFILE=./pgpass

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"
1
Davos