Como tornar o banco de dados (ou parte dele) acessível a um processador de dados em nuvem?

Eu estava interessado em usar serviços ETL como o Stitch Data ou o Skyvia para integrar diferentes fontes de dados (incluindo meu banco de dados Discourse), mas alguém do Skyvia me informou que isso não é possível:

O Skyvia pode se conectar ao PostgreSQL via SSH; no entanto, não é possível conectá-lo quando ele está dentro de um contêiner Docker, enquanto o servidor SSH não está no contêiner, mas na frente dele.

Estes são os requisitos deles para conectar ao Postgres.

Existe alguma solução alternativa óbvia?

Você pode habilitar o SSH no container do Discourse (em uma porta não padrão) e, em seguida, permitir que eles se conectem lá. Acredito que possa haver um exemplo no diretório de amostras do Discourse_docker.

Obrigado, Jay. Acabei usando docker-ssh com autenticação de chave pública. :+1:

Parece que estou perdendo um conceito-chave, pois consigo me conectar via SSH com a porta personalizada e, em seguida, executar su postgres -c 'psql discourse' sem problemas. Tudo funciona nessa abordagem de dois passos, mas acredito que o que preciso para me conectar diretamente via pgAdmin (por exemplo) é algo ligeiramente diferente.

Este é o comando que estou usando para expor uma porta personalizada:

