Nota: esta es una traducción de mi publicación (en inglés), que describe la implementación del servidor de comentarios utilizado en el mismo sitio donde se encuentra el original.
Versión TL; DR: desarrollé la configuración del servidor Commento, que se implementa fácil y simplemente en modo semiautomático. Copie este repositorio para usted desde GitHub y siga las instrucciones en README .
Hace algún tiempo, quería irresistiblemente cambiar Disqus, que es quizás el sistema más común para agregar comentarios a las páginas, a un Commento gratuito y abierto.
El problema con Disqus, como muchos otros productos "gratuitos", es que el producto en este caso es el usuario, es decir, usted. Además, Disqus "enriquece" cada página donde se usa con megabytes de scripts y más de cien solicitudes HTTP adicionales.
Además, su versión gratuita muestra anuncios desde los cuales puede pagar "solo" por $ 9 por mes (plan Plus). Esto solo es suficiente para querer encontrar algo mejor.
En algún momento, me topé con esta publicación y descubrí la existencia de un servidor de comentarios gratuito llamado Commento . Por una coincidencia afortunada, Commento recientemente se abrió por completo, antes de que estuviera disponible en dos versiones, Comunidad gratuita y Empresa comercial. Gracias a su desarrollador Adhityaa Chandrasekar.
Commento es un orden de magnitud más eficiente que Disqus, el tamaño típico de la carga adicional con él es de aproximadamente 11 KB , más los comentarios en sí, por supuesto. Aproximadamente la misma situación con las solicitudes HTTP requeridas.
Otra ventaja del servidor Commento es que es muy rápido, ya que está escrito en Go.
Bueno, como guinda del pastel, tiene una gran cantidad de comentarios de Disqus, ¿con qué más podría soñar?
Para usuarios no avanzados (técnicamente), Commento tiene un servicio en la nube listo para usar en commento.io . El autor le ofrece elegir la tarifa mensual usted mismo, pero no puede ser inferior a $ 3 "por razones técnicas".
El Sr. Chandrasekar también ofrece generosamente una cuenta gratuita en Commento.io a cambio de "parches no triviales" para el producto.
Bueno, elegí la tercera opción: subir el servidor Commento yo mismo. En este caso, no dependes de nadie (además del hoster, por supuesto), y me encanta la independencia.
Dificultades
Soy un gran admirador de los contenedores Docker y también uso a menudo Docker Compose , una herramienta para administrar grupos de varios contenedores relacionados. Commento tiene una imagen Docker lista para usar en el registro de contenedor de GitLab.
Por lo tanto, la decisión de usar recipientes maduró por sí sola, pero primero debían decidirse algunas cosas.
Dificultad No. 1: PostgreSQL
Commento requiere una versión bastante reciente del servidor PostgreSQL, desafortunadamente no se admiten otros servidores SQL.
Bueno, todavía ejecutamos todo en contenedores, por lo que es bastante simple.
Dificultad # 2: No hay soporte HTTPS
Commento en sí es un servidor web, pero solo admite el protocolo HTTP inseguro.
Cabe señalar que esta práctica es bastante común en estos días: en este caso, el servidor está oculto detrás del proxy inverso , que también realiza la descarga de SSL. La cuestión es que la compatibilidad con SSL / HTTPS es absolutamente necesaria en este caso, después de todo, en el patio 2019 y mirar los intentos de autorizar a un usuario utilizando un protocolo de Internet no seguro será muy irónico.
Decidí usar el servidor Nginx , en primer lugar, tenía una experiencia considerable trabajando con él y, en segundo lugar, es muy rápido, económico y estable. Y publica las compilaciones oficiales de las imágenes de Docker .
El segundo ingrediente en la receta HTTPS es el certificado SSL para el dominio. Estoy eternamente agradecido con EFF y Mozilla por crear la Autoridad de certificación Let's Encrypt , que emite millones de certificados gratuitos cada mes.
Let's Encrypt también proporciona una utilidad de línea de comandos gratuita llamada certbot , que simplifica enormemente el proceso de obtención y actualización de un certificado. Bueno, y, por supuesto, ¡una imagen de Docker para él!
Dificultad # 3: Problema del huevo de gallina Certbot
Pero este truco es más complicado.
Queremos referirnos al certificado SSL en la configuración de nuestro proxy inverso en Nginx, lo que significa que sin un certificado simplemente se niega a comenzar. Al mismo tiempo, para obtener un certificado SSL para un dominio, necesita un servidor HTTP que funcione, que Let's Encrypt demostrará su propiedad de este dominio.
Me las arreglé para resolver este problema y, me parece, con bastante elegancia:
- Primero, se genera un certificado ficticio e inválido, cuyo único propósito es permitir que Nginx se inicie.
- Nginx y certbot reciben conjuntamente un nuevo certificado ahora válido.
- Tan pronto como se recibe el certificado, certbot entra en "modo de espera", despertando cada 12 horas para verificar si necesita actualizarse, de acuerdo con las recomendaciones de Let's Encrypt.
- Cuando llegue el momento y el certificado se haya renovado, certbot le indicará a Nginx que se reinicie.
Dificultad No. 4: algo debe ser preservado
Sospecho firmemente que desea guardar los comentarios de los usuarios después de un reinicio o una actualización del sistema.
Además, para que Let's Encrypt no lo prohíba debido a solicitudes demasiado frecuentes, sería bueno conservar los certificados recibidos durante toda la fecha de vencimiento.
Ambos puntos se resolvieron en la configuración propuesta utilizando los volúmenes de Docker, creados automáticamente por systemd cuando se lanzó Commento por primera vez. Los volúmenes se marcan como external
, por lo que Docker los omite al eliminar contenedores con docker-compose down -v
.
Reúne todo
Ahora puedes ver cómo funciona todo junto.
La siguiente figura muestra la interacción y el tráfico entre los cuatro contenedores:

