Repository navigation
🐳 v2.16.0 — داکر: کل فروشگاه در یک دستور (Docker: the whole shop in one command)
دیجیشاپ — فروشگاه آنلاین تجهیزات شبکه | Digi-Shop — Online network-equipment store
Laravel 12 · PHP 8.2+ · Bootstrap 5 RTL · MIT License
🇬🇧 English
🐳 New — Docker: the whole shop in one command
docker compose up -d --wait→ http://localhost:8080 — the full store (PHP-FPM app, nginx, MySQL 8.4) boots with one command; no PHP, no Composer, no MySQL on the host — only Docker- One image, three containers: a multi-stage
Dockerfile(composer:2 stage bakes the optimized no-dev autoloader, thenphp:8.3-fpm-alpine+ nginx) runs twice — theappservice is php-fpm, thewebservice is the same image in web role serving static files and proxying PHP toapp:9000by service name;dbis the officialmysql:8.4with a health-checked volume - The container boots through the project's own installer: the entrypoint copies
.env.docker→.env, waits for MySQL to be really ready (healthchecks + adocker/await-db.phpretry loop —depends_onalone only guarantees order), then runs the same idempotentphp artisan shop:installthe project has had since v1.0.0 — restart-safe, no duplicate data - Data survives rebuilds in the
db-dataandstorage-datavolumes; host port changeable viaDIGISHOP_PORT; admin password printed once indocker compose logs app(or setADMIN_PASSWORDin.env.docker) - Tests inside a container, zero host tooling:
docker compose run --rm testruns all 304 tests on SQLite in-memory - New
dockerjob in CI proves the image on every push and PR: build → healthcheck-gated compose up → homepage smoke test (title + seeded product) → full suite in thetestcontainer .dockerignorekeeps the image lean and excludes the machine-localpublic/storagesymlink (it would dangle in the container; the entrypoint recreates it each boot)
📊 Numbers
- Zero migrations, zero PHP code changes — the suite stays at 304 tests (1183 assertions), all green; Pint clean (163 files); Larastan level 5: 0 errors
- New files:
Dockerfile,docker-compose.yml,.dockerignore,.env.docker,docker/nginx.conf,docker/entrypoint.sh,docker/await-db.php;ci.ymlgained thedockerjob (now five jobs + coverage on main)
Seeing it in action
On any machine with Docker:
git clone https://github.com/MSS1625/shop-php.git && cd shop-php
docker compose up -d --wait # build + boot app/web/db, gated on healthchecks
# → http://localhost:8080
docker compose logs app # admin password + Laravel logs (stderr)
docker compose run --rm test # the whole 304-test suite, inside a container
docker compose down # stop (data stays) · add -v to wipeOn GitHub, after pushing this version:
- Actions → CI now shows the Docker — build & boot the full stack job beside the test matrix, Pint, Larastan and Coverage: it builds the production image, boots the whole stack with
--wait, greps the rendered homepage for the store title and a seeded product, then runs the full suite inside thetestcontainer
Quick start without Docker (unchanged)
git clone https://github.com/MSS1625/shop-php.git && cd shop-php
composer install
php artisan shop:install # env + key + migrate + seed + link (includes WELCOME10)
php artisan admin:create # interactive admin user
php artisan serve # → http://localhost:8000🇮🇷 فارسی
🐳 جدید — داکر: کل فروشگاه در یک دستور
docker compose up -d --wait→ http://localhost:8080 — کل فروشگاه (اپ PHP-FPM، nginx، MySQL 8.4) با یک دستور بالا میآید؛ بدون PHP و Composer و MySQL روی سیستم — فقط خود داکر- یک ایمیج، سه کانتینر:
Dockerfileچندمرحلهای (مرحلهٔ composer:2 که autoloader بهینهٔ بدون-dev را میپزد و بعدphp:8.3-fpm-alpine+ nginx) یکبار ساخته و دو بار استفاده میشود — سرویسappهمان php-fpm است و سرویسwebهمان ایمیج در نقش وب: فایلهای استاتیک را مستقیم میدهد و PHP را با نام سرویس بهapp:9000پاس میکند؛dbهم ایمیج رسمیmysql:8.4با volume دارای healthcheck است - کانتینر با نصبکنندهٔ خود پروژه بوت میشود: entrypoint فایل
.env.dockerرا به.envکپی میکند، برای آمادهشدن واقعی MySQL صبر میکند (healthcheckها + حلقهٔ تلاش مجددdocker/await-db.php—depends_onبهتنهایی فقط ترتیب را تضمین میکند) و بعد همانphp artisan shop:installidempotent را اجرا میکند که از v1.0.0 همراه پروژه بوده — restart بدون خطر، بدون دادهٔ تکراری - دادهها از rebuild میمانند (volumeهای
db-dataوstorage-data)؛ پورت هاست باDIGISHOP_PORTقابل تغییر است؛ رمز مدیر یکبار درdocker compose logs appچاپ میشود (یاADMIN_PASSWORDرا در.env.dockerبگذارید) - تست داخل کانتینر، بدون هیچ ابزاری روی سیستم:
docker compose run --rm testهر ۳۰۴ تست را با SQLite درونحافظه اجرا میکند - جاب جدید
dockerدر CI ایمیج را روی هر push و PR اثبات میکند: بیلد ← بوت compose با دروازهٔ healthcheckها ← اسموکتست صفحهٔ اول (عنوان + محصول seed شده) ← کل تستها در کانتینرtest .dockerignoreایمیج را سبک نگه میدارد و سیملینک محلیpublic/storageرا حذف میکند (داخل کانتینر میشکست؛ entrypoint در هر بوت میسازدش)
📊 اعداد
- صفر مایگریشن و صفر تغییر کد PHP — تستها همان ۳۰۴ تست (۱۱۸۳ ادعا)، همه سبز؛ Pint تمیز (۱۶۳ فایل)؛ لاراستان سطح ۵: صفر خطا
- فایلهای جدید:
Dockerfile،docker-compose.yml،.dockerignore،.env.docker،docker/nginx.conf،docker/entrypoint.sh،docker/await-db.php؛ جابdockerبهci.ymlاضافه شد (حالا پنج جاب + پوشش روی main)
دیدنش در عمل
روی هر سیستمی که داکر دارد:
git clone https://github.com/MSS1625/shop-php.git && cd shop-php
docker compose up -d --wait # بیلد + بوت app/web/db با دروازهٔ healthcheckها
# ← http://localhost:8080
docker compose logs app # رمز مدیر + لاگهای لاراول (روی stderr)
docker compose run --rm test # کل ۳۰۴ تست، داخل کانتینر
docker compose down # توقف (دادهها میمانند) · با -v پاک میشوندروی گیتهاب، بعد از پوش این نسخه:
- Actions → CI حالا جاب Docker — build & boot the full stack را کنار ماتریس تست، Pint، لاراستان و پوشش نشان میدهد: ایمیج production را میسازد، کل استک را با
--waitبالا میآورد، عنوان فروشگاه و یک محصول seed شده را در صفحهٔ رندرشده جستجو میکند و بعد کل تستها را داخل کانتینرtestاجرا میکند
شروع سریع بدون داکر (بدون تغییر)
git clone https://github.com/MSS1625/shop-php.git && cd shop-php
composer install
php artisan shop:install # env + کلید + مهاجرت + داده اولیه + لینک
php artisan admin:create # ساخت مدیر (تعاملی)
php artisan serve # → http://localhost:8000