a536baabd6
Adds the complete project foundation: - BMAD BMM workflow tooling (_bmad/) - Claude slash commands, skills, and project memories (.claude/) - ESP32 firmware scaffold (PlatformIO + Waveshare e-ink driver) - .gitignore excluding _bmad-output/ and .pio/ build artifacts Planning artifacts (PRD, architecture, epics) are intentionally not tracked — they live in _bmad-output/ per project convention. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
330 lines
9.7 KiB
Markdown
330 lines
9.7 KiB
Markdown
---
|
|
name: oro-devops
|
|
description: OroCommerce DevOps and infrastructure reference covering system requirements, installation, deployment, Docker, cron setup, Supervisor, monitoring, caching, environment configuration, CI/CD, and performance optimization. Use when setting up local dev environments, configuring CI/CD, debugging deployment issues, or planning infrastructure. For OroCloud-specific operations (production deployment, upgrades, backups), see the oro-cloud skill.
|
|
---
|
|
|
|
# OroCommerce DevOps
|
|
|
|
Infrastructure, deployment, and operations reference for OroCommerce.
|
|
Docs: https://doc.oroinc.com/backend/setup/
|
|
|
|
**Note:** Production runs on OroCloud Enterprise. For cloud deployment,
|
|
upgrades, backups, and maintenance commands, see the `oro-cloud` skill.
|
|
This skill covers local dev, CI, and general infrastructure concepts.
|
|
|
|
## System Requirements
|
|
|
|
### Minimum Server
|
|
- 2 CPU cores, 2GB RAM, SSD
|
|
- Linux recommended (RHEL, Ubuntu, Debian, Oracle Linux)
|
|
|
|
### Software Stack
|
|
|
|
| Component | Version | Notes |
|
|
|---|---|---|
|
|
| PHP | >= 8.4 | CLI + FPM |
|
|
| PostgreSQL | >= 16.1 | with uuid-ossp extension |
|
|
| Nginx or Apache | latest | Nginx recommended |
|
|
| Node.js | >= 22 | asset build only |
|
|
| NPM | > 10 | asset build only |
|
|
| Redis | 7.2.x | cache + sessions (recommended) |
|
|
| Elasticsearch | >= 8.4.1, < 9.0 | EE only |
|
|
| RabbitMQ | 3.12.x | EE only |
|
|
| Supervisor | latest | MQ consumer daemon |
|
|
| Gotenberg | >= 8.5 | PDF generation (optional) |
|
|
|
|
### Required PHP Extensions
|
|
ctype, curl, fileinfo, gd, intl (ICU >= 4.4), json, mbstring, sodium,
|
|
openssl, pgsql, pcre, simplexml, tokenizer, xml, zip, imap, soap, bcmath,
|
|
ldap, mongodb (for GridFS)
|
|
|
|
### PHP Settings
|
|
```ini
|
|
date.timezone = UTC
|
|
detect_unicode = Off
|
|
memory_limit = 1G
|
|
; Increase for schema updates:
|
|
max_execution_time = 300
|
|
```
|
|
|
|
## Environment Configuration
|
|
|
|
Oro uses `.env-app` and `.env-app.local` for environment variables:
|
|
|
|
```bash
|
|
ORO_ENV=prod
|
|
ORO_SECRET=<random-secret>
|
|
ORO_DB_URL=postgres://user:pass@localhost:5432/oro_db?sslmode=disable&charset=utf8&serverVersion=17
|
|
ORO_MQ_DSN=amqp://user:pass@localhost:5672/%2f # or dbal: for CE
|
|
ORO_SEARCH_URL=elastic-search://localhost:9200 # EE only
|
|
ORO_REDIS_URL=redis://localhost:6379
|
|
ORO_REDIS_CACHE_DSN=redis://localhost:6379/1
|
|
ORO_REDIS_DOCTRINE_DSN=redis://localhost:6379/2
|
|
ORO_REDIS_LAYOUT_DSN=redis://localhost:6379/3
|
|
ORO_SESSION_DSN=redis://localhost:6379/0
|
|
ORO_MAILER_DSN=smtp://localhost:1025
|
|
ORO_WEBSOCKET_SERVER_DSN=//0.0.0.0:8080
|
|
ORO_WEBSOCKET_FRONTEND_DSN=//*:8080/ws
|
|
ORO_WEBSOCKET_BACKEND_DSN=tcp://127.0.0.1:8080
|
|
```
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
# Install dependencies
|
|
composer install --prefer-dist --no-dev --optimize-autoloader
|
|
|
|
# Install application (creates DB schema, loads fixtures, builds assets)
|
|
php bin/console oro:install --env=prod \
|
|
--organization-name="My Org" \
|
|
--user-name=admin \
|
|
--user-email=admin@example.com \
|
|
--user-firstname=Admin \
|
|
--user-lastname=Admin \
|
|
--user-password=<password> \
|
|
--application-url=https://app.example.com \
|
|
--timeout=3600
|
|
```
|
|
|
|
Verify requirements: `php bin/console oro:check-requirements -vv`
|
|
|
|
## Deployment Steps
|
|
|
|
```bash
|
|
# 1. Pull code
|
|
git pull origin main
|
|
|
|
# 2. Install dependencies
|
|
composer install --prefer-dist --no-dev --optimize-autoloader
|
|
|
|
# 3. Run migrations
|
|
php bin/console oro:migration:load --env=prod
|
|
|
|
# 4. Update extended entity schema
|
|
php bin/console oro:entity-extend:update-schema --env=prod
|
|
|
|
# 5. Clear and warmup cache
|
|
php bin/console cache:clear --env=prod
|
|
php bin/console oro:entity-extend:cache:warmup --env=prod
|
|
|
|
# 6. Build assets
|
|
php bin/console oro:assets:build --env=prod
|
|
|
|
# 7. Update cron definitions
|
|
php bin/console oro:cron:definitions:load --env=prod
|
|
|
|
# 8. Restart consumers
|
|
supervisorctl restart oro-consumer:*
|
|
```
|
|
|
|
## Cron Setup
|
|
|
|
Single system crontab entry runs Oro's dispatcher every minute:
|
|
|
|
```crontab
|
|
*/1 * * * * www-data /usr/bin/php /var/www/oro/bin/console oro:cron --env=prod > /dev/null
|
|
```
|
|
|
|
The `oro:cron` command dispatches scheduled commands to the MQ.
|
|
|
|
## Message Queue Consumers
|
|
|
|
Use Supervisor to keep MQ consumers running:
|
|
|
|
```ini
|
|
# /etc/supervisor/conf.d/oro-consumer.conf
|
|
[program:oro-consumer]
|
|
command=/usr/bin/php /var/www/oro/bin/console oro:message-queue:consume --env=prod --memory-limit=512
|
|
process_name=%(program_name)s_%(process_num)02d
|
|
numprocs=2
|
|
autostart=true
|
|
autorestart=true
|
|
startsecs=5
|
|
user=www-data
|
|
redirect_stderr=true
|
|
stdout_logfile=/var/log/oro/consumer_%(process_num)02d.log
|
|
```
|
|
|
|
Scale `numprocs` based on MQ load.
|
|
|
|
## WebSocket Server
|
|
|
|
For real-time notifications:
|
|
|
|
```ini
|
|
[program:oro-websocket]
|
|
command=/usr/bin/php /var/www/oro/bin/console gos:websocket:server --env=prod
|
|
autostart=true
|
|
autorestart=true
|
|
user=www-data
|
|
```
|
|
|
|
## Docker
|
|
|
|
### Two Docker Compose Patterns
|
|
|
|
**Pattern 1: Backing services only (CI / DDEV / local PHP)**
|
|
|
|
docker-compose.yml at project root provides only infrastructure services.
|
|
App runs on host or via DDEV/Symfony CLI:
|
|
|
|
```yaml
|
|
services:
|
|
pgsql:
|
|
image: oroinc/pgsql:17.4-alpine
|
|
ports: ['5432']
|
|
environment:
|
|
POSTGRES_USER: oro_db_user
|
|
POSTGRES_DB: oro_db
|
|
POSTGRES_PASSWORD: oro_db_pass
|
|
volumes:
|
|
- postgres:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: "pg_isready -U$${POSTGRES_USER} -d$${POSTGRES_DB}"
|
|
interval: 5s
|
|
timeout: 30s
|
|
start_period: 40s
|
|
redis:
|
|
image: redis:7.4.2-alpine
|
|
ports: ["6379"]
|
|
elasticsearch:
|
|
image: elasticsearch:8.17.4
|
|
command: bin/elasticsearch -Eingest.geoip.downloader.enabled=false
|
|
environment:
|
|
discovery.type: "single-node"
|
|
xpack.security.enabled: "false"
|
|
ES_JAVA_OPTS: -Xms2g -Xmx2g
|
|
rabbitmq:
|
|
image: oroinc/rabbitmq:3.13.7-alpine
|
|
ports: ['5672']
|
|
mongodb:
|
|
image: mongo:8.0.4
|
|
ports: ["27017"]
|
|
mailcatcher:
|
|
image: schickling/mailcatcher
|
|
ports: ['1025', '1080']
|
|
```
|
|
|
|
**Pattern 2: Full stack (PHP-FPM + Nginx) for team/staging-like dev**
|
|
|
|
Separate docker-compose in `.docker/` with app container, nginx reverse proxy, Xdebug:
|
|
|
|
```yaml
|
|
services:
|
|
oro:
|
|
build:
|
|
context: ./php
|
|
dockerfile: ./Dockerfile-6.1
|
|
environment:
|
|
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${GITHUB_TOKEN}"}}'
|
|
XDEBUG_SESSION: PHPSTORM
|
|
PHP_IDE_CONFIG: "serverName=localdev.example.com"
|
|
volumes:
|
|
- ../:/usr/share/nginx/html
|
|
nginx:
|
|
image: nginx:stable-alpine
|
|
ports: ["8280:80", "2443:443"]
|
|
depends_on: [oro]
|
|
volumes:
|
|
- ../public:/usr/share/nginx/html/public
|
|
- ./nginx/default.conf.template:/etc/nginx/templates/default.conf.template:ro
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
ports: ['25432:5432']
|
|
volumes:
|
|
- ./postgres/create_uuid-ossp_ext.sql:/docker-entrypoint-initdb.d/create_uuid-ossp_ext.sql
|
|
rabbitmq:
|
|
build:
|
|
context: .
|
|
dockerfile_inline: |
|
|
FROM rabbitmq:3.12-management-alpine
|
|
RUN wget -O $RABBITMQ_HOME/plugins/rabbitmq_delayed_message_exchange-3.12.0.ez \
|
|
https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download/v3.12.0/rabbitmq_delayed_message_exchange-3.12.0.ez && \
|
|
rabbitmq-plugins enable --offline rabbitmq_delayed_message_exchange
|
|
ports: ['25672:15672']
|
|
```
|
|
|
|
Notes:
|
|
- PostgreSQL requires `uuid-ossp` extension. Init script: `CREATE EXTENSION IF NOT EXISTS "uuid-ossp";`
|
|
- RabbitMQ delayed message exchange plugin is required for Oro delayed messages
|
|
- Adminer (`adminer:latest` on port 28080) is useful for DB inspection during dev
|
|
|
|
### Service Container Reference
|
|
|
|
| Service | Image | Health Check |
|
|
|---|---|---|
|
|
| PostgreSQL | oroinc/pgsql:17.4-alpine | `pg_isready` |
|
|
| Redis | redis:7.4.2-alpine | `redis-cli ping` |
|
|
| Elasticsearch | elasticsearch:8.17.4 | `curl localhost:9200/_cluster/health` |
|
|
| RabbitMQ | oroinc/rabbitmq:3.13.7-alpine | port 5672 |
|
|
|
|
## Environment Files
|
|
|
|
Oro uses `.env-app` (not `.env`) as the primary env file:
|
|
|
|
| File | Purpose |
|
|
|---|---|
|
|
| `.env-app` | Default values, committed to repo |
|
|
| `.env-app.local` | Local overrides (gitignored) |
|
|
| `.env-app.test` | Test-specific overrides |
|
|
|
|
Key variable prefix: `ORO_` (not `APP_`).
|
|
|
|
## CI/CD (Jenkins Pattern)
|
|
|
|
Jenkins pipeline with parallel build stages:
|
|
|
|
```groovy
|
|
stage('Build') {
|
|
parallel {
|
|
stage('Build:prod') {
|
|
// composer install --no-dev, docker build, oro:install
|
|
}
|
|
stage('Build:test') {
|
|
// composer install (with dev), phpcs, phpmd, unit tests, functional tests
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Static analysis tools in CI:
|
|
- `bin/phpcs --standard=PSR2 src/` (PHP CodeSniffer)
|
|
- `bin/phpmd src/ xml vendor/oro/platform/build/phpmd.xml` (PHP Mess Detector)
|
|
- Unit: `phpunit --testsuite=unit src/`
|
|
- Functional: `phpunit --testsuite=functional src/`
|
|
|
|
Image push to OroCloud registry: `harborio.oro.cloud/{project}/orocommerce-enterprise-application:{tag}`
|
|
|
|
## Monitoring
|
|
|
|
### Application Health
|
|
```bash
|
|
php bin/console oro:check-requirements -vv
|
|
php bin/console debug:router --env=prod # verify routes
|
|
php bin/console oro:message-queue:consume --help # MQ status
|
|
```
|
|
|
|
### Key Metrics to Monitor
|
|
- MQ queue depth (DBAL: `SELECT count(*) FROM oro_message_queue`)
|
|
- Consumer process count (Supervisor)
|
|
- PHP-FPM pool status
|
|
- PostgreSQL connection count, slow queries
|
|
- Redis memory usage
|
|
- Elasticsearch cluster health
|
|
- Disk usage (cache, logs, file storage)
|
|
|
|
### Logging
|
|
Oro uses Monolog (Symfony standard). Config in `config/config_prod.yml`.
|
|
Docs: https://doc.oroinc.com/backend/logging/
|
|
|
|
## Performance Optimization
|
|
|
|
- Enable OPcache for PHP
|
|
- Use Redis for cache + sessions (not filesystem)
|
|
- Use Elasticsearch for search (EE)
|
|
- Use RabbitMQ instead of DBAL transport (EE)
|
|
- Tune PostgreSQL (shared_buffers, work_mem, effective_cache_size)
|
|
- Use `--no-debug` for all prod commands
|
|
- Optimize Composer autoloader: `composer dump-autoload --optimize`
|
|
- Docs: https://doc.oroinc.com/backend/setup/system-requirements/performance-optimization/
|