Доступ к базе данных Postgres на стороне контейнера через container-side Node.js веб-приложение

#node.js #postgresql #docker

#node.js #postgresql #docker

Вопрос:

У меня есть Dockerfile для Node.js приложение, которое в целом выглядит следующим образом:

 FROM ubuntu
RUN rm /bin/sh amp;amp; ln -s /bin/bash /bin/sh

WORKDIR /app
COPY . /app

ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y -q --no-install-recommends 
        apt-transport-https 
        build-essential 
        ca-certificates 
        curl 
        git 
        libssl-dev 
        wget 
        postgresql-10 postgresql-client-10 postgresql-contrib-10

USER postgres
RUN    /etc/init.d/postgresql start amp;amp;
    psql --command "CREATE USER warbler WITH SUPERUSER;" amp;amp;
    createdb -O warbler warbler_store

# ... node setup stuff ...
# ...
# ...

RUN psql -U warbler -d warbler_store -f db_v1.sql

CMD ["node", "index.js"]
  

При этом я получаю следующее сообщение об ошибке:

 psql: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
  

Я немного поискал в Интернете, и большинство найденных мной решений, похоже, говорят, что docker пытается подключиться к экземпляру хоста postgres, среди других вопросов, связанных с контейнерами docker, основной целью которых является запуск PostgreSQL. Является ли это точным, и если да, то все еще возможно запустить экземпляр PostgreSQL на стороне контейнера, доступный для основного приложения?

Ответ №1:

По-видимому, не рекомендуется размещать вашу базу данных в том же контейнере Docker, что и ваше веб-приложение. Я изменил структуру своего контейнера, просто используя postgresql:10 изображение в другом контейнере и используя веб-приложение для связи с ним docker-compose . docker-compose позволяет определять службы, а внутренний DNS Docker позволит им взаимодействовать друг с другом

Вот как docker-compose.yaml выглядит:

 version: '3'
services:
    web:
        build: .
        ports:
        - "3000:3000"
        volumes:
        - .:/app
        links:
        - db

    db:
        image: postgres:10
        environment:
        - POSTGRES_USER=warbler
        - POSTGRES_DB=warbler_store
        volumes:
        - ./db_v1.sql:/docker-entrypoint-initdb.d/db_v1.sql
        - dbdata:/var/lib/postgresql/data

volumes:
    dbdata:
  

В этом случае в Dockerfile for web я устанавливаю необходимые переменные среды, чтобы узел подключался к базе данных, запущенной на postgresql://db:5432/warbler_store . db преобразуется через DNS в IP-адрес контейнера, в котором запущена db служба, которая является postgres контейнером изображения.