{"id":15296411,"url":"https://github.com/itnelo/reactphp-foundation","last_synced_at":"2026-02-06T08:01:43.570Z","repository":{"id":56994369,"uuid":"271659033","full_name":"itnelo/reactphp-foundation","owner":"itnelo","description":":rocket: Some hull parts and scrap to bootstrap an elegant spacecraft w/ ReactPHP","archived":false,"fork":false,"pushed_at":"2020-12-14T18:27:10.000Z","size":508,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-30T05:26:40.918Z","etag":null,"topics":["docker-compose","docker-swarm","microservice","microservice-architecture","php74","reactphp","skeleton"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itnelo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-11T22:33:22.000Z","updated_at":"2021-02-15T18:04:57.000Z","dependencies_parsed_at":"2022-08-21T10:40:43.457Z","dependency_job_id":null,"html_url":"https://github.com/itnelo/reactphp-foundation","commit_stats":null,"previous_names":[],"tags_count":3,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itnelo%2Freactphp-foundation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itnelo%2Freactphp-foundation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itnelo%2Freactphp-foundation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itnelo%2Freactphp-foundation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itnelo","download_url":"https://codeload.github.com/itnelo/reactphp-foundation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245407755,"owners_count":20610232,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker-compose","docker-swarm","microservice","microservice-architecture","php74","reactphp","skeleton"],"created_at":"2024-09-30T18:10:23.868Z","updated_at":"2026-02-06T08:01:38.544Z","avatar_url":"https://github.com/itnelo.png","language":"PHP","readme":"\n# ReactPHP Foundation\n\n- [What's inside?](#whats-inside)\n- [Installation](#installation)\n    - [Docker Swarm](#docker-swarm)\n- [Tests](#tests)\n- [See also](#see-also)\n- [Changelog](#changelog)\n\n## What's inside?\n\nThis skeleton for self-sufficient, asynchronous microservice contains:\n\n- Interfaces\n    - `psr/log` — PSR-3 (Logger)\n    - `psr/http-message` — PSR-7 (HTTP Message)\n    - `psr/container` — PSR-11 (Container)\n- Decoupling code via Symfony's container\n    - `symfony/dependency-injection`\n- Ensure the non-blocking I/O with ReactPHP components\n    - `react/event-loop`\n    - `react/http`\n    - `react/stream`\n- Managing environment and configurations\n    - `symfony/dotenv`\n    - `symfony/config`\n    - `symfony/yaml`\n\nIt follows strong SOLID design and fully PSR-compatible, built\nwith PHP 7.4+ features in mind (starting with typed properties). \n\nIt is also _relatively_ lightweight and takes benefits\nfrom both [Symfony](https://github.com/symfony/symfony) components\nand [ReactPHP](https://github.com/reactphp/reactphp)\nwithout raising up a heavy artillery setup.\n\nThere are a few deployment configurations\n([Docker Compose](https://docs.docker.com/compose) project and\nstack for [Docker Swarm](https://docs.docker.com/engine/swarm/key-concepts),\nfeaturing [HAProxy](https://www.haproxy.com) as a load balancer for your code).\n\n## Installation\n\n### Docker Swarm\n\nThis setup provides a basic service scalability using [Swarm mode](https://docs.docker.com/engine/swarm/key-concepts). \nFor testing purposes, let's assume we have the following servers:\n\n```\n192.169.56.1    # our pc, manager node; haproxy\n192.169.56.10   # vm, worker node; app instance\n192.169.56.20   # vm, worker node; app instance\n192.169.56.30   # vm, worker node; app instance\n```\n\n**Pre-requirements**. Ensure all necessary ports are accessible on each machine\nor it may cause implicit problems during communication between nodes.\nA common symptom is a successful `nslookup` for all replicas within overlay,\nbut a failed `ping` of some of them. Here is a quick list:\n\n```\n$ sudo ufw status\nStatus: active\n\nTo                         Action      From\n--                         ------      ----\n22/tcp                     ALLOW       192.169.56.0/24\n2376/tcp                   ALLOW       192.169.56.0/24\n2377/tcp                   ALLOW       192.169.56.0/24\n4789/udp                   ALLOW       192.169.56.0/24\n7946/tcp                   ALLOW       192.169.56.0/24\n7946/udp                   ALLOW       192.169.56.0/24\n```\n\n**Limitations**. This setup assumes you are using a single haproxy instance,\non the fixed node in the cluster and only that node will have its ports published:\n\n![how it works schema](https://github.com/itnelo/reactphp-foundation/blob/master/.github/images/how_it_works_schema.png)\n\n**Step 1**. Create a manager node (for haproxy with exposed ports):\n\n```\n# our pc\n$ docker swarm init --advertise-addr 192.169.56.1\n```\n\nAnd a few worker nodes:\n\n```\n# vm\n$ docker swarm join --token JOIN_TOKEN --advertise-addr 192.169.56.10 192.169.56.1\n```\n\nwhere `JOIN_TOKEN` is a parameter obtained by `docker swarm join-token worker` on the manager node.\nRepeat this action for all other worker servers in your cluster\nusing their own advertise addresses.\n\n**Step 2**. Assign geography labels to be able to evenly distribute\ncontainers between all available servers:\n\n```\n# our pc\n$ docker node update --label-add provider_location_machine=do.fra1.d1 HOSTNAME\n```\n\nwhere `HOSTNAME` is a server identifier, see `docker node ls` on the manager node.\n\n**Step 3**. Clone the repository and adjust environment variables:\n\n```\n# our pc\n$ git clone git@github.com:itnelo/reactphp-foundation.git my-service \u0026\u0026 cd \"$_\"\n$ cp .env.dev.dist .env\n```\n\nFill `APP_STACK_IMAGE_NAME` and `APP_STACK_IMAGE_VERSION` with your image metadata\nfrom the desired registry.\n\n**Step 4**. Apply stack configuration:\n\n```\n# our pc\n$ set -a; . .env; set +a \u0026\u0026 envsubst \u003c docker-compose.stack.yml.dist \u003e docker-compose.stack.yml\n```\n\nYou should also adjust placement constraints\n(according to **Step 2**) to ensure Swarm scheduler is able to assign tasks\nto the configured nodes. Check `haproxy.stack.cfg` from the `docker` directory\nif you have changed some ports or just use a custom haproxy image as well.\n\n**Step 5**. Deploy services:\n\n```\n# our pc\n$ docker stack deploy --orchestrator swarm --compose-file docker-compose.stack.yml my-service\n```\n\nBy accessing `192.169.56.1:6637/stats` (if you stick to the default configuration; \nuse your manager node IP) a rendered page with backend statistics should be available:\n\n![haproxy stats](https://github.com/itnelo/reactphp-foundation/blob/master/.github/images/haproxy_stats.png)\n\nTo rebalance app replicas between nodes, after one is added or removed, use:\n\n```\n# our pc\n$ docker service update --force my-service_app\n```\n\n## Tests\n\nApply test suite configuration and run [phpunit](https://github.com/sebastianbergmann/phpunit):\n\n```\n$ cp phpunit.xml.dist phpunit.xml\n\n# for docker-compose installation\n$ docker-compose run --rm app bin/phpunit\n```\n\n## See also\n\n- [driftphp/driftphp](https://github.com/driftphp/driftphp) — \nIf you are looking for a deeper Symfony integration, with Kernel adaptation\nto async environment.\n- [thesecretlivesofdata.com/raft](http://thesecretlivesofdata.com/raft/) —\nA helpful visualization to understand how the distributed consensus algorithm,\nused by Docker Swarm, works.\n\n## Changelog\n\nAll notable changes to this project will be documented in [CHANGELOG.md](CHANGELOG.md).","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitnelo%2Freactphp-foundation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitnelo%2Freactphp-foundation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitnelo%2Freactphp-foundation/lists"}