Files
pictureFrame-webApp/.claude/skills/oro-devops/SKILL.md
T
football2801 a536baabd6 feat: initial commit — BMAD tooling, Claude memories, firmware scaffold
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>
2026-04-27 15:38:46 -04:00

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/