docker run -d -p 2222:22 \
        -v /var/run/docker.sock:/var/run/docker.sock \
        -v ~/.ssh/authorized_keys:/authorized_keys \
        --name my-sshd \
        -e FILTERS={\"name\":[\"^/app$\"]} -e AUTH_MECHANISM=publicKey \
        -e AUTHORIZED_KEYS=/authorized_keys \
        jeroenpeeters/docker-ssh

Isso me permite fazer isso diretamente mais tarde (sem executar o contêiner Docker via launcher enter app):

ssh whatever@host -p 2222
su postgres -c 'psql discourse'

Já tentei várias coisas, mas sem sucesso. Sinto que deve haver uma maneira de executar ssh whatever@host -p XXXX e me conectar diretamente ao banco de dados (o que provavelmente é o que o pgAdmin espera).

Você não está conseguindo conectar ou está tendo algum problema de permissão?

Consigo me conectar na linha de comando via SSH e, em seguida, usar o psql. Não consigo me conectar pelo pgAdmin.

Você precisa expor a porta do PostgreSQL diretamente para conseguir se conectar via pgAdmin.

No app.yml, perto do topo, você verá as portas 80 e 443 abertas. Você pode adicionar outra linha para a porta 5432 do PostgreSQL.

Dito isso, isso é quase certamente uma ideia muito ruim. O banco de dados passou de aceitar apenas conexões locais para ficar exposto à internet inteira.

Se tudo o que você precisa é algum relatório ocasional, baixar alguns arquivos CSV do Data Explorer e carregá-los na sua ferramenta favorita pode ser suficiente. Você também pode fazer o download de backups do Discourse (sem uploads), que estão no formato padrão de dump do PostgreSQL. Com isso em mãos, você pode restaurá-los em uma instância local do PostgreSQL para análise.

Obrigado, Rafael

Fiz isso e reconstruí o contêiner. Mas isso ainda não funciona (tenho o IP real em vez de XX.XX.XX.XX)

E na aba SSH Tunnel:

Este é o erro que recebo:

Sobre isso, entendo que é uma camada a menos de proteção, mas ainda exige ter a chave privada SSH, não é?

Se você adicionar 5432 ao app.yml, ele será exposto diretamente, sem necessidade do túnel SSH.

Não posso dar conselhos sobre o túnel SSH do pgAdmin, pois nunca o usei. Acredito que ele espera que a porta escute conexões locais, então não precisa ser exposta à internet.

Tente:

expose:
  - "80:80"
  - "443:443"
  - "5432"

Mas não há senha do PostgreSQL porque é necessário ser superusuário: o arquivo pg_hba.conf tem as permissões de conexão “local” definidas como “peer”, o que depende do usuário UNIX, exigindo login via SSH, não é?

Isso não funciona: psql -h XX.XX.XX.XX -p 5432 -U postgres -d discourse

Você pode se conectar ao psql como superusuário

./launcher enter app
su postgres
psql

e criar o usuário necessário com as permissões necessárias para seus relatórios.

Certo, não tenho problemas ao conectar a partir do contêiner Docker do aplicativo. Meu problema é conectar diretamente ao banco de dados PostgreSQL a partir da minha máquina local (para que eu possa usar o pgAdmin) ou a partir de um processador de dados em nuvem como o Stitch. Ambos esperam um endereço IP de host e credenciais SSH, mas não consegui fazê-los funcionar (recebo o erro que mostrei acima).

A única coisa que consegui fazer foi usar o docker-ssh para acessar diretamente o contêiner Docker do aplicativo (via chave pública) a partir do meu computador local (sem executar launcher enter app), mas ainda preciso executar su postgres 'psql discourse' para acessar o banco de dados. Acredito que esse seja o problema com o pgAdmin/Stitch — eles esperam uma conexão direta.

Você tentou criar um novo PostgreSQL com uma senha e fornecê-la ao seu serviço?

Sim, eles têm um procedimento bastante extenso.

Mas eu tenho o mesmo problema simplesmente usando o pgAdmin do meu computador local.

Acredito que o tópico Como migrar de um contêiner autônomo para contêineres separados de web e dados possa conter instruções para definir uma senha.

Além disso, acho que você poderia vincular a porta do PostgreSQL apenas ao 127.0.0.1.

expose:
  - "80:80"
  - "443:443"
  - "127.0.0.1:5432:5432"

Decidi dar um passo atrás para ver se consigo me conectar ao banco de dados sem expor nenhuma porta. :grin:

Se eu entrar no container, vejo isso:

# netstat -lp | grep postgres
tcp        0      0 0.0.0.0:postgresql      0.0.0.0:*               LISTEN      -
tcp6       0      0 [::]:postgresql         [::]:*                  LISTEN      -
unix  2      [ ACC ]     STREAM     LISTENING     263612292 -                    /var/run/postgresql/.s.PGSQL.5432

Se eu sair do container e estiver no meu servidor remoto (ainda não no meu computador local), não deveria conseguir me conectar usando isso?

/var/discourse# psql -h localhost -d discourse -U postgres

O problema é que recebo uma solicitação de senha. Como o usuário postgres não tem senha, tentei criar um usuário diferente e atribuir uma senha a ele:

CREATE USER whatever_user WITH ENCRYPTED PASSWORD '<whatever password>';
GRANT CONNECT ON DATABASE discourse TO whatever_user;
GRANT USAGE ON SCHEMA public TO whatever_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO whatever_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO whatever_user;

Adicionei uma linha para esse usuário com md5 no pg_hba.conf e reiniciei o PG com service postgresql restart

# Database administrative login by Unix domain socket
local   all             postgres                                peer
local   all             whatever_user                      md5

No entanto, ao tentar me conectar a partir do servidor remoto, recebo uma falha de autenticação:

# psql -h localhost -d discourse -U whatever_user
Password for user whatever_user:
psql: FATAL:  password authentication failed for user "whatever_user"
FATAL:  password authentication failed for user "whatever_user"

O que estou esquecendo? Estou tentando, pelo menos, conseguir me conectar ao banco de dados a partir do mesmo servidor. O passo 2 seria fazer o mesmo usando um túnel SSH, mas acho que preciso resolver o passo 1 primeiro. Qualquer ajuda é bem-vinda.

Ok. Finalmente consegui resolver :tada:

Mudei isso:

para isso - "127.0.0.1:5433:5432", porque recebi um erro dizendo que a porta já estava em uso.

Reconstruí o container e verifiquei se a porta estava realmente aberta:

$ sudo docker ps
CONTAINER ID        IMAGE                           COMMAND             CREATED             STATUS              PORTS                      NAMES
whatever_id        local_discourse/app             "/sbin/boot"        20 minutes ago      Up 20 minutes       127.0.0.1:5433->5432/tcp   app

Agora consigo criar um túnel SSH e me conectar do meu servidor remoto usando um usuário com senha:

# cria o túnel (você também pode usar ssh -f para executá-lo em segundo plano)
ssh -v -N -L 5433:localhost:5433 SERVER_IP_ADDRESS

# conecta em outra aba e insere a senha
psql -h localhost -d discourse -U whatever_user -p 5433

Se alguém estiver tentando fazer isso e encontrar problemas, me avise.