Rozdział 1: Instalacja i konfiguracja
Witaj w tutorialu budowy sklepu internetowego na Symfony 8. To nie sklep „pod jeden produkt”, tylko uniwersalna platforma e-commerce, którą najpierw doprowadzimy do stanu wdrażalnego, a potem rozwiniemy kolejnymi rozdziałami — bez przebudowy schematu bazy. Budujemy ją stopniowo, w ośmiu częściach:
- Część I — Sklep działający lokalnie (rozdziały 1–12): fundament (User), katalog, koszyk, checkout, zamówienia i panel admina. Po niej masz działający sklep w klasycznym Symfony (Twig + Turbo).
- Część II — Wdrożenie na żywo (13–17): płatności, CMS, SEO, wydajność i deploy. Po niej sklep jest wdrażalny i sprzedaje.
- Część III — Front reaktywny (18–22): przepisanie koszyka i filtrów na Vue 3 + Pinia i porównanie obu podejść.
- Część IV — Uniwersalny model produktu (23–29): atrybuty (EAV), typy produktu, tagi, opinie, wishlist.
- Część V — Magazyn i zaopatrzenie (30–32): wiele magazynów, ruchy magazynowe, dostawcy.
- Część VI — Płatności, dostawy, zwroty, promocje (33–36): kolejni operatorzy, kurierzy, RMA, promocje.
- Część VII — Umiędzynarodowienie (37–39): wielojęzyczność, waluty i stawki VAT, multi-store.
- Część VIII — Integracje, bezpieczeństwo, jakość (40–46): API, integracje, produkty cyfrowe, bezpieczeństwo i testy.
Tutorial jest tak pomyślany, byś mógł zatrzymać się po dowolnej części i mieć spójny rezultat. Kluczowe kamienie milowe to koniec Części I (sklep działa lokalnie) i Części II (sklep da się wdrożyć).
Dziś przygotujemy środowisko i poznamy konwencje, których będziemy się trzymać.
Jak zbudowany jest ten tutorial: każdy rozdział to praktyczny krok, który kończy się sprawdzalnym efektem. Kod jest kompletny i gotowy do wklejenia — możesz go odtworzyć u siebie krok po kroku.
Stack
Sklep stoi na tym samym, nowoczesnym stacku co cały projekt:
| Warstwa | Technologia |
|---|---|
| Framework | Symfony 8.0 / PHP 8.4 |
| Baza danych | PostgreSQL 16 przez Doctrine ORM 3 |
| Szablony | Twig 3 |
| Frontend | Vite + Stimulus + Turbo (Symfony UX) |
| Front reaktywny | Vue 3 + Pinia + TypeScript (Część III) |
| Paginacja | Pagerfanta |
| Płatności | Stripe przez abstrakcję bramek (Część II) |
| Kolejki | Symfony Messenger — maile i zdarzenia async |
| Cache | Redis (Część II) |
| API | REST + NelmioApiDoc (Swagger /api/doc, Część VIII) |
| Środowisko | pełny Docker (PHP-FPM, Nginx, PostgreSQL, Mailpit, worker) |
Świadomie nie używamy gotowych „silników sklepowych” (Sylius, PrestaShop) ani „generatorów panelu” (EasyAdmin, Sonata) — katalog, koszyk, panel i API piszemy ręcznie, żeby mieć pełną kontrolę i pokazać, jak e-commerce działa pod spodem. To także sedno projektu: uniwersalny model, który rozwijasz modułami.
Uruchomienie środowiska
Całość działa w Dockerze — nie musisz instalować PHP ani PostgreSQL lokalnie. Do zarządzania służy make:
make start # zbuduj obrazy i wystartuj kontenery
make db-init # migracje + dane testowe (fixtures)
Po chwili narzędzia środowiska są dostępne pod:
| Usługa | URL |
|---|---|
| Aplikacja | http://localhost:8090 |
| Web Profiler | http://localhost:8090/_profiler |
| Mailpit (podgląd maili) | http://localhost:8025 |
| Adminer (GUI bazy) | http://localhost:8091 |
Sklep (/shop) i dokumentacja API (/api/doc) pojawią się dopiero, gdy zbudujemy odpowiednie warstwy —
katalog produktów w Rozdziale 7, a API w Części VIII.
Polecenia konsoli Symfony uruchamiamy w kontenerze app:
docker compose exec app php bin/console <komenda>
Maile zamówień idą przez kolejkę, więc w tle chodzi worker Messengera:
docker compose up -d worker # uruchom worker kolejki
docker compose logs -f worker # podgląd przetwarzania
Restart środowiska po zatrzymaniu:
make stop && make fast && make db-init
Struktura projektu
Kod sklepu rozłożymy według warstw — tak samo jak w pozostałych modułach projektu. Docelowa mapa najważniejszych katalogów (część z nich powstanie w kolejnych rozdziałach):
src/
├── Controller/ # kontrolery webowe (Twig) — CatalogController, CartController, CheckoutController
│ └── Admin/ # panel admina — OrderAdminController, ProductAdminController
├── Api/ # warstwa REST API (Część VIII)
│ ├── Controller/ # ShopApiController…
│ └── Dto/ # ProductDto, CartDto, OrderDto
├── Entity/ # encje Doctrine — Product, ProductVariant, Category, Order, OrderItem…
├── Form/ # typy formularzy — CheckoutType, ProductType…
├── Repository/ # repozytoria Doctrine — ProductRepository…
├── Service/ # logika biznesowa — Cart, PriceCalculator, PaymentGateway…
├── Message/ # komunikaty async — OrderConfirmationMessage
└── MessageHandler/ # handlery kolejki — wysyłka maila zamówienia
templates/
├── shop/ # front sklepu — catalog, product, cart, checkout
└── admin/shop/ # panel admina
assets/
└── vue/controllers/ # komponenty Vue (front reaktywny — Część III)
Nie buduj tego wszystkiego naraz — encje i katalogi rosną przyrostowo. W każdym rozdziale dokładamy tylko to, co jest w nim potrzebne, tak by aplikacja po każdym kroku dawała się uruchomić.
Konwencje projektu
Trzy zasady, które przewijają się przez cały tutorial — warto je zapamiętać od początku:
- Dwie warstwy kontrolerów.
src/Controller/renderuje szablony Twig (front sklepu i panel admina).src/Api/Controller/zwraca JSON. To rozdzielenie utrzymujemy konsekwentnie. - W API nigdy nie serializujemy encji Doctrine. Zawsze zwracamy DTO (
ProductDto::fromEntity). Dzięki temu kształt odpowiedzi API jest niezależny od modelu bazy (Część VIII). - Katalog, koszyk i panel piszemy ręcznie. Zwykły CRUD na formularzach Symfony, koszyk w sesji, płatności za abstrakcją bramki — bez gotowych silników i generatorów.
Płatności online, produkty cyfrowe, wielojęzyczność, API oraz testy i deploy dokładamy w kolejnych częściach, jako rozszerzenia — podstawowy sklep z Części I działa bez nich.
Uniwersalność od początku. Model projektujemy tak, by ten sam schemat obsłużył książki, elektronikę, ubrania czy kursy online. Sercem tego podejścia są warianty (osobny SKU, cena i stan) oraz atrybuty EAV (Część IV) — dzięki nim nowe typy produktów dodajemy bez zmian w tabelach.
Weryfikacja
Sprawdź, że środowisko stoi:
docker compose ps # kontenery w stanie "running"
docker compose exec app php bin/console about # wersja Symfony/PHP
Wejdź na http://localhost:8090 — powinna pojawić się strona startowa aplikacji (bez błędu 500). To Twój
działający stan po tym rozdziale: uruchomione środowisko. Sklep (/shop) zbudujemy dopiero od
Rozdziału 7, a użytkowników testowych (klient, admin) — w Rozdziale 2.
Zasada tutoriala: każdy rozdział kończy się czymś działającym, co możesz sprawdzić, zanim przejdziesz dalej. Dzięki temu sklep rośnie krok po kroku, a każdy krok da się dołożyć osobno.
Podsumowanie
Środowisko gotowe, konwencje ustalone:
- ✅ stack: Symfony 8 / PHP 8.4 / PostgreSQL 16 / Docker, front na Vite (Vue 3 w Części III), płatności Stripe, kolejki Messenger, cache Redis,
- ✅ uruchomienie przez
make start+make db-init, aplikacja podlocalhost:8090, worker kolejki w tle, - ✅ struktura
src/(dwie warstwy kontrolerów,Api/Dto,Entity,Repository,Service,Message), - ✅ trzy konwencje: dwie warstwy kontrolerów, DTO w API, ręczny CRUD (bez gotowych silników sklepowych i generatorów panelu),
- ✅ plan na 8 części z kamieniami milowymi: koniec Części I (sklep działa lokalnie) i Części II (wdrażalny).
W Rozdziale 2 zbudujemy fundament — encję User z rolami (customer, admin, employee),
bezpieczeństwo na natywnym Security Bundle i użytkowników testowych, na których opiera się cały sklep
(konto klienta, składanie zamówień, panel admina).