Skip to main content
Cloud & DevOps (AWS)

Guía Definitiva de DevOps: Instalar y Configurar PostgreSQL y Redis Localmente en AWS EC2 para Laravel (Solucionar Errores de Conexión Comunes)

Instala y configura PostgreSQL y Redis en AWS EC2 para Laravel. Soluciona errores de conexión comunes y configura un stack de base de datos listo para producción.

12 min
Tiempo de lectura
2,232
Palabras
Publicado
Última revisión
Engr Mejba Ahmed

Escrito por

Engr Mejba Ahmed

Compartir Artículo

Guía Definitiva de DevOps: Instalar y Configurar PostgreSQL y Redis Localmente en AWS EC2 para Laravel (Solucionar Errores de Conexión Comunes)

Introducción

Has desplegado una gran app Laravel en una instancia EC2. Nginx está funcionando, PHP-FPM está caliente, y entonces — ¡bam! — tus logs explotan con:

  • SQLSTATE[08006] [7] connection to server at "127.0.0.1", port 5432 failed: Connection refused
  • FATAL: role "ec2-user" does not exist
  • SQLSTATE[42501]: Insufficient privilege: permission denied for schema public
  • Class "Redis" not found o Connection refused [tcp://127.0.0.1:6379]

Si eso te resulta familiar, esta guía es para ti.

En este tutorial premium de principio a fin te mostraré cómo instalar y configurar PostgreSQL y Redis localmente en la misma máquina AWS EC2 que ejecuta Laravel — y cómo diagnosticar y corregir los errores más comunes que enfrentarás en el camino. Obtendrás un plano que puedes repetir para cada proyecto: limpio, seguro y rápido.

Lo que tendrás al final:

  • Un stack PostgreSQL 15 y Redis funcionando en Amazon Linux (o similar) con servicios systemd y persistencia.
  • Un Laravel .env reforzado que usa Redis para caché/sesiones/colas y PostgreSQL para la base de datos.
  • Una sección rápida de troubleshooting que resuelve connection refused, roles faltantes, errores de permisos y problemas con la extensión PHP Redis.
  • Consejos prácticos de rendimiento y confiabilidad: tuning de instancias pequeñas, verificación de logs e higiene de producción.

Empecemos.


Lo Que Necesitarás

  • Una instancia AWS EC2 (t3.micro o mayor). Amazon Linux 2023 es perfecto; los comandos coinciden estrechamente con RHEL/CentOS usando dnf.
  • Un security group que permita tráfico entrante en 80/443 (HTTP/HTTPS) desde internet y 22 (SSH) desde tu IP. No abras PostgreSQL (5432) ni Redis (6379) al internet público.
  • Una codebase Laravel desplegada (Nginx + PHP-FPM) con acceso SSH como ec2-user (o similar).

Instalar Paquetes Requeridos por Laravel + Stack de DB

Los comandos a continuación son para Amazon Linux 2023. Para Ubuntu, reemplaza dnf por apt.

# Siempre empezar aquí
sudo dnf -y update

# PHP & extensiones comunes (ajustar versiones si es necesario)
sudo dnf -y install php-cli php-fpm php-common php-opcache php-mbstring php-xml php-curl php-zip php-gd php-intl

# Cliente Postgres + extensión PHP
sudo dnf -y install postgresql postgresql15 postgresql15-server php-pgsql

# Servidor Redis + extensión PHP Redis
# En Amazon Linux 2023, redis se proporciona típicamente como redis6 en amazon-linux-extras.
sudo dnf -y install redis || true
sudo amazon-linux-extras enable redis6 || true
sudo dnf -y install redis
sudo dnf -y install php-pecl-redis || sudo dnf -y install php-redis

# Git & herramientas
sudo dnf -y install git unzip

¿Por qué tanto postgresql como postgresql15*? En AL2023, postgresql15 es el servidor que quieres. El paquete genérico postgresql proporciona utilidades de cliente. Si postgresql15 no se encuentra, habilita el repositorio correcto o usa la versión principal de PostgreSQL proporcionada por el SO.

Reinicia PHP-FPM después de instalar extensiones PHP:

sudo systemctl restart php-fpm

Inicializar e Iniciar PostgreSQL 15

Inicializa el directorio de datos como el usuario de sistema postgres:

# Inicializar cluster
sudo -u postgres /usr/bin/initdb -D /var/lib/pgsql/15/data

# (Si initdb no se encuentra, localízalo)
# sudo find / -type f -name initdb 2>/dev/null

# Crea un servicio systemd para PG15 si tu imagen carece de la unidad:
cat <<'EOF' | sudo tee /etc/systemd/system/postgresql-15.service
[Unit]
Description=PostgreSQL 15 database server
After=network.target

[Service]
Type=notify
User=postgres
ExecStart=/usr/bin/pg_ctl -D /var/lib/pgsql/15/data -l /var/lib/pgsql/15/data/serverlog start
ExecStop=/usr/bin/pg_ctl -D /var/lib/pgsql/15/data stop
ExecReload=/usr/bin/pg_ctl -D /var/lib/pgsql/15/data reload
KillMode=mixed

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable postgresql-15
sudo systemctl start postgresql-15
sudo systemctl status postgresql-15 --no-pager

Si el estado muestra active (running), estás listo.


Crear Base de Datos, Usuario y Asegurar Auth Local

Entra a la shell de Postgres:

sudo -u postgres psql

Crea una base de datos/usuario dedicado y otorga propiedad (esto evita el temido "permission denied for schema public"):

-- dentro de psql
CREATE DATABASE writeflow;
CREATE USER writeflow_user WITH ENCRYPTED PASSWORD 'StrongPassword123!';
GRANT ALL PRIVILEGES ON DATABASE writeflow TO writeflow_user;

\c writeflow
ALTER SCHEMA public OWNER TO writeflow_user;

-- opcional: asegura que los objetos futuros pertenezcan al usuario de la app
ALTER DATABASE writeflow OWNER TO writeflow_user;

Refuerza la autenticación local para usar MD5 para conexiones TCP locales (o peer/ident si prefieres sockets):

sudo nano /var/lib/pgsql/15/data/pg_hba.conf

Agrega o asegura que estas líneas estén cerca del principio:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     peer
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5

Recarga PostgreSQL:

sudo systemctl restart postgresql-15

Pruebas rápidas:

PGPASSWORD='StrongPassword123!' psql -U writeflow_user -d writeflow -h 127.0.0.1 -c "select now();"

Si eso devuelve una marca de tiempo, tu autenticación de DB es correcta.


Instalar e Iniciar Redis (y Hacerlo Persistente)

# Instalar (ya hecho arriba); iniciar y habilitar
sudo systemctl enable redis
sudo systemctl start redis
sudo systemctl status redis --no-pager

# Prueba de humo
redis-cli ping
# Esperado: PONG

Si tu imagen trae Redis 6 con un nombre de unidad diferente (ej. redis6), simplemente adapta:

sudo systemctl enable redis6
sudo systemctl start redis6
sudo systemctl status redis6 --no-pager

Bind + Seguridad: Para uso solo local, enlaza a 127.0.0.1 y mantén el modo protegido activado.

sudo sed -i 's/^#\?bind .*/bind 127.0.0.1/' /etc/redis/redis.conf || true
sudo sed -i 's/^protected-mode .*/protected-mode yes/' /etc/redis/redis.conf || true
sudo systemctl restart redis || sudo systemctl restart redis6

Configurar el .env de Laravel

En la raíz de tu app:

nano /var/www/your-app/.env

Usa esta línea base limpia para DB y Redis:

APP_ENV=production
APP_DEBUG=false
APP_URL=https://your-domain.com

# --- Base de Datos (PostgreSQL)
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=writeflow
DB_USERNAME=writeflow_user
DB_PASSWORD=

# --- Cache/Session/Queue via Redis
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis

REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

Importante: asegúrate de que la extensión Redis de PHP esté cargada. Después de instalar php-pecl-redis, un reinicio de PHP-FPM generalmente la detecta:

php -m | grep -i redis     # debería mostrar: redis
sudo systemctl restart php-fpm

Migrar y Optimizar la App Laravel

Desde tu directorio de app:

php artisan key:generate
php artisan config:clear
php artisan cache:clear
php artisan view:clear

# Ejecuta fresh o standard migrate según sea necesario
php artisan migrate --force

Si obtienes permission denied for schema public, vuelve a ejecutar los grants de Postgres (ver Sección 3). También asegúrate de que el propietario de la base de datos sea tu usuario de app y no postgres.


Corregir Cada Error Común (Bóveda de Troubleshooting)

A) SQLSTATE[08006] [7] connection to server at "127.0.0.1", port 5432 failed: Connection refused

