Pourquoi Deployer Laravel sur Railway ?
Deployer Laravel sur Railway permet aux développeurs d'expédier rapidement leurs applications Laravel en production sans se soucier de la gestion des serveurs et des environnements. Cela offre une solution rapide, fiable et économique pour le déploiement en ligne.
Un cas concret serait de développer un blog pour une entreprise locale. En utilisant Railway, le développeur peut déployer rapidement son application sur Internet, permettant aux visiteurs de consulter le blog à partir d'importe part du monde.
Prerequis
Voici la liste des connaissances et outils nécessaires avant de commencer :
- Connaissance approfondie de Laravel (version 8 ou plus tard)
- Connaissances en gestion de base de données
- Comptes sur Railway, GitHub et Git
- Outils d'éditeur de code (ex: Visual Studio Code)
Outils à installer :
- Node.js : Version 14.x
- Composer : Version 2.x
- Git : Dernière version
Concepts fondamentaux
Création du Projet Laravel
Commencez par créer un nouveau projet Laravel en utilisant Composer :
composer create-project --prefer-dist laravel/laravel my-laravel-app
Cela créera une nouvelle application Laravel dans le répertoire my-laravel-app.
Configuration de la Base de Données
Ouvrez le fichier .env et configurez vos paramètres de base de données :
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_database
DB_USERNAME=root
DB_PASSWORD=
Création d'une Migration
Créez une migration pour la table des utilisateurs :
php artisan make:migration create_users_table --create=users
Editez le fichier de migration dans database/migrations et ajoutez les champs nécessaires :
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
}
Ensuite, exécutez la migration :
php artisan migrate
Création d'un Contrôleur et une Vue
Créez un contrôleur pour les utilisateurs :
php artisan make:controller UserController --resource
Editez le fichier app/Http/Controllers/UserController.php pour ajouter des actions :
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
$users = User::all();
return view('users.index', compact('users'));
}
public function create()
{
return view('users.create');
}
public function store(Request $request)
{
User::create($request->validate([
'name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required|min:8'
]));
return redirect()->route('users.index');
}
public function show(User $user)
{
return view('users.show', compact('user'));
}
public function edit(User $user)
{
return view('users.edit', compact('user'));
}
public function update(Request $request, User $user)
{
$user->update($request->validate([
'name' => 'required',
'email' => 'required|email|unique:users,' . $user->id,
'password' => 'nullable|min:8'
]));
return redirect()->route('users.index');
}
public function destroy(User $user)
{
$user->delete();
return redirect()->route('users.index');
}
}
Créez les vues correspondantes dans resources/views/users :
index.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Users</h1>
<a href="route('users.create')" class="btn btn-primary">Create User</a>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach($users as $user)
<tr>
<td>$user->id</td>
<td>$user->name</td>
<td>$user->email</td>
<td>
<a href="route('users.edit', $user)" class="btn btn-warning">Edit</a>
<form action="route('users.destroy', $user)" method="POST" style="display: inline-block;">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endsection
create.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Create User</h1>
<form action="route('users.store')" method="POST">
@csrf
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" name="name" id="name" class="form-control" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" name="email" id="email" class="form-control" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" name="password" id="password" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary">Create User</button>
</form>
</div>
@endsection
edit.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Edit User</h1>
<form action="route('users.update', $user)" method="POST">
@csrf
@method('PUT')
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" name="name" id="name" class="form-control" value="$user->name" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" name="email" id="email" class="form-control" value="$user->email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" name="password" id="password" class="form-control" placeholder="Leave empty if not changing">
</div>
<button type="submit" class="btn btn-primary">Update User</button>
</form>
</div>
@endsection
Mise en pratique : projet fil rouge
Étape 1 : Initialisation du Projet
Créez un nouveau projet Laravel :
composer create-project --prefer-dist laravel/laravel task-manager
cd task-manager
Étape 2 : Création de la Migration pour les Tâches
Créez une migration pour la table des tâches :
php artisan make:migration create_tasks_table --create=tasks
Editez le fichier database/migrations et ajoutez les champs nécessaires :
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTasksTable extends Migration
{
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description')->nullable();
$table->boolean('completed')->default(false);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('tasks');
}
}
Ensuite, exécutez la migration :
php artisan migrate
Étape 3 : Création d'un Contrôleur et des Vues
Créez un contrôleur pour les tâches :
php artisan make:controller TaskController --resource
Editez le fichier app/Http/Controllers/TaskController.php pour ajouter des actions :
use App\Models\Task;
use Illuminate\Http\Request;
class TaskController extends Controller
{
public function index()
{
$tasks = Task::all();
return view('tasks.index', compact('tasks'));
}
public function create()
{
return view('tasks.create');
}
public function store(Request $request)
{
Task::create($request->validate([
'title' => 'required',
'description' => 'nullable'
]));
return redirect()->route('tasks.index');
}
public function show(Task $task)
{
return view('tasks.show', compact('task'));
}
public function edit(Task $task)
{
return view('tasks.edit', compact('task'));
}
public function update(Request $request, Task $task)
{
$task->update($request->validate([
'title' => 'required',
'description' => 'nullable'
]));
return redirect()->route('tasks.index');
}
public function destroy(Task $task)
{
$task->delete();
return redirect()->route('tasks.index');
}
}
Créez les vues correspondantes dans resources/views/tasks :
index.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Tasks</h1>
<a href="route('tasks.create')" class="btn btn-primary">Create Task</a>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Description</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach($tasks as $task)
<tr>
<td>$task->id</td>
<td>$task->title</td>
<td>Str::limit($task->description, 100)</td>
<td>$task->completed ? 'Completed' : 'Pending'</td>
<td>
<a href="route('tasks.edit', $task)" class="btn btn-warning">Edit</a>
<form action="route('tasks.destroy', $task)" method="POST" style="display: inline-block;">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endsection
create.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Create Task</h1>
<form action="route('tasks.store')" method="POST">
@csrf
<div class="mb-3">
<label for="title" class="form-label">Title</label>
<input type="text" name="title" id="title" class="form-control" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea name="description" id="description" class="form-control"></textarea>
</div>
<button type="submit" class="btn btn-primary">Create Task</button>
</form>
</div>
@endsection
edit.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Edit Task</h1>
<form action="route('tasks.update', $task)" method="POST">
@csrf
@method('PUT')
<div class="mb-3">
<label for="title" class="form-label">Title</label>
<input type="text" name="title" id="title" class="form-control" value="$task->title" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea name="description" id="description" class="form-control">$task->description</textarea>
</div>
<button type="submit" class="btn btn-primary">Update Task</button>
</form>
</div>
@endsection
Étape 4 : Configuration de la Base de Données
Ouvrez le fichier .env et configurez vos paramètres de base de données :
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_database
DB_USERNAME=root
DB_PASSWORD=
Étape 5 : Lancement du Serveur Local
Lancez le serveur local pour tester votre application :
php artisan serve
Allez sur http://localhost:8000/tasks et vous devriez voir la liste des tâches.
Erreurs fréquentes et debugging
Erreur 1 : Class 'App\Models\Task' not found
Code incorrect :
use App\Models\Task;
class TaskController extends Controller
{
public function index()
{
$tasks = Task::all();
return view('tasks.index', compact('tasks'));
}
}
Code correct :
use App\Models\Task;
class TaskController extends Controller
{
public function index()
{
$tasks = Task::all();
return view('tasks.index', compact('tasks'));
}
}
Erreur 2 : syntax error, unexpected token "endwhile"
Code incorrect :
@foreach($tasks as $task)
<tr>
<td>$task->id</td>
<td>$task->title</td>
<td>Str::limit($task->description, 100)</td>
<td>$task->completed ? 'Completed' : 'Pending'</td>
<td>
<a href="route('tasks.edit', $task)" class="btn btn-warning">Edit</a>
<form action="route('tasks.destroy', $task)" method="POST" style="display: inline-block;">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
@endwhile
Code correct :
@foreach($tasks as $task)
<tr>
<td>$task->id</td>
<td>$task->title</td>
<td>Str::limit($task->description, 100)</td>
<td>$task->completed ? 'Completed' : 'Pending'</td>
<td>
<a href="route('tasks.edit', $task)" class="btn btn-warning">Edit</a>
<form action="route('tasks.destroy', $task)" method="POST" style="display: inline-block;">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
@endforeach
Erreur 3 : MethodNotAllowedHttpException in RouteCollection.php line 250
Code incorrect :
<form action="route('tasks.update', $task)" method="POST">
@csrf
<button type="submit" class="btn btn-primary">Update Task</button>
</form>
Code correct :
<form action="route('tasks.update', $task)" method="POST">
@csrf
@method('PUT')
<button type="submit" class="btn btn-primary">Update Task</button>
</form>
Pour aller plus loin
Vous pouvez ajouter des fonctionnalités supplémentaires à votre application, comme la possibilité de marquer les tâches comme terminées ou d'ajouter des commentaires. Vous pouvez également améliorer l'interface utilisateur en utilisant des bibliothèques CSS et JavaScript.
N'oubliez pas de tester vos modifications pour vous assurer qu'elles fonctionnent correctement. Vous pouvez utiliser les outils de débogage intégrés dans votre éditeur de code ou utiliser des outils en ligne comme php artisan tinker pour tester des requêtes directement dans la console.