Deploy to Production
LaravelYour blog is complete! Now let's deploy it to a real server so the world can read it. We'll cover deployment to both Railway (cheap/easy) and AWS EC2 (production-grade).
Pre-deployment Checklist
Terminal — Final checks
# Run all tests
php artisan test
# Check for any issues
php artisan about
# Optimize for production
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
# Make sure storage is linked
php artisan storage:linkOption 1: Deploy to Railway (Easiest)
Steps
1. Push code to GitLab/GitHub
2. Go to railway.app → New Project
→ Deploy from GitHub repo
3. Add MySQL database service
→ Railway provides connection string
4. Set environment variables:
APP_ENV=production
APP_DEBUG=false
APP_KEY=(generate with: php artisan key:generate --show)
DB_CONNECTION=mysql
DB_HOST=${{MySQL.MYSQL_HOST}}
DB_PORT=${{MySQL.MYSQL_PORT}}
DB_DATABASE=${{MySQL.MYSQL_DATABASE}}
DB_USERNAME=${{MySQL.MYSQL_USER}}
DB_PASSWORD=${{MySQL.MYSQL_PASSWORD}}
5. Add start command:
php artisan migrate --force && php artisan serve --host=0.0.0.0 --port=$PORTOption 2: Deploy to AWS EC2
SSH Commands
# 1. Clone your repo
cd /var/www
sudo git clone https://gitlab.com/yourname/laravel-blog.git html
cd html
# 2. Install dependencies
sudo composer install --optimize-autoloader --no-dev
# 3. Setup environment
sudo cp .env.example .env
sudo nano .env # Edit with your production values
sudo php artisan key:generate
# 4. Run migrations
sudo php artisan migrate --force
sudo php artisan db:seed --force
# 5. Set permissions
sudo chown -R nginx:nginx /var/www/html
sudo chmod -R 755 /var/www/html/storage
sudo chmod -R 755 /var/www/html/bootstrap/cache
# 6. Create storage link
sudo php artisan storage:link
# 7. Optimize
sudo php artisan config:cache
sudo php artisan route:cache
sudo php artisan view:cache
# 8. Start services
sudo systemctl restart php-fpm nginxAuto-Deploy Script
deploy.sh
#!/bin/bash
# Save as deploy.sh — run after every update
echo "Deploying Laravel Blog..."
# Pull latest code
git pull origin main
# Install/update dependencies
composer install --optimize-autoloader --no-dev
# Run migrations
php artisan migrate --force
# Clear and rebuild cache
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan queue:restart # Restart queue workers
# Set permissions
sudo chown -R nginx:nginx storage bootstrap/cache
echo "Deploy complete!"SEO Setup
resources/views/layouts/app.blade.php (head section)
<!-- Basic SEO -->
<title>@yield('title', config('app.name'))</title>
<meta name="description" content="@yield('description', 'A Laravel blog')" />
<!-- Open Graph (for social sharing) -->
<meta property="og:title" content="@yield('title')" />
<meta property="og:description" content="@yield('description')" />
<meta property="og:image" content="@yield('og_image', asset('images/default.jpg'))" />
<meta property="og:url" content="{{ url()->current() }}" />
<!-- Canonical URL -->
<link rel="canonical" href="{{ url()->current() }}" />Sitemap for SEO
routes/web.php
<?php
Route::get('/sitemap.xml', function () {
$posts = Post::published()->latest()->get();
$categories = Category::all();
return response()->view('sitemap', compact('posts', 'categories'))
->header('Content-Type', 'application/xml');
})->name('sitemap');🎉
Congratulations! Your blog is complete! You've built a full-stack Laravel application with authentication, admin panel, CRUD, file uploads, comments, search, pagination, and deployment. This is a real production-ready project you can put on your portfolio!
💡
Next steps to improve your blog: Add RSS feed, newsletter subscription, post scheduling, image optimization, Redis caching, and analytics. Each of these is a great learning exercise!
Stuck? Need help?
Review the previous lessons or check the Laravel documentation.