Significado: El servidor PG no está escuchando, se cayó o está bloqueado.

Lista de verificación:

sudo systemctl status postgresql-15 --no-pager
journalctl -xeu postgresql-15 --no-pager
ss -ltnp | grep 5432
  • Si la unidad está inactiva/fallida, revisa serverlog en /var/lib/pgsql/15/data/.
  • Verifica pg_hba.conf y postgresql.conf (listen_addresses). Para TCP local, asegura listen_addresses = 'localhost' o '*' (solo local está bien).
  • Asegúrate de que tu .env use el nombre de DB, usuario y contraseña correctos.

B) FATAL: role "ec2-user" does not exist

Significado: Laravel intentó autenticarse con un nombre de usuario Linux (ocurre a menudo si .env no está cargado o el cache de env está obsoleto).

Fix:

  • Verifica los valores de .env y php artisan config:clear.
  • Confirma que las credenciales de DB en config/database.php usen env() y no fallbacks hardcodeados que apunten a ec2-user.

C) SQLSTATE[42501]: Insufficient privilege: permission denied for schema public

Significado: Tu usuario de app no es propietario del schema o carece de permisos.

Fix en psql:

\c writeflow
ALTER SCHEMA public OWNER TO writeflow_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO writeflow_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO writeflow_user;
ALTER DATABASE writeflow OWNER TO writeflow_user;

