Inleiding
Je hebt een geweldige Laravel app naar een EC2 instance gedeployed. Nginx draait, PHP-FPM is warm, en dan — bam — je logs exploderen met:
SQLSTATE[08006] [7] connection to server at "127.0.0.1", port 5432 failed: Connection refusedFATAL: role "ec2-user" does not existSQLSTATE[42501]: Insufficient privilege: permission denied for schema publicClass "Redis" not foundofConnection refused [tcp://127.0.0.1:6379]
Als dat herkenbaar klinkt, is deze gids voor jou.
In deze uitgebreide, end-to-end tutorial laat ik je zien hoe je PostgreSQL en Redis lokaal installeert en configureert op dezelfde AWS EC2 machine die Laravel draait — en hoe je de meest voorkomende fouten kunt diagnosticeren en oplossen. Je krijgt een blauwdruk die je kunt hergebruiken voor elk project: lean, veilig en snel.
Wat je aan het eind hebt:
- Een werkende PostgreSQL 15 en Redis stack op Amazon Linux (of vergelijkbaar) met systemd services en persistentie.
- Een geharde Laravel .env die Redis voor cache/sessions/queues en PostgreSQL voor de database gebruikt.
- Een snelle troubleshooting sectie die connection refused, ontbrekende rollen, permissiefouten en PHP Redis extensieproblemen oplost.
- Praktische prestatie- en betrouwbaarheidstips: small-instance tuning, logcontroles en productiehygiëne.
Laten we beginnen.
Wat Je Nodig Hebt
- Een AWS EC2 instance (t3.micro of groter). Amazon Linux 2023 is perfect; commando's komen nauw overeen met RHEL/CentOS via
dnf. - Een security group die inkomend verkeer toestaat op 80/443 (HTTP/HTTPS) vanaf het internet en 22 (SSH) vanaf jouw IP. Open niet PostgreSQL (5432) of Redis (6379) naar het publieke internet.
- Een gedeployde Laravel codebase (Nginx + PHP-FPM) met SSH-toegang als
ec2-user(of vergelijkbaar).
Pakketten Installeren die Laravel + DB Stack Nodig Hebben
De onderstaande commando's zijn gericht op Amazon Linux 2023. Voor Ubuntu, vervang
dnfdoorapt.
# Begin altijd hier
sudo dnf -y update
# PHP & veelgebruikte extensies (pas versies aan indien nodig)
sudo dnf -y install php-cli php-fpm php-common php-opcache php-mbstring php-xml php-curl php-zip php-gd php-intl
# Postgres client + PHP extensie
sudo dnf -y install postgresql postgresql15 postgresql15-server php-pgsql
# Redis server + PHP Redis extensie
# Op Amazon Linux 2023 wordt redis meestal aangeboden als redis6 in 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 & tools
sudo dnf -y install git unzip
Waarom zowel postgresql als postgresql15*?
Op AL2023 is postgresql15 de server die je wilt. Het generieke postgresql pakket biedt client-hulpprogramma's. Als postgresql15 niet wordt gevonden, schakel dan de juiste repo in of gebruik de door het OS geleverde PostgreSQL hoofdversie.
Herstart PHP-FPM na het installeren van PHP extensies:
sudo systemctl restart php-fpm
PostgreSQL 15 Initialiseren en Starten
Initialiseer de data directory als de postgres systeemgebruiker:
# Cluster initialiseren
sudo -u postgres /usr/bin/initdb -D /var/lib/pgsql/15/data
# (Als initdb niet gevonden wordt, zoek het)
# sudo find / -type f -name initdb 2>/dev/null
# Maak een systemd service voor PG15 als je image de unit mist:
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
Als de status active (running) toont, ben je klaar.
Database, Gebruiker Aanmaken en Lokale Auth Beveiligen
Open de Postgres shell:
sudo -u postgres psql
Maak een dedicated database/gebruiker aan en ken eigenaarschap toe (dit voorkomt de gevreesde "permission denied for schema public"):
-- in 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;
-- optioneel: zorg ervoor dat toekomstige objecten standaard van de app-gebruiker zijn
ALTER DATABASE writeflow OWNER TO writeflow_user;
Beveilig lokale authenticatie om MD5 te gebruiken voor lokale TCP-verbindingen (of peer/ident als je sockets verkiest):
sudo nano /var/lib/pgsql/15/data/pg_hba.conf
Voeg toe of zorg dat deze regels bovenaan staan:
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
Herlaad PostgreSQL:
sudo systemctl restart postgresql-15
Snelle tests:
PGPASSWORD='StrongPassword123!' psql -U writeflow_user -d writeflow -h 127.0.0.1 -c "select now();"
Als dat een timestamp retourneert, is je DB-authenticatie correct.
Redis Installeren & Starten (en Persistent Maken)
# Installeren (hierboven al gedaan); starten en inschakelen
sudo systemctl enable redis
sudo systemctl start redis
sudo systemctl status redis --no-pager
# Rooktest
redis-cli ping
# Verwacht: PONG
Als je image Redis 6 levert onder een andere unit-naam (bijv. redis6), pas dan eenvoudig aan:
sudo systemctl enable redis6
sudo systemctl start redis6
sudo systemctl status redis6 --no-pager
Bind + Beveiliging: Voor alleen lokaal gebruik, bind aan 127.0.0.1 en houd protected mode aan.
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
Laravel's .env Configureren
In je app-root:
nano /var/www/your-app/.env
Gebruik deze schone basislijn voor DB en Redis:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://your-domain.com
# --- Database (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
Belangrijk: zorg ervoor dat PHP's Redis extensie geladen is. Na installatie van php-pecl-redis pikt een herstart van PHP-FPM het meestal op:
php -m | grep -i redis # moet tonen: redis
sudo systemctl restart php-fpm
Laravel App Migreren & Optimaliseren
Vanuit je app-directory:
php artisan key:generate
php artisan config:clear
php artisan cache:clear
php artisan view:clear
# Voer fresh of standaard migrate uit naar behoefte
php artisan migrate --force
Als je permission denied for schema public krijgt, voer dan de Postgres grants opnieuw uit (zie Sectie 3). Zorg er ook voor dat de database-eigenaar je app-gebruiker is en niet postgres.
Elke Veelvoorkomende Fout Oplossen (Troubleshooting Kluis)
A) SQLSTATE[08006] [7] connection to server at "127.0.0.1", port 5432 failed: Connection refused
Betekenis: De PG server luistert niet, is gecrasht of geblokkeerd.
Fix checklist:
sudo systemctl status postgresql-15 --no-pager
journalctl -xeu postgresql-15 --no-pager
ss -ltnp | grep 5432
- Als de unit inactief/gefaald is, controleer
serverlogin/var/lib/pgsql/15/data/. - Verifieer
pg_hba.confenpostgresql.conf(listen_addresses). Voor lokale TCP, zorg datlisten_addresses = 'localhost'of'*'(alleen lokaal is prima). - Zorg dat je
.envde juiste DB-naam, gebruiker en wachtwoord gebruikt.
B) FATAL: role "ec2-user" does not exist
Betekenis: Laravel probeerde te authenticeren met een Linux gebruikersnaam (gebeurt vaak als .env niet geladen is of env-caching verouderd is).
Fix:
- Verifieer
.envwaarden enphp artisan config:clear. - Bevestig dat DB-instellingen in
config/database.phpenv()gebruiken en niet hardcoded fallbacks die naarec2-userverwijzen.
C) SQLSTATE[42501]: Insufficient privilege: permission denied for schema public
Betekenis: Je app-gebruiker bezit het schema niet of mist rechten.
Fix in 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
Betekenis: PHP Redis extensie niet geladen.
Fix:
sudo dnf -y install php-pecl-redis || sudo dnf -y install php-redis
php -m | grep -i redis
sudo systemctl restart php-fpm
Zorg dat .env REDIS_CLIENT=phpredis gebruikt.
E) Redis connection refused [tcp://127.0.0.1:6379]
Betekenis: Redis service draait niet, of is gebonden aan een ander IP.
Fix:
sudo systemctl status redis --no-pager || sudo systemctl status redis6 --no-pager
redis-cli ping
ss -ltnp | grep 6379
- Als de unit down is,
sudo systemctl start redisensudo systemctl enable redis. - Zorg voor
bind 127.0.0.1in/etc/redis/redis.conf, herstart dan.
F) migrations table does not exist (terwijl je weet dat het bestaat)
Betekenis: Config cache verwijst naar verkeerde DB, of .env wordt niet gelezen.
Fix:
php artisan config:clear
php artisan cache:clear
php artisan migrate --force
Prestatiewinst voor Kleine Instances
Je hebt geen DB-beheerder nodig om out-of-memory fouten te voorkomen.
PostgreSQL (op t3.micro/t3.small):
- Houd
max_connectionsbescheiden (bijv. 100 of minder). - Gebruik redelijke shared buffers:
shared_buffers = 128MB. - Laat
effective_cache_size = 1GBop kleine machines (als het geheugen het toelaat).
PHP-FPM:
- Verlaag
pm.max_childrenom overeen te komen met RAM. Op kleine machines is 5–10 vaak voldoende.
Redis:
- Houd het alleen lokaal met
bind 127.0.0.1en standaard persistentie voor sessions/queues.
Beveiliging & Betrouwbaarheidshygiëne
-
Security Groups: Stel 5432 of 6379 nooit publiek bloot. Houd ze alleen gebonden aan 127.0.0.1.
-
Backups: Nachtelijke
pg_dumpnaar 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.gzPlan het dan in:
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
- PostgreSQL:
End-to-End Rooktest Checklist
sudo systemctl status postgresql-15→ active (running)PGPASSWORD='StrongPassword123!' psql -U writeflow_user -d writeflow -h 127.0.0.1 -c "select version();"→ retourneert versiesudo systemctl status redis(ofredis6) → active (running)redis-cli ping→ PONGphp -m | grep -i redis→ redisphp artisan migrate --force→ DONE- Login/registratie flows werken; sessies persisteren; caches warmen op.
Opsommingspunten / Snelle Samenvattingen
- Stel DB/Redis nooit bloot aan het internet. Bind aan
127.0.0.1, beveilig via security groups. - Fix "role does not exist" door ervoor te zorgen dat
.envgeladen is en de juiste DB-gebruiker is aangemaakt. - Fix "permission denied for schema public" door schema/database eigenaarschap over te dragen aan je app-gebruiker.
- Fix Redis "Class not found" door
php-pecl-rediste installeren en PHP-FPM te herstarten. - Fix Redis "Connection refused" door de Redis service in te schakelen en te starten, en te bevestigen dat het luistert op 127.0.0.1:6379.
- Vergrendel betrouwbaarheid: controleer met
systemctlenjournalctl, en maak nachtelijk backups naar S3.
Call to Action (CTA)
Wil je een beproefde deployment checklist (Nginx, PHP-FPM, SSL, Postgres, Redis) die je in je terminal kunt plakken? Heb je dit snel goed nodig? 👉 Koop mijn Fiverr gig: https://www.fiverr.com/s/DBjDz4a
FAQ (Veelgestelde Vragen)
V1) Moet ik lokale PostgreSQL/Redis gebruiken of beheerde diensten (RDS/ElastiCache)? Als je in een vroeg stadium bent of kostenbewust, is lokaal lean en snel op te zetten. Naarmate je verkeer groeit of je multi-AZ failover nodig hebt, stap over naar RDS + ElastiCache voor beheerde betrouwbaarheid en schaalbaarheid.
V2) Moet ik poort 5432 of 6379 extern openzetten? Nee. Je Laravel app verbindt lokaal. Houd beide gesloten voor het internet en gebonden aan 127.0.0.1.
V3) Hoe los ik "SQLSTATE[08006] connection refused" op, terwijl PostgreSQL draait?
Verifieer dat het luistert op 127.0.0.1:5432 (ss -ltnp | grep 5432), bevestig .env instellingen, en controleer pg_hba.conf voor lokale md5 regels. Voer tot slot php artisan config:clear uit om verouderde env-cache te wissen.
V4) Redis draait maar sessies falen nog steeds — waarom?
Bevestig dat php -m | grep -i redis de extensie toont. Zorg dat .env REDIS_CLIENT=phpredis heeft en herstart php-fpm. Verifieer ook dat storage/framework/sessions niet per ongeluk wordt gebruikt (controleer SESSION_DRIVER).
V5) Hoe voorkom ik "permission denied for schema public" op nieuwe tabellen? Na het aanmaken van de DB, stel de eigenaar in op je app-gebruiker en voer uit:
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;
Dit repareert zowel huidige als toekomstige objecten.
V6) Hoe zit het met SSL/TLS naar de database? Voor verbindingen op dezelfde host (127.0.0.1) is SSL niet nodig. Als je later de DB naar een apart instance of RDS verplaatst, schakel SSL in en beperk verbindingen via security groups.
Slotwoord
Je hebt geen enorm DevOps-budget nodig om snelle, stabiele Laravel apps op AWS te draaien. Met deze gids heb je:
- PostgreSQL 15 + Redis lokaal opgezet,
- Laravel aangesloten voor prestaties (Redis cache/sessions/queues),
- De frustrerende fouten opgelost die de meeste teams op dag één blokkeren.
Bewaar deze gids. Hergebruik hem bij je volgende lancering. En wanneer je klaar bent om te schalen, ben je al productieklaar.