Files
tripz-llc/docker/docker-compose.yml
2026-08-09 16:56:13 +03:00

263 lines
10 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ============================================================
# تربز في حاويات — نسخة واحدة كاملة على سيرفر واحد
# ============================================================
# المبدأ: التقسيم بالدور (nginx / fpm / سوكيتات / mysql / redis)
# لا حاوية-واحدة-فيها-كل-شيء، ولا تفتيت microservices.
# الأداء = نفس العمليات على نفس النواة؛ الفرق تشغيلي فقط.
#
# التشغيل: docker compose up -d --build (انظر README.md)
#
# البورتات: تربز تستضيف على نفس سيرفر نسخ أخرى (siro/intaleq)،
# فكل منفذ هنا مخصص لتربز ولا يتصادم معها:
# HTTP 8183 · driver 12022 · passenger 13033 · food 14042
# mysql 33063 · phpmyadmin 8084 · coturn 3479 (UDP 49301–49400)
# ============================================================
name: tripz-core
services:
nginx:
image: nginx:1.27-alpine
ports:
- "${HTTP_PORT:-8183}:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
- ../backend:/var/www/backend:ro
- ../payment_server/v2:/var/www/v2:ro
- ../loction_server:/var/www/loction_server:ro
- ../dashboard:/var/www/dashboard:ro
depends_on:
- php
- php_transit
- php_food
mem_limit: 256m
restart: unless-stopped
# php-fpm واحدة تخدم كل الخدمات الطلبية (backend + payment v2)
# التقسيم لأبعد من هذا لا يضيف أداءً — نفس الصورة، نفس النواة.
php:
build:
context: ..
dockerfile: docker/php/Dockerfile.fpm
args:
PHP_VERSION: "${PHP_VERSION:-8.2}"
volumes:
- ../backend:/var/www/backend
- ../payment_server/v2:/var/www/v2
- ../loction_server:/var/www/loction_server
- ./php/opcache.ini:/usr/local/etc/php/conf.d/zz-opcache.ini:ro
- ./php/php-prod.ini:/usr/local/etc/php/conf.d/zz-prod.ini:ro
- ./php/www-pool.conf:/usr/local/etc/php-fpm.d/zz-pool.conf:ro
- ./keys:/keys:ro
env_file: .env
depends_on:
- mysql
- redis
mem_limit: 2g
restart: unless-stopped
# php-fpm معزولة لتخدم المواصلات (transit) — حاوية مستقلة عن الباك إند الرئيسي.
# المشترك الوحيد مع النظام الأساسي: JWT والمصادقة والرحلات الداخلية عبر backend/core
# (نُركّبها read-only)، ونفس mysql/redis. لا صلة بـ backend الرئيسي ولا payment v2.
php_transit:
build:
context: ..
dockerfile: docker/php/Dockerfile.fpm.transit
args:
PHP_VERSION: "${PHP_VERSION:-8.2}"
volumes:
- ../backend/core:/var/www/backend/core:ro
- ../backend/functions.php:/var/www/backend/functions.php:ro
# نفس سبب php_food: JwtService يحتاج Firebase\JWT من backend/vendor،
# والصورة بلا composer. للقراءة فقط.
- ../backend/vendor:/var/www/backend/vendor:ro
- ../backend/transit:/var/www/backend/transit
- ./php/opcache.ini:/usr/local/etc/php/conf.d/zz-opcache.ini:ro
- ./php/php-prod.ini:/usr/local/etc/php/conf.d/zz-prod.ini:ro
- ./php/www-pool.transit.conf:/usr/local/etc/php-fpm.d/zz-pool.conf:ro
- ./keys:/keys:ro
env_file: .env
depends_on:
- mysql
- redis
mem_limit: 512m
restart: unless-stopped
# php-fpm معزولة لوحدة طلبات الطعام — نفس منطق عزل php_transit.
# المشترك الوحيد: JWT (backend/core) ونفس mysql/redis. قاعدة tripz_food منفصلة.
php_food:
build:
context: ..
dockerfile: docker/php/Dockerfile.fpm.transit
args:
PHP_VERSION: "${PHP_VERSION:-8.2}"
volumes:
- ../backend/core:/var/www/backend/core:ro
- ../backend/functions.php:/var/www/backend/functions.php:ro
# core/bootstrap.php يحمّل backend/vendor/autoload.php، وJwtService
# يحتاج Firebase\JWT. الصورة هنا بلا composer عمداً، ودون هذا التركيب
# كانت كل نقطة طعام تسقط بـ Class "Firebase\JWT\JWT" not found.
# للقراءة فقط: مكتبات مشتركة لا كود مشترك — العزل باقٍ.
- ../backend/vendor:/var/www/backend/vendor:ro
- ../backend/food:/var/www/backend/food
- ./php/opcache.ini:/usr/local/etc/php/conf.d/zz-opcache.ini:ro
- ./php/php-prod.ini:/usr/local/etc/php/conf.d/zz-prod.ini:ro
- ./php/food-pool.conf:/usr/local/etc/php-fpm.d/zz-pool.conf:ro
- ./keys:/keys:ro
env_file: .env
depends_on:
- mysql
- redis
mem_limit: 768m
restart: unless-stopped
# سوكيت الطعام — WS بورت 4040 + HTTP داخلي 4041
socket_food:
build:
context: ./php
dockerfile: Dockerfile.socket
args:
PHP_VERSION: "${PHP_VERSION:-8.2}"
command: ["php", "food_socket.php", "start"]
working_dir: /app
volumes:
- ../food_server:/app
- ./keys:/keys:ro
env_file: .env
ports:
# نفس منطق سوكيت السائقين: لا نفتح 4040 للعالم مباشرة — nginx على
# المضيف يستمع 4040 بالشهادة ويمرّر إلى 14042 هنا. 4041 داخلي فقط
# (الباك إند يناديه عبر http://socket_food:4041).
- "127.0.0.1:${FOOD_SOCKET_PORT:-14042}:4040"
depends_on:
- redis
mem_limit: 512m
restart: unless-stopped
# سوكيت السائقين (Workerman + PHPSocketIO) — WS بورت 2020 + HTTP داخلي 2021
# عملية دائمة، لا علاقة لها بـ fpm — حاوية مستقلة إجبارياً.
socket_driver:
build:
context: ./php
dockerfile: Dockerfile.socket
args:
PHP_VERSION: "${PHP_VERSION:-8.2}"
command: ["php", "driver_socket.php", "start"]
working_dir: /app
volumes:
- ../loction_server:/app
- ./keys:/keys:ro
env_file: .env
ports:
# لا نفتح 2020 للعالم مباشرة: Workerman يتكلم نصاً صريحاً، والتطبيق يطلب
# TLS على هذا المنفذ فتتجمّد المصافحة وينتهي بـ timeout.
# nginx على المضيف يستمع على 2020 بالشهادة ويمرّر إلى 12022 هنا.
# انظر nginx/tripz-sockets-tls.conf
# المنفذ قابل للضبط: على سيرفر تعمل عليه أكثر من نسخة (siro/tripz/intaleq)
# لا يتصادم. اضبط DRIVER_SOCKET_PORT في .env.
- "127.0.0.1:${DRIVER_SOCKET_PORT:-12022}:2020"
# و2021 داخلي فقط: الباك إند يناسيه عبر http://socket_driver:2021
depends_on:
- redis
mem_limit: 768m
restart: unless-stopped
# سوكيت الركاب (ride_server) — WS بورت 3030 + HTTP داخلي 3031
socket_passenger:
build:
context: ./php
dockerfile: Dockerfile.socket
args:
PHP_VERSION: "${PHP_VERSION:-8.2}"
command: ["php", "passenger_socket.php", "start"]
working_dir: /app
volumes:
- ../ride_server:/app
- ./keys:/keys:ro
env_file: .env
ports:
# نفس منطق سوكيت السائقين: nginx على المضيف يستمع على 3030 بالشهادة
# ويمرّر إلى 13033 هنا. و3031 داخلي فقط (http://socket_passenger:3031).
# ⚠️ 13032 محجوزة من نسخة intaleq على السيرفر نفسه — لهذا استخدمنا 13033.
- "127.0.0.1:${PASSENGER_SOCKET_PORT:-13033}:3030"
depends_on:
- redis
mem_limit: 512m
restart: unless-stopped
mysql:
image: mysql:8.4
environment:
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:?set in .env}"
# بيانات القاعدة على volume مسمّى — يتجاوز overlayfs = أداء قرص شبه أصلي.
volumes:
- mysql-data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d:ro
command:
- --innodb-buffer-pool-size=1G
- --max-connections=300
- --innodb-flush-log-at-trx-commit=1
- --slow-query-log=1
- --long-query-time=0.2
- --slow-query-log-file=/var/lib/mysql/slow.log
ports:
# للإدارة من السيرفر نفسه فقط — ليس للعامة.
# 33061 يحتجزه intaleq-mysql-1 و33062 يحتجزه siro-mysql-1.
- "127.0.0.1:33063:3306"
mem_limit: 2560m
restart: unless-stopped
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
PMA_HOST: mysql
PMA_PORT: 3306
UPLOAD_LIMIT: 300M
ports:
# مقيّد على loopback عمداً — لا تكشفه للإنترنت بلا TLS.
# الوصول عبر نفق SSH فقط: ssh -N -L 8084:127.0.0.1:8084 USER@SERVER
- "127.0.0.1:8084:80"
depends_on:
- mysql
mem_limit: 256m
restart: unless-stopped
redis:
image: redis:7-alpine
command:
- redis-server
- --maxmemory
- 400mb
- --maxmemory-policy
- noeviction
- --appendonly
- "yes"
volumes:
- redis-data:/data
mem_limit: 512m
restart: unless-stopped
# خادم TURN لمكالمات الصوت (رحلات + توصيل الطعام).
# network_mode: host إجباري هنا لا تفضيلاً: coturn يضع عنوان الخادم داخل
# حمولة ICE، ولو مرّ عبر جسر دوكر لأعلن عنواناً داخلياً (172.x) فيفشل
# التمرير. ومع host يسري جدار الحماية عادةً بدل أن يلتفّ عليه docker-proxy.
#
# ⚠️ منفذ TURN مختلف عن نسخة سيرو (3478 محجوزة هناك): هنا 3479.
coturn:
image: coturn/coturn:4.6-alpine
network_mode: host
volumes:
- ./coturn/turnserver.conf:/etc/coturn/turnserver.conf:ro
command: >
-c /etc/coturn/turnserver.conf
--realm=${TURN_REALM:-api.tripz-egypt.com}
--static-auth-secret=${TURN_STATIC_AUTH_SECRET:?TURN_STATIC_AUTH_SECRET is required}
--external-ip=${TURN_EXTERNAL_IP:?TURN_EXTERNAL_IP is required}
--listening-ip=${TURN_EXTERNAL_IP}
--relay-ip=${TURN_EXTERNAL_IP}
mem_limit: 256m
restart: unless-stopped
volumes:
mysql-data:
redis-data: