@@ -18,20 +18,129 @@ This skeleton for self-sufficient, asynchronous microservice contains:
1818 - ` symfony/config `
1919 - ` symfony/yaml `
2020
21- It follows strong SOLID design and fully PSR-compatible,
22- with PHP 7.4+ features in mind
23- (starting with typed properties).
21+ It follows strong SOLID design and fully PSR-compatible, built
22+ with PHP 7.4+ features in mind (starting with typed properties).
2423
2524It is also relatively lightweight and takes benefits
2625from both [ Symfony] ( https://github.com/symfony/symfony ) components
2726and [ ReactPHP] ( https://github.com/reactphp/reactphp )
2827without raising up a heavy artillery setup.
2928
29+ ## Installation
30+
31+ ### Docker Swarm
32+
33+ This setup provides a basic service scalability using [ Swarm mode] ( https://docs.docker.com/engine/swarm/key-concepts ) .
34+ For testing purposes, let's assume we have the following servers:
35+
36+ ```
37+ 192.169.56.1 # our pc, manager node; haproxy
38+ 192.169.56.10 # vm, worker node; app instance
39+ 192.169.56.20 # vm, worker node; app instance
40+ 192.169.56.30 # vm, worker node; app instance
41+ ```
42+
43+ ** Pre-requirements** . Ensure all necessary ports are accessible on each machine
44+ or it may cause implicit problems during communication between nodes.
45+ A common symptom is a successful ` nslookup ` for all replicas within overlay,
46+ but a failed ` ping ` of some of them. Here is a quick list:
47+
48+ ```
49+ $ sudo ufw status
50+ Status: active
51+
52+ To Action From
53+ -- ------ ----
54+ 22/tcp ALLOW 192.169.56.0/24
55+ 2376/tcp ALLOW 192.169.56.0/24
56+ 2377/tcp ALLOW 192.169.56.0/24
57+ 4789/udp ALLOW 192.169.56.0/24
58+ 7946/tcp ALLOW 192.169.56.0/24
59+ 7946/udp ALLOW 192.169.56.0/24
60+ ```
61+
62+ ** Limitations** . This setup assumes you are using a single haproxy instance,
63+ on the fixed node in the cluster and only that node will have its ports published:
64+
65+ ![ how it works schema] ( https://github.com/itnelo/reactphp-foundation/blob/master/.github/images/how_it_works_schema.png )
66+
67+ ** Step 1** . Create a manager node (for haproxy with exposed ports):
68+
69+ ```
70+ # our pc
71+ $ docker swarm init --advertise-addr 192.169.56.1
72+ ```
73+
74+ And a few worker nodes:
75+
76+ ```
77+ # vm
78+ $ docker swarm join --token JOIN_TOKEN --advertise-addr 192.169.56.10 192.169.56.1
79+ ```
80+
81+ where ` JOIN_TOKEN ` is a parameter obtained by ` docker swarm join-token worker ` on the manager node.
82+ Repeat this action for all other worker servers in your cluster
83+ using their own advertise addresses.
84+
85+ ** Step 2** . Assign geography labels to be able to evenly distribute
86+ containers between all available servers:
87+
88+ ```
89+ # our pc
90+ $ docker node update --label-add provider_location_machine=do.fra1.d1 HOSTNAME
91+ ```
92+
93+ where ` HOSTNAME ` is a server identifier, see ` docker node ls ` on the manager node.
94+
95+ ** Step 3** . Clone the repository and adjust environment variables:
96+
97+ ```
98+ # our pc
99+ $ git clone git@github.com:itnelo/reactphp-foundation.git my-service && cd "$_"
100+ $ cp .env.dev.dist .env
101+ ```
102+
103+ Fill ` APP_STACK_IMAGE_NAME ` and ` APP_STACK_IMAGE_VERSION ` with your image metadata
104+ from the desired registry.
105+
106+ ** Step 4** . Apply stack configuration:
107+
108+ ```
109+ # our pc
110+ $ set -a; . .env; set +a && envsubst < docker-compose.stack.yml.dist > docker-compose.stack.yml
111+ ```
112+
113+ You should also adjust placement constraints
114+ (according to ** Step 2** ) to ensure Swarm scheduler is able to assign tasks
115+ to the configured nodes. Check ` haproxy.stack.cfg ` from the ` docker ` directory
116+ if you have changed some ports or just use a custom haproxy image as well.
117+
118+ ** Step 5** . Deploy services:
119+
120+ ```
121+ # our pc
122+ $ docker stack deploy --orchestrator swarm --compose-file docker-compose.stack.yml my-service
123+ ```
124+
125+ By accessing ` 192.169.56.1:6637/stats ` (if you stick to the default configuration;
126+ use your manager node IP) a rendered page with backend statistics should be available:
127+
128+ ![ haproxy stats] ( https://github.com/itnelo/reactphp-foundation/blob/master/.github/images/haproxy_stats.png )
129+
130+ To rebalance app replicas between nodes, after one is added or removed, use:
131+
132+ ```
133+ $ docker service update --force my-service_app
134+ ```
135+
30136## See also
31137
32138- [ driftphp/driftphp] ( https://github.com/driftphp/driftphp ) —
33139If you are looking for a deeper Symfony integration, with Kernel adaptation
34140to async environment.
141+ - [ thesecretlivesofdata.com/raft] ( http://thesecretlivesofdata.com/raft/ ) —
142+ A helpful visualization to understand how the distributed consensus algorithm,
143+ used by Docker Swarm, works.
35144
36145## Changelog
37146
0 commit comments