A modern Symfony 8 microservice with gRPC support powered by RoadRunner, implementing Domain-Driven Design (DDD).
- Symfony 8.0 - Latest Symfony framework
- RoadRunner - High-performance PHP application server
- gRPC - Modern RPC framework for microservices
- ️ DDD Architecture - Domain-Driven Design structure
- PHPUnit - Comprehensive unit testing
- PHPStan - Static analysis for code quality
- Docker - Containerized development environment
- PHP 8.4+
- Composer 2.x
- Docker & Docker Compose
- grpcurl (for testing gRPC endpoints)
- Clone the repository:
git clone git@github.com:albertcolom/symfony-grpc.git
cd symfony-grpc- Install dependencies:
make install- Build Docker containers:
make build- Start the application:
make upThe gRPC server will be available at localhost:9001.
symfony-grpc/
├── bin/ # Executables (git-ignored, installed via Composer)
├── config/ # Symfony configuration
├── generated/ # Auto-generated gRPC PHP classes
├── proto/ # Protocol Buffer definitions
├── public/ # Public entry points (grpc-worker.php)
├── resources/ # Docker resources
│ └── docker/
│ ├── php-roadrunner/ # PHP + RoadRunner Dockerfile
│ └── protobuf/ # Protocol Buffer generator
├── src/ # Application source code
│ ├── Kernel.php
│ └── User/ # User domain module
│ ├── Application/ # Use cases (Commands, Queries, Handlers)
│ ├── Domain/ # Domain entities and value objects
│ └── Infrastructure/ # Infrastructure layer (GRPC, Persistence)
├── tests/ # PHPUnit tests
│ └── Unit/
└── vendor/ # Composer dependencies (git-ignored)
Run make help to see all available commands:
make help # Show available commands
make install # Install Composer dependencies
make build # Build Docker containers
make up # Start Docker containers
make down # Stop Docker containers
make restart # Restart Docker containers
make logs # Show container logs (follow mode)
make shell # Access PHP container shell
make test # Run PHPUnit tests
make phpstan # Run PHPStan static analysis
make grpc-test # Test gRPC service example
make clean # Clean cache and logsThe application includes a User service with the following RPC method:
service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse);
}Using Make command:
make grpc-testUsing grpcurl directly:
grpcurl -plaintext \
-proto proto/user.proto \
-d '{"id":"f5fb962d-60f6-4096-8bd6-f717249d46fa"}' \
localhost:9001 \
user.v1.UserService/GetUserExpected response:
{
"id": "f5fb962d-60f6-4096-8bd6-f717249d46fa",
"email": "john.doe@example.com"
}Run all unit tests with coverage:
make testOr directly with PHPUnit:
docker compose exec php-rr vendor/bin/phpunitRun PHPStan for code quality checks:
make phpstanTo access the PHP container:
make shellTo follow container logs in real-time:
make logsThe project follows DDD principles with a clear separation of concerns:
- Domain Layer: Core business logic, entities, and value objects
- Application Layer: Use cases, commands, queries, and handlers
- Infrastructure Layer: External concerns (gRPC, persistence, etc.)
Protocol Buffer definitions are located in proto/ directory. Generated PHP classes are automatically created in generated/GRPC/ when containers start.
To manually regenerate:
docker compose up proto-gen- php-rr: PHP 8.4 with RoadRunner
- Port 8080: HTTP server
- Port 6001: RoadRunner metrics
- Port 9001: gRPC server
- proto-gen: Protocol Buffer code generator
RoadRunner is configured via .rr.yaml in the project root.
Application configuration is in config/ directory:
services.yaml: Service container configurationpackages/: Bundle-specific configurations
- The
bin/directory is git-ignored as executables (likebin/console) are installed via Composer - PHPUnit is available at
vendor/bin/phpunit - The application runs in production mode by default in Docker