Guide to Configuring a PHP gRPC Client with Docker and Composer
This tutorial provides a step‑by‑step guide to configuring a PHP gRPC client using proto files, Composer, Docker, and Docker‑Compose, covering project structure, code generation, autoload setup, Dockerfile creation, and client execution in a containerized environment.
PHP gRPC Client Configuration
This guide walks you through configuring a gRPC client in PHP. It covers everything from setting up the project structure and creating proto files to Dockerizing the environment and writing the PHP client code.
Key Points
Initial folder structure
Create proto file
Create Composer file
Composer autoload configuration
Composer install script
PHP Dockerfile
PHP gRPC client code
Docker Compose configuration
1. Initial Folder Structure
Ensure the project follows the layout below:
<code>|-php-grpc
|- docker
| |- php
| | |- Dockerfile
| | |- install-composer.sh
| |- go
| | |- Dockerfile
| |- docker-compose.yml
|- grpc-client-php
| |- composer.json
| |- src
| | |- user.php
|- grpc-server-go
| |- main.go
|- protos
|- userService.proto
</code>2. Create Proto File
Create protos/userService.proto with the following content:
<code>// User service definition
service User {
// Send greeting
rpc FindById (FindByIdRequest) returns (FindByIdReply) {}
}
// Request message containing user ID
message FindByIdRequest {
string id = 1;
}
// Response message containing user data
message FindByIdReply {
string id = 1;
string name = 2;
}
</code>During Docker image build, compile userService.proto and generate two directories:
<code>app
|- grpc-client-php
|- GPBMetadata
| |- UserService.php
|- Grpc
| |- FindByIdReply.php
| |- FindByIdRequest.php
| |- UserClient.php
</code>3. Create Composer File
<code>{
"name": "php/grpc",
"description": "grpc example",
"type": "project",
"require": {
"grpc/grpc": "^1.57",
"google/protobuf": "^4.0@RC"
},
"license": "Free"
}
</code>4. Composer Autoload Configuration
Add the following autoload section to ./grpc-client-php/composer.json :
<code>{
...,
"autoload": {
"psr-4": {
"Grpc\\": "src/Grpc",
"GPBMetadata\\": "src/GPBMetadata"
}
}
}
</code>5. Composer Install Script
The Composer installer runs inside the Docker image. Create ./docker/php/install-composer.sh with the content below:
<code>#!/bin/sh
echo 'It is being installed a COMPOSER'
EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php')")"
if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
then
>&2 echo 'ERROR: Invalid installer checksum'
rm composer-setup.php
exit 1
fi
php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php
mv composer.phar /usr/local/bin/composer
exit $RESULT
</code>6. PHP Dockerfile
Create ./docker/php/Dockerfile with the following content:
<code>FROM php:8.3-fpm-alpine
COPY docker/php/install-composer.sh /tmp
RUN chmod +x /tmp/install-composer.sh && sh /tmp/install-composer.sh
COPY ./grpc-client-php /app/grpc-client-php
COPY ./protos /app/protos
RUN apk add --update linux-headers \
&& apk add --no-cache autoconf gcc make g++ zlib-dev git cmake \
&& pecl channel-update pecl.php.net \
# Install the grpc extension
&& pecl install grpc \
&& docker-php-ext-enable grpc
# Install gRPC PHP plugin
RUN cd /app && git clone https://github.com/grpc/grpc \
&& cd /app/grpc && git submodule update --init \
&& mkdir -p cmake/build && cd cmake/build && cmake ../.. && make protoc grpc_php_plugin
RUN cd /app/grpc-client-php \
# Install required packages
&& composer install \
# Install protobuf compiler
&& apk add protobuf \
# Compile userService.proto
&& cd /app && protoc --proto_path=protos \
--php_out=./grpc-client-php/src \
--grpc_out=./grpc-client-php/src \
--plugin=protoc-gen-grpc=./grpc/cmake/build/grpc_php_plugin \
./protos/userService.proto
WORKDIR /app
CMD ["php-fpm"]
</code>7. PHP gRPC Client Code
Create grpc-client-php/src/user.php with the following script:
<code><?php
use Grpc\UserClient;
use Grpc\ChannelCredentials;
use Grpc\FindByIdRequest;
require dirname(__FILE__) . '/../vendor/autoload.php';
/**
* Parse gRPC error
*/
function getErrorMessage(\stdClass $status, string $id): string
{
if ($status->code !== \Grpc\STATUS_NOT_FOUND)
return sprintf("User %s was not found", $id);
return "ERROR: " . $status->code . ", " . $status->details;
}
function run(string $hostname, string $id): void
{
// Create gRPC client
$userClient = new UserClient($hostname, [
'credentials' => ChannelCredentials::createInsecure(),
]);
// Create request
$request = new FindByIdRequest();
$request->setId($id);
// Call remote procedure
list($response, $status) = $userClient->FindById($request)->wait();
// Handle errors
if ($status->code !== \Grpc\STATUS_OK) {
echo getErrorMessage($status, $id) . PHP_EOL;
exit(1);
}
// Output received user name
echo $response->getName() . PHP_EOL;
}
// User ID (default if not provided)
$id = !empty($argv[1]) ? $argv[1] : 'some-unique-id';
// gRPC server address (default if not provided)
$hostname = !empty($argv[2]) ? $argv[2] : 'grpc-server:9090';
run($hostname, $id);
</code>8. Docker Compose
Create docker/docker-compose.yml with the following configuration:
<code>version: '3.6'
services:
grpc-client:
build:
context: ../
dockerfile: docker/php/Dockerfile
container_name: grpc-client
volumes:
- ../grpc-client-php:/project
networks:
- dev_grpc_network
networks:
dev_grpc_network:
external: true
</code>9. Build and Run
Create the Docker network:
<code>docker network create dev_grpc_network
</code>Build and start the client container:
<code>cd ./docker
docker compose up --build grpc-client -d
</code>php中文网 Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.