簡體   English   中英

Docker - Redis 連接 ECONNREFUSED 127.0.0.1:6379

[英]Docker - Redis connect ECONNREFUSED 127.0.0.1:6379

我知道這是一個常見的錯誤,但我確實花了一整天的時間試圖克服這個錯誤,嘗試了我在網上能找到的一切。 但我找不到任何適合我的東西。

我對 Docker 非常陌生,並將它用於我的 NodeJS + Express + Postgresql + Redis 應用程序。

這是我的 docker-compose 文件:

version: "3.8"
services:
  db:
    image: postgres:14.1-alpine
    restart: always
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=admin
    ports:
      - "5432:5432"
    volumes:
      - db:/var/lib/postgresql/data
      - ./db/init.sql:/docker-entrypoint-initdb.d/create_tables.sql
  cache:
    image: redis:6.2-alpine
    restart: always
    ports:
      - "6379:6379"
    command: redis-server --save 20 1 --loglevel warning
    volumes:
      - cache:/data
  api:
    container_name: api
    build:
      context: .
    #  target: production
    # image: api
    depends_on:
      - db
      - cache
    ports:
      - 3000:3000
    environment:
      NODE_ENV: production
      DB_HOST: db
      DB_PORT: 5432
      DB_USER: postgres
      DB_PASSWORD: admin
      DB_NAME: postgres
      REDIS_HOST: cache
      REDIS_PORT: 6379
    links:
      - db
      - cache
    volumes:
      - ./:/src
volumes:
  db:
    driver: local
  cache:
    driver: local

這是我的 app.js 上半部分:

const express = require('express')
const app = express()
const cors = require('cors')
const redis = require('redis')

const client = redis.createClient({
  host: 'cache',
  port: 6379,
  legacyMode: true // Also tried without this line, same behavior
})

client.connect()
client.on('connect', () => {
  log('Redis connected')
})

app.use(cors())
app.use(express.json())

還有我的 Dockerfile:

FROM node:16.15-alpine3.14
WORKDIR ./
COPY package.json ./
RUN npm install
COPY ./ ./

EXPOSE 3000 6379

CMD [ "npm", "run", "serve" ]

npm run serve 是nodemon ./app.js

我也已經嘗試修剪系統和網絡。

我錯過了什么? 幫助!

這里有兩點需要注意,

首先是Docker 網絡:容器暴露給你的本地主機系統,所以作為一個“服務器”你可以直接通過瀏覽器或命令行訪問它們中的每一個,但是

  1. 理所當然地認為您只能訪問容器,因為它們暴露於系統根可訪問的默認網絡 -您可以順便檢查的 docker 用戶。
  2. 默認情況下,部署的容器不會相互公開,因此您需要定義一個虛擬網絡並將它們公開給它,以便它們可以通過端口或主機名相互通信——這將是container_name

所以你需要做兩件事:

  1. 在 compose 文件中向 redis 添加容器名稱,就像在 API 上所做的一樣
  2. 創建一個網絡並將所有服務綁定到它,這樣做的一種方法是:

 version: "3.8" Network: my-network: name: my-network services: .... cache: container_name: cache image: redis:6.2-alpine restart: always ports: - "6379:6379" command: redis-server --save 20 1 --loglevel warning volumes: - cache:/data networks: # add it in all containers that communicate together - my-network

只有這樣你才能調用redis容器名作為主機,因為docker網絡會通過容器名為服務創建一個主機名,稍后部署整個compose文件時,容器將被創建並全部加入到啟動時默認為網絡,這將允許您 API 應用程序通過 docker 容器名稱作為主機名與 Redis 容器通信

有關詳細信息,請參閱這些資源:

不相關的注釋:我個人在一些測試項目中使用了來自 npm 的 redis,但我發現 ioredis 在 TypeScript 項目中要好得多,並且在其行為方面更值得期待

為了避免Redis出現任何問題,請確保創建密碼並使用它進行連接,有時redis會隨機將客戶端視為ReadOnly客戶端並且無法找到只讀副本,添加密碼為我解決了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM