Cómo instalar Ghost CMS con Docker en Ubuntu 20.04

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.
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.
Aquí, se le pedirá que cree su cuenta de administrador y elija un título de blog.
Anuncio 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.
Al final de la configuración, aparecerá el panel de administración de Ghost.
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.
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.