D) Class "Redis" not found

Significado: Extensión PHP Redis no cargada.

Fix:

sudo dnf -y install php-pecl-redis || sudo dnf -y install php-redis
php -m | grep -i redis
sudo systemctl restart php-fpm

Asegúrate de que .env use REDIS_CLIENT=phpredis.

E) Redis connection refused [tcp://127.0.0.1:6379]

Significado: El servicio Redis no está corriendo o está enlazado a otra IP.

Fix:

sudo systemctl status redis --no-pager || sudo systemctl status redis6 --no-pager
redis-cli ping
ss -ltnp | grep 6379
  • Si la unidad está caída, sudo systemctl start redis y sudo systemctl enable redis.
  • Asegura bind 127.0.0.1 en /etc/redis/redis.conf, luego reinicia.

F) migrations table does not exist (cuando sabes que existe)

Significado: El cache de config apunta a la DB incorrecta, o .env no se lee.

Fix:

php artisan config:clear
php artisan cache:clear
php artisan migrate --force

Ganancias de Rendimiento para Instancias Pequeñas

No necesitas un administrador de DB para evitar errores de falta de memoria.

PostgreSQL (en t3.micro/t3.small):

  • Mantén max_connections modesto (ej. 100 o menos).
  • Usa shared buffers razonables: shared_buffers = 128MB.
  • Configura effective_cache_size = 1GB en máquinas pequeñas (si la memoria lo permite).

PHP-FPM:

  • Reduce pm.max_children para coincidir con la RAM. En máquinas pequeñas, 5–10 suele ser suficiente.

Redis:

  • Mantenlo solo local con bind 127.0.0.1 y persistencia predeterminada para sesiones/colas.

Higiene de Seguridad y Confiabilidad

  • Security Groups: Nunca expongas 5432 o 6379 públicamente. Mantén ambos enlazados solo a 127.0.0.1.

  • Backups: pg_dump nocturno a S3:

    # /usr/local/bin/pg-backup.sh
    #!/usr/bin/env bash
    set -e
    TS=$(date +%F-%H%M)
    PGPASSWORD='StrongPassword123!' pg_dump -U writeflow_user -h 127.0.0.1 writeflow \
      | gzip > /tmp/writeflow-$TS.sql.gz
    aws s3 cp /tmp/writeflow-$TS.sql.gz s3://your-db-backups/
    rm -f /tmp/writeflow-$TS.sql.gz
    

    Luego prográmalo con cron:

    sudo crontab -e
    0 3 * * * /usr/local/bin/pg-backup.sh >> /var/log/pg-backup.log 2>&1
    
  • Logs:

    • PostgreSQL: /var/lib/pgsql/15/data/serverlog
    • Redis: journalctl -xeu redis
    • Nginx/PHP: /var/log/nginx/access.log, /var/log/nginx/error.log, journalctl -xeu php-fpm

Checklist de Prueba de Humo End-to-End

  1. sudo systemctl status postgresql-15 → active (running)
  2. PGPASSWORD='StrongPassword123!' psql -U writeflow_user -d writeflow -h 127.0.0.1 -c "select version();" → devuelve versión
  3. sudo systemctl status redis (o redis6) → active (running)
  4. redis-cli ping → PONG
  5. php -m | grep -i redis → redis
  6. php artisan migrate --force → DONE
  7. Los flujos de login/registro funcionan; las sesiones persisten; los cachés se calientan.

Puntos Clave / Resumen Rápido

  • Nunca expongas DB/Redis a internet. Enlaza a 127.0.0.1, asegura vía security groups.
  • Corrige "role does not exist" asegurándote de que .env esté cargado y el usuario de DB correcto esté creado.
  • Corrige "permission denied for schema public" transfiriendo la propiedad del schema/base de datos a tu usuario de app.
  • Corrige Redis "Class not found" instalando php-pecl-redis y reiniciando PHP-FPM.
  • Corrige Redis "Connection refused" habilitando e iniciando el servicio Redis, luego confirmando que escucha en 127.0.0.1:6379.
  • Asegura la confiabilidad: verifica con systemctl y journalctl, y haz backup nocturno a S3.

