Cómo instalar Ghost CMS con Docker en Ubuntu 20.04

P√°gina de inicio fantasma

Ghost es una plataforma de blogs de código abierto para ayudarte a crear un blog de aspecto profesional. Se lanzó en 2013 como una alternativa a WordPress porque se estaba volviendo demasiado complejo. Ghost está escrito en JavaScript y funciona con Node.js.

En este tutorial, exploraremos c√≥mo instalar Ghost CMS usando Docker en un servidor con Ubuntu 20.04. Tambi√©n usaremos Nginx como proxy y el certificado Let’s Encrypt SSL para asegurar nuestra instalaci√≥n.

requisitos previos

  • Un servidor con Ubuntu 20.04.
  • Un usuario sudo no root.
  • Aseg√ļrate de que todo est√© actualizado.
    $ sudo apt update 
    $ sudo apt upgrade
    

Paso 1: configurar el cortafuegos UFW

El primer paso es configurar el cortafuegos. Ubuntu viene con ufw (Cortafuegos sin complicaciones) por defecto.

Compruebe si el cortafuegos se est√° ejecutando.

$ sudo ufw status

Deberías obtener el siguiente resultado.

Status: inactive

Permita el puerto SSH para que el firewall no interrumpa la conexión actual al habilitarlo.

$ sudo ufw allow OpenSSH

Permita también los puertos HTTP y HTTPS.

$ sudo ufw allow 80
$ sudo ufw allow 443

Habilitar el cortafuegos

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Vuelva a comprobar el estado del cortafuegos.

$ sudo ufw status

Deberías ver una salida similar.

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
80                         ALLOW       Anywhere
443                        ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
80 (v6)                    ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

Paso 2: instale Certbot y obtenga el certificado SSL

Antes de continuar, debemos instalar la herramienta Certbot e instalar un certificado SSL para nuestro dominio.

Para instalar Certbot, usaremos el instalador del paquete Snapd. El repositorio oficial de Certbot ha quedado obsoleto y el paquete Certbot de Ubuntu tiene m√°s de un a√Īo. Snapd siempre lleva la √ļltima versi√≥n estable de Certbot y deber√≠a usarla. Afortunadamente, Ubuntu 20.04 viene con Snapd preinstalado.

Aseg√ļrese de que su versi√≥n de Snapd est√© actualizada.

$ sudo snap install core 
$ sudo snap refresh core

Elimine cualquier versión anterior de Certbot.

$ sudo apt remove certbot

Instale Certbot.

$ sudo snap install --classic certbot

Utilice el siguiente comando para asegurarse de que el comando Certbot se pueda ejecutar creando un enlace simbólico al directorio /usr/bin.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Genere un certificado SSL.

$ sudo certbot certonly --standalone -d example.com

El comando anterior descargar√° un certificado en el directorio /etc/letsencrypt/live/example.com de su servidor.

Paso 3: instale Docker y Docker Compose

El primer paso es instalar Docker Engine y Docker Compose. Primero, desinstale cualquier versión anterior de Docker.

$ sudo apt remove docker docker-engine docker.io containerd runc

Instale algunos paquetes necesarios para que se ejecute Docker.

$ sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release

Agregue la clave GPG oficial de Docker.

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Agregue el repositorio oficial de Docker.

$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Actualice los repositorios del sistema.

$ sudo apt update

Instale la √ļltima versi√≥n de Docker Engine.

$ sudo apt install docker-ce docker-ce-cli containerd.io

Verifique que Docker Engine esté funcionando e instalado correctamente.

$ sudo docker run hello-world

De forma predeterminada, Docker requiere sudo para ejecutarse. Para evitar eso, podemos agregar la cuenta de usuario actual al grupo de usuarios de Docker.

$ sudo usermod -aG docker ${USER}

Para aplicar la nueva pertenencia al grupo, cierre la sesión y vuelva a iniciarla o use el siguiente comando.

$ su - ${USER}

Ahora, puede ejecutar los comandos de la ventana acoplable sin usar sudo.

A continuación, descargue la versión estable actual de Docker compose.

sudo curl -L "https://github.com/docker/compose/releases/download/1.28.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

Al momento de escribir este tutorial, 1.28.6 es la √ļltima versi√≥n de Docker compose. Siempre puede cambiar o elegir una versi√≥n diferente en el comando comprobando desde el Github lanza la p√°gina de Docker compose.

Aplique el permiso ejecutable a la versión instalada de Docker compose.

$ sudo chmod +x /usr/local/bin/docker-compose

Pruebe la instalación.

$ docker-compose --version
docker-compose version 1.28.6, build 5db8d86f

Paso 4 – Instalar fantasma

