Dockerizar Strapi con Postgres

Hace unos días un cliente puso sobre la mesa un proyecto en el que su equipo quería usar Strapi como CMS. Siendo sincero no he leído o escuchado mucho sobre Strapi, así que siempre, lo primero que se me ocurre es “¿cómo puedo usar docker para no llenar de cosas mi compu?”. Así que el objetivo del post es ver cómo dockerizar Strapi con Postgres (PostgreSQL).

¿Qué es Strapi?

El objetivo del post no es indagar en Strapi, pero en el futuro, cuando lo conozca más, trataré de hacer algunos posts sobre esta tecnología.

Por ahora solo diremos que es un CMS headless de código abierto y cuyo objetivo es la gestión del contenido como blogs, una tienda en línea o una app, y nos podemos conectar a ella mediante su API.

Iniciar un proyecto

Antes de iniciar debemos tener instalado lo siguiente:

Primero vamos a crearnos un proyecto de Strapi:

npx [email protected] strapi-pg-docker --quickstart
dockerizar strapi con postgres
Strapi recién instalado

Si tumbamos el proceso (ctrl + c), podemos reiniciarlo con npm run develop.

strapi crear usuario administrador
Strapi // Creación del usuario administrador

Una vez finalizado el proceso, se abrirá tu navegador y mostrará esta pantalla para que creemos nuestro usuario administrador y comenzar a usarlo.

collection type strapi

Como ya dije, no entraremos en detalle con Strapi, pero ya estamos listos para crear nuestro primer COLLECTION TYPE.

Configurar Strapi

Por ahora no hemos configurado nada, ni MySQL ni Postgres para que Strapi se conecte a una base específica. ¿Strapi instala algo? No, si vemos en la ruta config\database.js, vemos que por default, nos aparece SQLite como el motor predeterminado.

module.exports = ({ env }) => {
    const client = env('DATABASE_CLIENT', 'sqlite');

Y si vemos el archivo .env está configurado lo siguiente:

DATABASE_CLIENT=sqlite
DATABASE_FILENAME=.tmp/data.db

Nos indica que el cliente es sqlite y el archivo de la base de datos está en .tmp\data.db. Para que funcione nuestro proyecto, el archivo data.db será gestionado por el paquete better-sqlite3 que está en las dependencias de nuestro package.json.

Postgres en Docker

Como nuestro objetivo es dockerizar nuestro Strapi con PostgreSQL, tenemos que crear y configurar lo necesario. Primero vamos a crear el archivo docker-compose.yml con el siguiente contenido:

version: "3"
services:
    strapiDB:
        container_name: strapiDB
        platform: linux/amd64 #for platform error on Apple M1 chips
        restart: unless-stopped
        env_file: .env
        image: postgres:14.5-alpine
        environment:
            POSTGRES_USER: ${POSTGRES_USER}
            POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
            POSTGRES_DB: ${POSTGRES_DB}
        volumes:
            - ./volumes/postgres:/var/lib/postgresql/data
        ports:
            - "5432:5432"

Esta configuración usa la versión 14.5 de PostgresQL y vamos a montar un volumen dentro de nuestro propio directorio, al que llamaremos volumes.

También vamos a agregar al archivo .env tres variables:

POSTGRES_DB=strapidb
POSTGRES_USER=strapi
POSTGRES_PASSWORD=strapi

Y cambiar DATABASE_CLIENTde “sqlite” a “postgres“.

También vamos a editar el archivo config\database.js. Al igual que en el .env cambiaremos de “slite” a “postgres“.

module.exports = ({ env }) => {
    const client = env('DATABASE_CLIENT', 'postgres');

Ahora agregamos el paquete de Node para que nos controle la conexión con PostgreSQL.

npm install pg

Una vez instalado la librería pg podemos probar nuestro contenedor:

docker-compose up -d strapiDB
contenedor de corriendo en docker
Contenedor de PostgreSQL ejecutándose

Strapi en Docker

Para terminar de dockerizar strapi con postgresql, vamos a crear y editar algunos archivos.

Crear archivo Dockerfile

FROM node:18-alpine
# Installing libvips-dev for sharp Compatibility
RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev nasm bash vips-dev git
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}

WORKDIR /opt/
COPY package.json package-lock.json ./
RUN npm install -g node-gyp
RUN npm config set fetch-retry-maxtimeout 600000 -g && npm install
ENV PATH /opt/node_modules/.bin:$PATH

WORKDIR /opt/app
COPY . .
RUN chown -R node:node /opt/app
USER node
RUN ["npm", "run", "build"]
EXPOSE 1337
CMD ["npm", "run", "develop"]

Creamos .dockerignore:

.tmp/
.cache/
.git/
.env
build/
node_modules/
# Ignoring folders that might be used in starter templates
data/
backup/

Ahora modificarmos el docker-compose.yml:

version: "3"

services:
    strapi:
        container_name: strapi
        build:
            dockerfile: Dockerfile
        restart: unless-stopped
        env_file: .env
        environment:
            DATABASE_CLIENT: postgres
            DATABASE_HOST: strapiDB
            DATABASE_NAME: ${POSTGRES_DB}
            DATABASE_USERNAME: ${POSTGRES_USER}
            DATABASE_PORT: 5432
            JWT_SECRET: ${JWT_SECRET}
            ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET}
            DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
            NODE_ENV: development
        volumes:
            - ./volumes/public/uploads:/opt/app/public/uploads
            - ./config:/opt/app/config
            - ./src:/opt/app/src
            - ./package.json:/opt/package.json
            - ./yarn.lock:/opt/yarn.lock
        ports:
            - "1337:1337"
        depends_on:
            - strapiDB

    strapiDB:
        container_name: strapiDB
        platform: linux/amd64 #for platform error on Apple M1 chips
        restart: unless-stopped
        env_file: .env
        image: postgres:14.5-alpine
        environment:
            POSTGRES_USER: ${POSTGRES_USER}
            POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
            POSTGRES_DB: ${POSTGRES_DB}
        volumes:
            - ./volumes/postgres:/var/lib/postgresql/data
        ports:
            - "5432:5432"

NOTA: cambiamos los permisos de volumes, ya que deben ser usados por otro contenedor y nos dará error si intentamos levantar el contenedor strapi.

sudo chown -R $USER:$USER volumes 

Si no tienes a Docker ejecutándose con tus permisos de usuario, puedes darle todos los permisos:

sudo chmod 777 -R _docker_volumes

Listo, ejecutamos lo siguiente y a disfrutar 😀

docker-compose up strapi
strapi con docker-compose

Este proceso puede tardar más o menos, de acuerdo a tu red y capacidad de la máquina.

NOTA: es común ejecutar docker-compose con el switch -d para que el proceso corra en background sin que nos bloquee, pero no lo recomiendo al principio, porque en caso de error no podremos ver qué está pasando (aunque podemos ejecutar docker logs strapi) y consume en muchos casos la CPU.

comenzar a usar strapi

Abrimos el navegador y ejecutamos http://localhost:1337/. Con esto hemos terminado de dockerizar strapi con postgres.

Gracias por leer.


Posted

in

, , , , , , , ,

by