Some hull parts and scrap to bootstrap an elegant spacecraft w/ ReactPHP

0.3.0 2020-08-17 17:43 UTC

This package is auto-updated.

Last update: 2024-05-15 02:18:35 UTC


What's inside?

This skeleton for self-sufficient, asynchronous microservice contains:

  • Interfaces
    • psr/log — PSR-3 (Logger)
    • psr/http-message — PSR-7 (HTTP Message)
    • psr/container — PSR-11 (Container)
  • Decoupling code via Symfony's container
    • symfony/dependency-injection
  • Ensure the non-blocking I/O with ReactPHP components
    • react/event-loop
    • react/http
    • react/stream
  • Managing environment and configurations
    • symfony/dotenv
    • symfony/config
    • symfony/yaml

It follows strong SOLID design and fully PSR-compatible, built with PHP 7.4+ features in mind (starting with typed properties).

It is also relatively lightweight and takes benefits from both Symfony components and ReactPHP without raising up a heavy artillery setup.

There are a few deployment configurations (Docker Compose project and stack for Docker Swarm, featuring HAProxy as a load balancer for your code).


Docker Swarm

This setup provides a basic service scalability using Swarm mode. For testing purposes, let's assume we have the following servers:    # our pc, manager node; haproxy   # vm, worker node; app instance   # vm, worker node; app instance   # vm, worker node; app instance

Pre-requirements. Ensure all necessary ports are accessible on each machine or it may cause implicit problems during communication between nodes. A common symptom is a successful nslookup for all replicas within overlay, but a failed ping of some of them. Here is a quick list:

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW
2376/tcp                   ALLOW
2377/tcp                   ALLOW
4789/udp                   ALLOW
7946/tcp                   ALLOW
7946/udp                   ALLOW

Limitations. This setup assumes you are using a single haproxy instance, on the fixed node in the cluster and only that node will have its ports published:

how it works schema

Step 1. Create a manager node (for haproxy with exposed ports):

# our pc
$ docker swarm init --advertise-addr

And a few worker nodes:

# vm
$ docker swarm join --token JOIN_TOKEN --advertise-addr

where JOIN_TOKEN is a parameter obtained by docker swarm join-token worker on the manager node. Repeat this action for all other worker servers in your cluster using their own advertise addresses.

Step 2. Assign geography labels to be able to evenly distribute containers between all available servers:

# our pc
$ docker node update --label-add provider_location_machine=do.fra1.d1 HOSTNAME

where HOSTNAME is a server identifier, see docker node ls on the manager node.

Step 3. Clone the repository and adjust environment variables:

# our pc
$ git clone my-service && cd "$_"
$ cp .env

Fill APP_STACK_IMAGE_NAME and APP_STACK_IMAGE_VERSION with your image metadata from the desired registry.

Step 4. Apply stack configuration:

# our pc
$ set -a; . .env; set +a && envsubst < docker-compose.stack.yml.dist > docker-compose.stack.yml

You should also adjust placement constraints (according to Step 2) to ensure Swarm scheduler is able to assign tasks to the configured nodes. Check haproxy.stack.cfg from the docker directory if you have changed some ports or just use a custom haproxy image as well.

Step 5. Deploy services:

# our pc
$ docker stack deploy --orchestrator swarm --compose-file docker-compose.stack.yml my-service

By accessing (if you stick to the default configuration; use your manager node IP) a rendered page with backend statistics should be available:

haproxy stats

To rebalance app replicas between nodes, after one is added or removed, use:

# our pc
$ docker service update --force my-service_app


Apply test suite configuration and run phpunit:

$ cp phpunit.xml.dist phpunit.xml

# for docker-compose installation
$ docker-compose run --rm app bin/phpunit

See also

  • driftphp/driftphp — If you are looking for a deeper Symfony integration, with Kernel adaptation to async environment.
  • — A helpful visualization to understand how the distributed consensus algorithm, used by Docker Swarm, works.


All notable changes to this project will be documented in