La instalaci√≥n de Ghost constar√° de tres componentes: el paquete Ghost, un servidor de base de datos como MySQL y un servidor web (Nginx). Todos estos servicios se pueden instalar utilizando un √ļnico archivo de composici√≥n de Docker.

Crear archivo de redacción de Docker

Primero, cree un directorio para almacenar y ejecutar su archivo de composición de Docker.

$ mkdir ghost && cd ghost

Cree un archivo llamado docker-compose.yml y √°bralo con el editor Nano.

$ nano docker-compose.yml

Pegue el siguiente c√≥digo en el archivo. Reemplaza ejemplo.com con tu dominio e inserta una contrase√Īa de base de datos en lugar del valor de tu_contrase√Īa. Mantenga los mismos valores para la base de datos__conexi√≥n__contrase√Īa y MYSQL_ROOT_PASSWORD. Reemplace con el nombre de usuario de su servidor.

version: '3.3'
services:

  ghost:
    image: ghost:latest
    restart: always
    depends_on:
      - db
    environment:
      url: https://example.com
      database__client: mysql
      database__connection__host: db
      database__connection__user: ghost
      database__connection__password: ghostdbpass
      database__connection__database: ghostdb
      mail__transport: SMTP
      mail__options__host: {Your Mail Service host}
      mail__options__port: {Your Mail Service port}
      mail__options__secureConnection: {true/false}
      mail__options__service: {Your Mail Service}
      mail__options__auth__user: {Your User Name}
      mail__options__auth__pass: {Your Password}
    volumes:
      - /home/<username>/ghost/content:/var/lib/ghost/content

  db:
    image: mariadb:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: your_mysql_root_password
	  MYSQL_USER: ghost
      MYSQL_PASSWORD: ghostdbpass
      MYSQL_DATABASE: ghostdb
    volumes:
      - /home/<username>/ghost/mysql:/var/lib/mysql

  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    restart: always
    depends_on:
      - ghost
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /etc/letsencrypt/:/etc/letsencrypt/
      - /usr/share/nginx/html:/usr/share/nginx/html

El archivo de composición de Docker crea algunos puntos de montaje, es decir, asigna ciertos directorios en el servidor a directorios dentro del contenedor.

  • Los directorios /var/lib/ghost/content y /var/lib/mysql dentro de sus contenedores est√°n asignados a /home//ghost/content y /home//ghost/mysql en el servidor.
  • Nginx usa el enlace /etc/letsencrypt/ para acceder a los certificados de Let’s Encrypt desde el servidor.
  • Nginx tambi√©n necesita acceso al directorio de usuarios /usr/share/nginx/html para que pueda acceder a los archivos de Let’s Encrypt Challenge para el certificado.

En el archivo anterior, tambi√©n hemos incluido opciones para configurar el correo. Si est√° utilizando un servicio de correo SMTP popular como Mailgun, Mailjet, Mandrill, Postmark, Sendgrid, SendCloud, SES, Zoho o Gmail, simplemente puede agregar el nombre del servicio y su nombre de usuario y contrase√Īa SMTP y eliminar el resto de los campos. De lo contrario, complete todas las dem√°s opciones y elimine el nombre del servicio y a√ļn deber√≠a funcionar. Puedes consultar m√°s opciones de correo en Documentaci√≥n de Ghost sobre las opciones de correo.

Cree directorios para todos los montajes de enlace descritos anteriormente (excepto para /etc/letsencrypt, que ya se creó cuando creamos el certificado antes)

$ cd ~/ghost
$ mkdir content
$ mkdir mysql
$ sudo mkdir -p /usr/share/nginx/html

Crear la imagen acoplable de Nginx

El archivo de redacción de Docker que creamos se basa en la imagen de Nginx Docker. Para que funcione, debemos incluir un archivo de configuración personalizado para Nginx que funcionará con Ghost.

Cree un directorio para esta imagen en el directorio actual.

$ mkdir nginx

Cree un archivo llamado Dockerfile en este directorio.

$ touch nginx/Dockerfile

Pegue el siguiente código en el Dockerfile.

FROM nginx:latest
RUN rm /etc/nginx/conf.d/default.conf
COPY ghost.conf /etc/nginx/conf.d

El c√≥digo anterior le indica a Docker que use la √ļltima imagen de Nginx. Tambi√©n elimina el archivo de configuraci√≥n predeterminado de Nginx y copia el archivo de configuraci√≥n personalizado que hemos creado para nuestro Ghost CMS.

Cree un archivo llamado ghost.conf en el directorio nginx.

$ touch nginx/ghost.conf

Pegue el siguiente código en el archivo ghost.conf. Reemplace todas las instancias de ejemplo.com con su dominio.

