APP_DEBUG=false မဖြစ်မနေထားပါ! Error detail တွေ public မထွက်နေအောင်။
APP_NAME="Codex Blog" APP_ENV=production APP_KEY=base64:... # php artisan key:generate APP_DEBUG=false # NEVER true in production APP_URL=https://your-domain.com LOG_CHANNEL=stack LOG_LEVEL=error # only log real errors DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=blog_production DB_USERNAME=blog_user DB_PASSWORD=StrongPassword123! CACHE_DRIVER=redis QUEUE_CONNECTION=redis SESSION_DRIVER=redis MAIL_MAILER=smtp MAIL_HOST=smtp.mailgun.org MAIL_PORT=587 MAIL_USERNAME=your@mailgun.com MAIL_PASSWORD=secret
# === First deploy === git clone https://github.com/you/your-app.git /var/www/your-app cd /var/www/your-app cp .env.example .env composer install --no-dev --optimize-autoloader php artisan key:generate php artisan migrate --force php artisan storage:link # symlink public/storage → storage/app/public # Optimize (cache everything) php artisan optimize # = config + route + view + event cache # === Subsequent deploys (after git pull) === git pull origin main composer install --no-dev --optimize-autoloader php artisan migrate --force php artisan optimize php artisan queue:restart # restart background workers
php artisan optimize = config:cache + route:cache + view:cache + event:cache all in one (Laravel 11)
# /etc/nginx/sites-available/laravel-app
server {
listen 80;
server_name your-domain.com www.your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com www.your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# Web root = Laravel public/ folder only!
root /var/www/your-app/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
# Security
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
location ~ /\.(env|git|htaccess) { deny all; }
# Gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript;
}
sudo ln -s /etc/nginx/sites-available/laravel-app /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo apt install certbot python3-certbot-nginx -y sudo certbot --nginx -d your-domain.com -d www.your-domain.com # Auto-renew is added to cron automatically. # Test renewal: sudo certbot renew --dry-run
# Set ownership sudo chown -R www-data:www-data /var/www/your-app # storage/ and bootstrap/cache/ must be writable by web server sudo chmod -R 775 /var/www/your-app/storage sudo chmod -R 775 /var/www/your-app/bootstrap/cache # Add yourself to www-data group (so you can edit files without sudo): sudo usermod -aG www-data $USER
sudo apt install supervisor -y # /etc/supervisor/conf.d/laravel-worker.conf [program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /var/www/your-app/artisan queue:work redis --sleep=3 --tries=3 autostart=true autorestart=true user=www-data numprocs=2 redirect_stderr=true stdout_logfile=/var/www/your-app/storage/logs/worker.log sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start laravel-worker:* # After each deploy: php artisan queue:restart
# .github/workflows/deploy.yml
name: Deploy to Server
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/your-app
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize
php artisan queue:restart
sudo systemctl reload php8.2-fpm
| Item | Command / Action | Priority |
|---|---|---|
| APP_DEBUG=false | .env setting | ⚠️ Critical |
| APP_ENV=production | .env setting | ⚠️ Critical |
| Generate APP_KEY | php artisan key:generate | Required |
| Run migrations | php artisan migrate --force | Required |
| Storage symlink | php artisan storage:link | Required |
| Optimize / cache | php artisan optimize | Recommended |
| File permissions | chmod 775 storage/ bootstrap/cache/ | Required |
| Nginx webRoot = public/ | Nginx config | ⚠️ Critical |
| HTTPS / SSL | certbot --nginx | Required |
| Queue worker | supervisor setup | If using jobs |
| DB backup schedule | mysqldump cron | Recommended |
| Error monitoring | Sentry.io / Bugsnag | Recommended |
Setup → Routes → Blade → Eloquent → CRUD → Auth + Policies → API + Sanctum → Deploy
8 Lessons — PHP → Laravel Full Stack + REST API + Production Deploy!