--- title: "Instalar Strapi 5 con PostgreSQL y Nginx en Ubuntu 24.04" description: "Instala Strapi 5 en Ubuntu 24.04 con Node.js 22 y PostgreSQL, ejecútalo como servicio systemd y publícalo tras Nginx con HTTPS de Let's Encrypt." category: "E-commerce y CMS" language: es source: https://cubepath.com/es/docs/e-commerce-y-cms/instalacion-de-strapi-cms-headless updated: 2026-09-25 --- # Instalar Strapi 5 con PostgreSQL y Nginx en Ubuntu 24.04 Strapi es un CMS headless de código abierto escrito en Node.js: gestionas el contenido desde un panel de administración y lo sirves a cualquier frontend (web, app móvil) a través de una API REST o GraphQL. En este tutorial instalarás Strapi 5 en Ubuntu 24.04 con Node.js 22 y PostgreSQL, lo ejecutarás en modo producción como servicio systemd y lo publicarás detrás de Nginx con un certificado HTTPS de Let's Encrypt. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 2 GB de RAM. La compilación del panel de administración consume bastante memoria; con 1 GB necesitarás swap. - Un usuario no root con privilegios `sudo`. - Un dominio con un registro DNS A que apunte a la IP del servidor. En esta guía se usa `tu_dominio`. - UFW permitiendo SSH, si tienes el cortafuegos activado. ## Paso 1: Instalar Node.js 22 Strapi 5 necesita una versión LTS activa de Node.js. Los repositorios de Ubuntu 24.04 traen Node.js 18, que ya no está soportado, así que instala Node.js 22 desde el repositorio oficial de NodeSource. Descarga la clave del repositorio en `/etc/apt/keyrings`: ```bash sudo apt update sudo apt install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg ``` Añade el repositorio de Node.js 22 e instala el paquete: ```bash echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list sudo apt update sudo apt install nodejs ``` Comprueba las versiones: ```bash node -v npm -v ``` ```output v22.x.x 10.x.x ``` ## Paso 2: Instalar PostgreSQL y crear la base de datos Strapi funciona con SQLite por defecto, pero para producción conviene PostgreSQL. Instálalo desde los repositorios de Ubuntu (versión 16): ```bash sudo apt install postgresql ``` Crea un usuario de base de datos llamado `strapi`. El comando te pedirá la contraseña dos veces; elige una contraseña segura y guárdala, la usarás en el paso siguiente: ```bash sudo -u postgres createuser --pwprompt strapi ``` Crea la base de datos con `strapi` como propietario: ```bash sudo -u postgres createdb -O strapi strapi ``` Comprueba que puedes conectarte con ese usuario por TCP, que es como lo hará Strapi: ```bash psql -h 127.0.0.1 -U strapi -d strapi -c 'SELECT current_user;' ``` ```output current_user -------------- strapi (1 row) ``` ## Paso 3: Crear el proyecto de Strapi Crea un usuario de sistema sin privilegios para la aplicación y cambia a él: ```bash sudo useradd -m -s /bin/bash strapi sudo -iu strapi ``` Genera el proyecto con `create-strapi`. Las opciones indican que no quieres usar Strapi Cloud, que la base de datos es PostgreSQL y que no arranque el servidor al terminar. Sustituye `tu_contraseña_db` por la contraseña del paso 2: ```bash npx create-strapi@latest cms --skip-cloud --use-npm --no-run \ --dbclient=postgres --dbhost=127.0.0.1 --dbport=5432 \ --dbname=strapi --dbusername=strapi --dbpassword=tu_contraseña_db ``` El asistente hará algunas preguntas que no cubren las opciones, como si quieres datos de ejemplo, TypeScript o inicializar un repositorio Git. Para esta guía, responde **No** a los datos de ejemplo; lo demás a tu gusto. Al terminar tendrás el proyecto en `/home/strapi/cms`, con las dependencias instaladas y un archivo `.env` con claves aleatorias (`APP_KEYS`, `ADMIN_JWT_SECRET`, `JWT_SECRET`, etc.) y los datos de conexión a la base de datos. Comprueba el `.env`: ```bash cd ~/cms grep -E '^(HOST|PORT|DATABASE_CLIENT|DATABASE_NAME)=' .env ``` ```output HOST=0.0.0.0 PORT=1337 DATABASE_CLIENT=postgres DATABASE_NAME=strapi ``` > Importante: el `.env` contiene los secretos de la instancia. No lo subas a ningún repositorio y haz copia de él, porque sin `APP_KEYS` y los demás secretos no podrás descifrar sesiones ni tokens existentes. ## Paso 4: Configurar Strapi para producción detrás de un proxy Strapi solo tiene que escuchar en local, porque Nginx recibirá las peticiones públicas. Cambia `HOST` en el `.env` y añade la URL pública: ```bash nano ~/cms/.env ``` ```ini HOST=127.0.0.1 PORT=1337 PUBLIC_URL=https://tu_dominio ``` Ahora indica a Strapi su URL pública y que confíe en las cabeceras del proxy. Edita el archivo de configuración del servidor (`config/server.ts` si elegiste TypeScript, `config/server.js` si elegiste JavaScript): ```bash nano ~/cms/config/server.ts ``` ```typescript export default ({ env }) => ({ host: env('HOST', '0.0.0.0'), port: env.int('PORT', 1337), url: env('PUBLIC_URL', 'http://localhost:1337'), proxy: { koa: true }, app: { keys: env.array('APP_KEYS'), }, }); ``` En la versión JavaScript el contenido es el mismo, con `module.exports =` en lugar de `export default`. Compila el panel de administración en modo producción. Tarda uno o dos minutos: ```bash NODE_ENV=production npm run build ``` Cuando termine, vuelve a tu usuario con sudo: ```bash exit ``` ## Paso 5: Ejecutar Strapi con systemd Una unidad systemd arranca Strapi con el sistema, lo reinicia si falla y envía sus logs al journal. Crea el archivo: ```bash sudo nano /etc/systemd/system/strapi.service ``` ```ini [Unit] Description=Strapi CMS After=network.target postgresql.service Requires=postgresql.service [Service] Type=simple User=strapi Group=strapi WorkingDirectory=/home/strapi/cms Environment=NODE_ENV=production ExecStart=/usr/bin/npm run start Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target ``` Arranca el servicio y actívalo al inicio: ```bash sudo systemctl daemon-reload sudo systemctl enable --now strapi sudo systemctl status strapi --no-pager ``` Strapi expone un endpoint de salud que responde `204 No Content` cuando está listo: ```bash curl -I http://127.0.0.1:1337/_health ``` ```output HTTP/1.1 204 No Content ``` Si no responde, revisa el log con `sudo journalctl -u strapi -n 50`. ## Paso 6: Configurar Nginx y HTTPS Instala Nginx y Certbot con su plugin para Nginx: ```bash sudo apt install nginx certbot python3-certbot-nginx ``` Crea un bloque de servidor para Strapi: ```bash sudo nano /etc/nginx/sites-available/strapi ``` ```nginx server { listen 80; listen [::]:80; server_name tu_dominio; client_max_body_size 50M; location / { proxy_pass http://127.0.0.1:1337; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } ``` `client_max_body_size` permite subir archivos de hasta 50 MB a la biblioteca de medios; Nginx limita a 1 MB por defecto. Activa el sitio, comprueba la sintaxis y recarga: ```bash sudo ln -s /etc/nginx/sites-available/strapi /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` Abre HTTP y HTTPS en el cortafuegos y solicita el certificado. Certbot modifica el bloque de servidor para usar HTTPS y redirigir HTTP: ```bash sudo ufw allow 'Nginx Full' sudo certbot --nginx -d tu_dominio ``` Comprueba que el sitio responde por HTTPS: ```bash curl -I https://tu_dominio/_health ``` ```output HTTP/2 204 ``` ## Paso 7: Crear el administrador y probar la API Abre `https://tu_dominio/admin` en el navegador. La primera vez Strapi muestra un formulario para crear el primer usuario administrador; hazlo cuanto antes, porque cualquiera que llegue a esa URL antes que tú podría registrarlo. > Nota: en modo producción el **Content-Type Builder** es de solo lectura. Los tipos de contenido se crean en un entorno de desarrollo (`npm run develop` en tu equipo), se guardan como archivos en `src/api/` y se despliegan copiando el código al servidor y repitiendo `npm run build` y `sudo systemctl restart strapi`. El contenido en sí sí se edita en producción desde el **Content Manager**. Para acceder a la API desde un frontend o un script, crea un token en **Settings > API Tokens > Create new API Token**, con tipo **Read-only**. Copia el token, porque solo se muestra una vez, y úsalo en la cabecera `Authorization`. Por ejemplo, si tu proyecto tiene un tipo de colección `article`: ```bash curl -H "Authorization: Bearer tu_token_api" https://tu_dominio/api/articles ``` ```output {"data":[...],"meta":{"pagination":{"page":1,"pageSize":25,"pageCount":1,"total":3}}} ``` Si prefieres que un tipo de contenido sea público sin token, concede los permisos `find` y `findOne` al rol **Public** en **Settings > Users & Permissions plugin > Roles**. ## Paso 8: Copias de seguridad Lo que necesitas guardar es la base de datos, los archivos subidos (`/home/strapi/cms/public/uploads`) y el `.env`. Haz un volcado de la base de datos con `pg_dump` como el usuario `postgres`: ```bash sudo mkdir -p /var/backups/strapi sudo -u postgres pg_dump -Fc strapi | sudo tee /var/backups/strapi/strapi-$(date +%F).dump > /dev/null sudo tar -czf /var/backups/strapi/uploads-$(date +%F).tar.gz -C /home/strapi/cms public/uploads .env ls -lh /var/backups/strapi ``` Programa esos comandos con cron o un temporizador systemd y copia el directorio fuera del servidor. Para restaurar la base de datos usa `pg_restore -d strapi`. ## Solución de problemas - **`npm run build` termina con "JavaScript heap out of memory" o el proceso muere.** El servidor no tiene RAM suficiente para compilar el panel. Añade un archivo de swap de 2 GB o amplía la RAM del servidor y repite la compilación. - **El servicio falla con errores de conexión a la base de datos.** Revisa `DATABASE_HOST`, `DATABASE_USERNAME` y `DATABASE_PASSWORD` en el `.env` y repite la prueba con `psql` del paso 2. - **El panel carga pero las URLs apuntan a `localhost` o a HTTP.** Falta `PUBLIC_URL` en el `.env` o `url` en la configuración del servidor. Corrígelo y vuelve a ejecutar `npm run build` antes de reiniciar. - **Nginx devuelve 502 Bad Gateway.** Strapi no está escuchando en `127.0.0.1:1337`. Comprueba `sudo systemctl status strapi` y el journal. - **Error 413 al subir archivos.** Aumenta `client_max_body_size` en el bloque de Nginx y recárgalo. ## Conclusión Ya tienes Strapi 5 en producción en Ubuntu 24.04, con PostgreSQL, gestionado por systemd y publicado por HTTPS detrás de Nginx. Como siguientes pasos, puedes definir tus tipos de contenido en local y desplegarlos al servidor, instalar el plugin de GraphQL si tu frontend lo prefiere, o mover la biblioteca de medios a un almacenamiento compatible con S3 mediante un proveedor de subida.