Llamada a la Acción (CTA)

¿Quieres una checklist de deployment probada en batalla (Nginx, PHP-FPM, SSL, Postgres, Redis) que puedas pegar en tu terminal? ¿Necesitas esto hecho bien — rápido? 👉 Compra mi gig en Fiverr: https://www.fiverr.com/s/DBjDz4a


FAQ (Preguntas Frecuentes)

P1) ¿Debería usar PostgreSQL/Redis local o servicios administrados (RDS/ElastiCache)? Si estás en etapa temprana o eres consciente de los costos, local es ligero y rápido de configurar. A medida que tu tráfico crece o necesitas failover multi-AZ, migra a RDS + ElastiCache para confiabilidad y escalado administrados.

P2) ¿Necesito abrir el puerto 5432 o 6379 externamente? No. Tu app Laravel se conecta localmente. Mantén ambos cerrados a internet y enlazados a 127.0.0.1.

P3) ¿Cómo corrijo "SQLSTATE[08006] connection refused" aunque PostgreSQL está corriendo? Verifica que esté escuchando en 127.0.0.1:5432 (ss -ltnp | grep 5432), confirma credenciales de .env, y revisa pg_hba.conf para reglas md5 locales. Finalmente, php artisan config:clear para limpiar el caché de env obsoleto.

P4) Redis está corriendo pero las sesiones siguen fallando — ¿por qué? Confirma que php -m | grep -i redis muestre la extensión. Asegura que .env tenga REDIS_CLIENT=phpredis y reinicia php-fpm. También verifica que storage/framework/sessions no se esté usando por error (revisa SESSION_DRIVER).

P5) ¿Cómo evito "permission denied for schema public" en tablas nuevas? Después de crear la DB, establece el propietario como tu usuario de app y ejecuta:

ALTER SCHEMA public OWNER TO writeflow_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO writeflow_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO writeflow_user;

Esto corrige tanto objetos actuales como futuros.

P6) ¿Qué hay del SSL/TLS hacia la base de datos? Para conexiones en el mismo host (127.0.0.1), SSL no es necesario. Si luego mueves la DB a una instancia separada o RDS, habilita SSL y restringe conexiones vía security groups.


Palabra Final

No necesitas un presupuesto DevOps enorme para ejecutar apps Laravel rápidas y estables en AWS. Con esta guía has:

  • Configurado PostgreSQL 15 + Redis localmente,
  • Conectado Laravel para rendimiento (Redis caché/sesiones/colas),
  • Resuelto los errores frustrantes que bloquean a la mayoría de los equipos en el día uno.

Guarda esta guía. Reúsala en tu próximo lanzamiento. Y cuando estés listo para escalar, ya serás production-ready.

Publicidad
Coffee cup

¿Te gustó este artículo?

Tu apoyo me ayuda a crear más contenido técnico detallado, herramientas de código abierto y recursos gratuitos para la comunidad de desarrolladores.

Temas Relacionados

Engr Mejba Ahmed

Engr Mejba Ahmed

Engr. Mejba Ahmed builds AI-powered applications and secure cloud systems for businesses worldwide. With 8+ years shipping production software in Laravel, Python, and AWS, he's helped companies automate workflows, reduce infrastructure costs, and scale without security headaches. He writes about practical AI integration, cloud architecture, and developer productivity.

Artículos Relacionados

Ver Todos

Comments

Leave a Comment

Comments are moderated before appearing.

Learning Resources

Expand Your Knowledge

Accelerate your growth with structured courses, verified certificates, interactive flashcards, and production-ready AI agent skills.

Sample Certificate of Completion

Sample certificate — complete any course to earn yours

Engr Mejba Ahmed

Engr Mejba Ahmed

AI assistant · trained on my work

👋

Hey there!

Quick Actions

WhatsApp Direct line to me

Chat on WhatsApp

+880 1723 741224 · Replies within the hour on working days

Popular Questions

Engr Mejba Ahmed is connected
Engr Mejba Ahmed is typing...
Engr Mejba Ahmed avatar

✉ Want me to follow up? Drop your email

Engr Mejba Ahmed avatar

📞 Connect Directly

Choose how you'd like to reach me

WhatsApp

+880 1723 741224

Email

mejba.13@gmail.com

✓ Details sent! I'll get back to you shortly.

Powered by OpenAI

335+

Blog Posts

25

AI Courses

63

Projects

Services & Expertise

Pricing & Process

Learning & Resources

Connect & Support