server {
  listen 80;
  listen [::]:80;
  server_name example.com;
  # Useful for Let's Encrypt
  location /.well-known/acme-challenge/ { root /usr/share/nginx/html; allow all; }
  location / { return 301 https://$server_name$request_uri; }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name example.com;
    
  access_log /var/log/nginx/ghost.access.log;
  error_log /var/log/nginx/ghost.error.log;
  client_max_body_size 20m;

  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
  ssl_prefer_server_ciphers on;
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:10m;

  ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  location / {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://ghost:2368;
  }
}

La configuración anterior redirigirá todas las solicitudes HTTP a HTTPS y servirá como un proxy para que el servicio Ghost lo sirva a través de su dominio.

Paso 5 – Ejecute el sitio

Ejecute el siguiente comando desde el directorio fantasma para iniciar el servicio Ghost.

$ docker-compose up -d

Ahora, puede verificar su instalación abriendo https://example.com en su navegador web. Es posible que Docker tarde varios minutos en encender todos los servicios, por lo que es posible que deba actualizar si no ve su blog de inmediato.

P√°gina de inicio fantasma

Si su sitio no aparece en el navegador, debe revisar los registros de Docker. Para eso, primero cierra tu contenedor.

$ cd ghost
$ docker-compose down

Ejecute Docker compose en un estado adjunto para ver los registros generados por cada contenedor.

$ docker-compose up

Para cerrar el contenedor y volver al indicador de bash, presione CTRL+C. Una vez que haya terminado de solucionar el problema, puede ejecutar el contenedor nuevamente y su blog debería estar visible esta vez.

Paso 6 РConfiguración completa

Para terminar de configurar su blog de Ghost, visite https://example.com/ghost en su navegador. El /fantasma adicional al final del dominio de su blog lo redirige al Panel de administración de Ghost o, en este caso, a la configuración, ya que está accediendo a él por primera vez.

Página de configuración fantasma

Aquí, se le pedirá que cree su cuenta de administrador y elija un título de blog.

Detalles de configuración fantasmaAnuncio publicitario

También puede invitar a miembros del personal o colaboradores adicionales para su blog, lo que también puede hacer más tarde si elige omitir ahora.

Página de invitación del personal fantasma

Al final de la configuración, aparecerá el panel de administración de Ghost.

Panel de administración fantasma

Si desea cambiar al modo oscuro, puede hacerlo haciendo clic en el interruptor junto al botón de configuración en la parte inferior de la página de configuración.

Cambio de modo fantasma oscuro

Ya verá algunas publicaciones predeterminadas que son básicamente guías para ayudarlo a navegar y usar Ghost. Puede anular su publicación o eliminarlos y comenzar a publicar.

Paso 7 – Actualizar fantasma

En nuestro archivo de composici√≥n de Docker, extraemos la √ļltima versi√≥n de Ghost disponible en el momento de la instalaci√≥n, lo que facilita la actualizaci√≥n de su blog de Ghost.

Para actualizar, debe cerrar su contenedor, extraer las im√°genes m√°s recientes y luego ejecutar el contenedor nuevamente.

$ docker-compose down
$ docker-compose pull && docker-compose up -d

Paso 8: renueve su certificado SSL de Let’s Encrypt

Los certificados de Let’s Encrypt son v√°lidos solo por 90 d√≠as. Por lo tanto, debemos configurar un cronjob que renovar√° el certificado autom√°ticamente.

Abra Crontab en su editor.

$ sudo crontab -e

Pegue la siguiente línea al final que ejecutará Certbot a las 11 p. m. todos los días. Reemplaza ejemplo.com con tu dominio.

0 23 * * *   certbot certonly -n --webroot -w /usr/share/nginx/html -d example.com --deploy-hook='docker exec ghost_nginx_1 nginx -s reload'

La ejecución a las 11 p. m. todos los días no significa que su certificado se renovará todos los días, ya que Certbot renovará su certificado solo si su fecha de vencimiento es dentro de los 30 días. Ejecutar esto todas las noches le da al script varias oportunidades para intentarlo antes de que caduque.

El comando anterior también reiniciará el servidor Nginx dentro del contenedor Docker después de la renovación exitosa.

Puede probar el cronjob usando la opci√≥n –dry-run de Certbot.

$ sudo bash -c "certbot certonly -n --webroot --dry-run -w /usr/share/nginx/html -d example.com --deploy-hook='docker exec ghost_nginx_1 nginx -s reload'"

Conclusión

Esto concluye nuestro tutorial sobre cómo configurar Ghost CMS en su servidor basado en Ubuntu 20.04 usando Docker. Si tiene alguna pregunta o comentario, compártalos en los comentarios a continuación.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *