redis
サービスからapp
サービスに接続する方法がわかりません。 DDockerバージョン18.03.1-ceを使用して、Mac用の9ee9f40ockerをビルドします。
私は同様の質問で見つけたさまざまな方法を接続してみました:
const client = redis.createClient({ Host: 'localhost', port: 6379});
const client = redis.createClient({ Host: 'redis', port: 6379});
const client = redis.createClient('redis://redis:6379');
const client = redis.createClient('redis', 6379); // and reversed args
私はいつも何らかの形で得ます:
エラー:localhost:6379へのRedis接続が失敗しました-ECONNREFUSED 127.0.0.1:6379に接続してください
エラー:redis:6379へのRedis接続が失敗しました-ECONNREFUSED 172.20.0.2:6379に接続してください
Dockerコンテナ
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0fd798d58561 app_app "pm2-runtime start e…" 2 seconds ago Up 7 seconds app
65d148e498f7 app_redis "docker-entrypoint.s…" About a minute ago Up 8 seconds 0.0.0.0:6379->6379/tcp redis
Redisは機能します:
$ docker exec -it redis /bin/bash
root@65d148e498f7:/data# redis-cli ping
PONG
Redis Dockerfile(かなりシンプル)
FROM redis:4.0.9
COPY redis.conf /usr/local/etc/redis/redis.conf
CMD ["redis-server", "/usr/local/etc/redis/redis.conf"]
app Dockerfile
FROM node:10.3.0-slim
RUN mkdir -p /app
COPY src/* /app/
CMD ["pm2-runtime", "start", "/app/ecosystem.config.js"]
docker-compose.yml
version: "3"
services:
redis:
build: ./redis/
container_name: redis
restart: unless-stopped
ports:
- "6379:6379"
expose:
- "6379"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- 'API_PORT=6379'
- 'NODE_ENV=production'
app:
depends_on:
- redis
build: ./app/
container_name: app
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /app/node_modules
environment:
- 'NODE_ENV=production'
すべてのインターフェースではなく127.0.0.1でリッスンするようにredisイメージが構成されているようです。これはデフォルトのredisイメージの問題ではないため、Dockerハブの公式イメージを使用するか、0.0.0.0でリッスンするように設定を修正してください。
これはnetshootで確認できます。
docker run --rm --net container:app_redis nicolaka/netshoot netstat -ltn
Redis confでは、redis.confの「bind」行をコメント化することで、すべてのインターフェースをリッスンします。
簡単な言葉で説明しましょう。 docker-compose up
を実行すると、redisとappが別々のコンテナーで実行されます。これで、アプリはredisコンテナーに接続/アクセスする必要があります(redisはマシンのlocalhostではなく、コンテナー内にあり、コンテナー内でデフォルトポート6379
で実行されることに注意してください)。デフォルトでは、Dockerはアプリコンテナーとredisコンテナーを同じネットワークに保持し、サービス名でコンテナーにアクセスできます(この場合はredisとapp)なので、アプリコンテナーからredisにアクセスするには、すべてデフォルトのポート6379
を使用する必要があり、Hostがサービス名になります(この場合は「redis」)。
コンテナーで実行されているノードアプリケーションの場合、Redis(コンテナーでも実行されていました)にアクセスします。
const redis = require("redis");
const client = redis.createClient(6379, "service-name-for-redis-container");
localhost
コンテナの観点から見たapp
は、app
コンテナから離れることはできません。したがって、最善の策は、redis
またはホストのIPアドレスを使用することです。
redis
コンテナからapp
にアクセスする場合は、それらをリンクするか、同じネットワークに配置する必要があります。同じネットワーク名を使用して、network
プロパティを両方のサービスに追加してください。 Dockerは、サービス名の有効なDNSルックアップを提供します。
https://docs.docker.com/compose/compose-file/#networks の公式ドキュメントを参照してください(service:
プロパティ)および https://docs.docker.com/compose/compose-file/#network-configuration-reference (トップレベルのnetworks
プロパティ用)。