depends_on
opción depends_on
Docker Compose depends_on
para asegurar que los contenedores comiencen en el orden correcto.
Si solo desea iniciar su propio servidor Commento, puede omitir el resto del artículo e ir directamente al código en GitHub .
Bueno, hablaré más sobre esta implementación con más detalle más adelante.
Como funciona todo
Redactar archivo
Como puede ver en la imagen de arriba, mi "composición" consta de cuatro servicios:
certbot
- utilidad certbot
de EFFnginx
: proxy inverso que implementa la descarga SSLapp
- servidor Commentopostgres
- base de datos PostgreSQL
El docker-compose.yml
contiene declaraciones de su propia red Docker, llamada commento_network
, y tres volúmenes, de los cuales dos son externos (es decir, deben crearse fuera de Compose):
commento_postgres_volume
almacena datos del servidor PostgreSQL para Commento: usuarios, moderadores, comentarios, etc.certbot_etc_volume
contiene los certificados recibidos por certbot
.
Nginx
El contenedor Nginx se basa en una imagen oficial ligera basada en Alpine y utiliza el siguiente script para ejecutarse:
- Línea 3 ( ARRGHHH, Habr no admite la visualización de números de línea en el código - aprox. Transl. ) Se registra un controlador de interrupciones para que Nginx y el proceso de monitoreo en segundo plano completen con éxito el trabajo cuando el contenedor se detenga.
- La línea 27 llama a la función de espera, que detiene el proceso de inicio de Nginx hasta que
certbot
archivos de configuración SSL creados por el contenedor certbot
. Sin esto, Nginx se negaría a comenzar. - La línea 30 crea un proceso en segundo plano que regularmente, cada diez segundos, verifica la presencia de un archivo indicador llamado
.nginx-reload
, y tan pronto como lo detecta, le indica a Nginx que vuelva a cargar la configuración. Este archivo también crea certbot cuando se actualiza el certificado. - La línea 34 inicia Nginx en modo normal. En este caso,
exec
significa que el proceso de shell actual se reemplaza por el proceso Nginx.
Otro archivo importante en esta imagen es la configuración del servidor virtual Commento, que obliga a Nginx a reenviar solicitudes HTTPS al contenedor de commento
:
server { listen [::]:443 ssl ipv6only=on; listen 443 ssl; server_tokens off; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name __DOMAIN__; location / { proxy_pass http://app:8080/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } ssl_certificate /etc/letsencrypt/live/__DOMAIN__/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/__DOMAIN__/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } server { listen 80 default_server; listen [::]:80 default_server; server_tokens off; server_name __DOMAIN__; location /.well-known/acme-challenge/ { root /var/www/certbot; }
El primer bloque de servidor (líneas 1-21 ) describe cómo trabajar con HTTPS y la regla de reenvío. Aquí es donde se mencionan los archivos de certificado Let's Encrypt (o se usan stubs en su lugar).
El dominio servido por el servidor se pasa como argumento al construir la imagen; reemplaza la línea __DOMAIN__
en la configuración del servidor.
El segundo bloque (líneas 23-38 ) es la configuración del servidor HTTP, que es utilizado por el certbot para confirmar la propiedad del dominio (el llamado "desafío ACME"). Todas las demás solicitudes provocan un redireccionamiento a la dirección correspondiente a través de HTTPS.
certbot
Nuestra imagen certbot se basa en la compilación oficial con el siguiente script:
Un breve recorrido por sus líneas:
- La línea 3 , como en la secuencia de comandos anterior, es necesaria para completar el contenedor regularmente.
- Las líneas 17-19 verifican las variables requeridas.
- Y en las líneas 22-25 , que los directorios necesarios para que certbot funcione están montados correctamente.
- El tenedor sigue:
- Las líneas 30-50 se ejecutan solo en el primer inicio del contenedor:
- Se copia un certificado ficticio, lo que permite que Nginx se inicie normalmente.
- Nginx, mientras tanto, está esperando el final de este proceso, luego de lo cual continúa descargándose.
- Una vez que Nginx ha comenzado, certbot inicia el proceso de obtención de un certificado válido de Let's Encrypt.
- Y finalmente, tan pronto como se recibe el certificado, se crea el archivo
.nginx-reload
, insinuando a Nginx que es hora de volver a cargar la configuración.
- La línea 54 espera a que Nginx se inicie, en el caso de que un certificado completo ya esté disponible.
- Después de todo esto (líneas 58-63 ), continúa con el ciclo, una vez cada 12 horas, verificando la necesidad de renovar el certificado y señalando a Nginx para reiniciar.
La app
y los contenedores de postgres
usan las imágenes originales proporcionadas por los desarrolladores sin ningún cambio.
Servicio Systemd
La última pieza de este rompecabezas es el archivo de unidad systemd commento.service
, en el que debe crear un enlace simbólico en /etc/systemd/system/commento.service
para que se inicie en un buen momento cuando se inicia el sistema:
[Unit] Description=Commento server [Service] TimeoutStopSec=30 WorkingDirectory=/opt/commento ExecStartPre=-/usr/bin/docker volume create commento_postgres_volume ExecStartPre=-/usr/bin/docker volume create certbot_etc_volume ExecStartPre=-/usr/local/bin/docker-compose -p commento down -v ExecStart=/usr/local/bin/docker-compose -p commento up --abort-on-container-exit ExecStop=/usr/local/bin/docker-compose -p commento down -v [Install] WantedBy=multi-user.target
Filas:
- La línea 6 implica que el código del proyecto está clonado en el directorio
/opt/commento
, esto es mucho más simple. - Las líneas 7-8 crean volúmenes externos, si aún no lo están.
- En la línea 9 , se eliminan los posibles restos de los contenedores anteriores. Los volúmenes externos se conservan.
- La línea 10 marca el lanzamiento real de Docker Compose. El
--abort-on-container-exit
toda la bandada de contenedores cuando alguno de ellos se --abort-on-container-exit
. Gracias a esto, systemd al menos sabrá que el servicio está detenido. - La línea 11 nuevamente está limpiando y eliminando contenedores, redes y volúmenes.
Código fuente
Una implementación completamente funcional, que requiere solo la configuración de variables en docker-compose.yml
, está disponible en GitHub . Solo necesita seguir cuidadosamente los pasos descritos en README .
El código está sujeto a la licencia MIT .
Gracias por leer este lugar, ¡los comentarios son frenéticamente bienvenidos!