¿Es posible conectarse directamente a la base de datos desde una aplicación separada?

La aplicación estaría fuera del contenedor Docker de Discourse, pero en el mismo servidor. En ese caso, ¿alguien podría compartir algunos detalles sobre cómo hacerlo o indicarme una guía o instrucciones, por favor?

¿También habría alguna desventaja al hacerlo en lugar de usar el plugin o la API DE?

Las desventajas se deben principalmente a que dicha conexión podría usarse para acceso de escritura. ¿Es eso un requisito?

Si tu integración necesita acceso de escritura a la base de datos, considera escribir un plugin que exponga solo las operaciones que necesitas.

No es un requisito, pero me parece bien como inconveniente :slight_smile:

Empecé a usar tu plugin DE, pero desafortunadamente creo que mi caso de uso requerirá una conexión directa, ya que estoy enviando demasiadas solicitudes a través de la API para algunas de mis páginas (y eso solo contando con mi propio tráfico en el sitio). La mayoría son consultas personalizadas, así que no estoy seguro de si eso está teniendo algún impacto. ¡Aun así, me encanta el plugin DE!
¿Sabrías cuál es la mejor manera de conectarse directamente a la base de datos Postgres fuera del contenedor? Tanto el foro como el sitio están en el mismo servidor, por si eso ayuda.


Edición: Creo que estoy alcanzando un límite de tasa con el plugin DE, pero estoy seguro de que vi a Sam decir que si las solicitudes provienen del mismo servidor no se aplica ningún límite de tasa. ¿Sigue siendo así?

Aunque es posible, la otra aplicación puede adquirir bloqueos en las tablas e impedir que Discourse funcione con normalidad.

Puedes optar por un nuevo plugin que agregue los puntos de conexión de API necesarios que necesitas, o bien sumergirte por completo creando otra instancia de PostgreSQL que replique tu Discourse y donde puedas integrar tu aplicación.

Gracias por la información, Rafael. Voy a utilizar exclusivamente sentencias SELECT y, hasta donde sé, estas no generan bloqueos, por lo que solo tendría que preocuparme por los cambios en la tabla del lado de Discourse (es decir, durante las actualizaciones) y en los momentos en los que pueda desactivar temporalmente la otra aplicación. ¿Eso mitigaría las preocupaciones sobre los bloqueos?

En cuanto a replicar la base de datos, parece una opción interesante. ¿Se puede hacer en tiempo real, de modo que los datos no estén desactualizados por más de un par de minutos? (Necesito obtener los temas más recientes con frecuencia: casi todas las páginas del sitio los incluyen, aunque tengo una caché de dos minutos; sin embargo, estos varían según la página y los criterios, y habrá cientos de este tipo de páginas). Además, ¿esta opción podría dejar de ser viable a medida que la base de datos crezca? (En otro foro de Discourse, mi base de datos ya tiene varios gigabytes).

(No creo que crear un plugin sea una opción aquí, ya que no veo cómo podría ser mejor que el plugin Data Explorer; de hecho, el plugin DE es casi perfecto, salvo por este problema.)

¿Alguien tiene alguna idea de por qué esto no funciona, por favor?

Seguí algunos de los posts de @pfaffman y @Nacho_Caballero en este tema: How to make the database (or part of it) accessible to a cloud data processor? y el post de @mpalmer en este otro: Accessing to the database from outside the container - #4 by mpalmer.

Primero edité app.yml con:

expose:
  - "127.0.0.2:5432:5432"

Reconstruí el contenedor. Dentro del contenedor, establecí una contraseña para el usuario postgres y luego pude conectarme desde dentro del contenedor con lo siguiente:

psql -h localhost -d discourse -U postgres

Sin embargo, cuando salgo del contenedor e intento conectarme, obtengo:

# psql -h 127.0.0.2 -p 5432 -d discourse -U postgres
psql: server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.

También he probado cambiar el puerto por otro, pero obtengo lo mismo. Obtuve la IP 127 de docker ps y al inspeccionar en Network Settings (tengo tres instancias independientes de Discourse en ejecución).

Si cambio la IP (a la de uno de los otros foros de Discourse), obtengo una respuesta/mensaje diferente (más inmediata), por lo que lo anterior parece ser parcialmente correcto:

# psql -h 127.0.0.3 -p 5432 -d discourse -U postgres
psql: could not connect to server: Connection refused
	Is the server running on host "127.0.0.3" and accepting
	TCP/IP connections on port 5432?

¿Alguna idea de qué estoy haciendo mal? Buscar en Google psql: server closed the connection unexpectedly parece sugerir un problema de red, ¿necesito cambiar algo más dentro del contenedor?

Lo que funcionó para mí (desde fuera del contenedor) es usar un túnel SSH. De hecho, creé un nuevo usuario en lugar de usar postgres y configuré puertos personalizados para SSH y postgres, pero esto debería funcionar en tu configuración:

ssh -L 5432:localhost:5432 EXTERNAL_VPS_IP "psql -U postgres -d discourse -h localhost"

EXTERNAL_VPS_IP es la dirección IP que usas para conectarte a tu servidor remoto.

Si aún así no funciona, podrías intentar cambiar la IP expuesta en app.yml para usar la IP del puente de Docker en lugar de la IP interna del contenedor que obtuviste con docker ps. No estoy seguro de si esto es necesario, pero así es como lo tengo configurado:

expose:
  - "127.0.0.1:5432:5432"
# o si usas un puerto personalizado:  - "127.0.0.1:PUERTO_PERSONALIZADO:5432"

Recuerda reconstruir el contenedor después.

Avísame cómo te va. Me llevó MUCHO TIEMPO lograr que todo funcionara (y al final fue tan sencillo), así que estoy encantado de ayudar.

¡Gracias por la información @Nacho_Caballero… especialmente el enlace sobre docker!

Parece que el consejo en tu (y en el otro) hilo era correcto, necesitas:

expose:
  - "127.17.0.1:5432:5432"

…como se menciona en ese enlace, Docker reenviará automáticamente al IP correcto para tu contenedor (lo cual tiene sentido dado que esas IPs son dinámicas, algo que me había preguntado). Creo que esto es todo lo necesario para la mayoría de las configuraciones.

Aunque ya había intentado eso, así que quizás te preguntes cuál era mi problema. ¡Mi firewall! (¡Pensé que reconocía el error psql: server closed the connection unexpectedly!)

Todo resuelto ahora, ¡gracias a todos :blush:

¡Qué bueno saberlo! Me alegra que lo hayas solucionado. ¿Tu firewall es iptables? ¿Cómo abriste el puerto?

Uso firewalld, pero para iptables algo como esto debería funcionar:

iptables -A INPUT -p tcp --dport xxxx -j ACCEPT
iptables -A OUTPUT -p tcp --dport xxxx -j ACCEPT