To transfer data to the server on the php client, you can use the following algorithm:
The source code of the project can be found on github
Here I will move in very small steps.
The project will use a bunch of nginx and php-fpm and I will start with the settings
nginx.
Let's start creating docker-compose.yml
in the root folder of our project.
# docker-compose.yml version: '3' services: nginx: image: nginx ports: - 4400:80
Open in the browser: http://localhost:4400
and see the standard greeting
nginx.
Now we configure nginx to give the static contents of the folder
./www/public
.
First create folders
mkdir -pv www/public
Create a file ./www/pulbic/index.html
<!-- www/public/index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>Hello World!</h1> </body> </html>
Create a nginx configuration file - nginx/conf/custom.conf
. To start
copy the standard /etc/nginx/conf.d/default.conf
.
Change docker-compose.yml
services: nginx: image: nginx + volumes: + - ./nginx/conf/custom.conf:/etc/nginx/conf.d/default.conf ports: - 4400:80
Recreate nginx container
docker-compose up -d
And once again we see in the browser at http://localhost:4400
standard
greeting nginx.
Make changes
docker-compose.yml
image: nginx volumes: - ./nginx/conf/custom.conf:/etc/nginx/conf.d/default.conf + - ./www:/www ports: - 4400:80
nginx/conf/custom.conf
#access_log /var/log/nginx/host.access.log main; location / { - root /usr/share/nginx/html; + root /www/public; index index.html index.htm; }
Now, at http://localhost:4400
, 'Hello World!' Is displayed. from file
www/public/index.html
.
Breakthrough is difficult to call, but we are definitely moving in the right direction.
Let's start by creating folders for storing container settings files.
mkdir -pv php/conf
Next, create a php/Dockerfile
FROM php:7-fpm RUN apt-get -qq update && apt-get -qq install \ curl \ > /dev/null ENV PHPREDIS_VERSION 3.0.0 RUN mkdir -p /usr/src/php/ext/redis \ && curl -L https://github.com/phpredis/phpredis/archive/$PHPREDIS_VERSION.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \ && echo 'redis' >> /usr/src/php-available-exts \ && docker-php-ext-install redis
And make changes to docker-compose.yml
- ./www:/www ports: - 4400:80 + php: + build: ./php + volumes: + - ./www:/www + environment: + - REDIS_PASSWORD=${REDIS_PASSWORD}
We also need to make changes to the nginx settings so that the files with the extension
.php
processed by php-fpm
.
Modify the nginx/conf/custom.conf
file as follows
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # -#location ~ \.php$ { -# root html; -# fastcgi_pass 127.0.0.1:9000; -# fastcgi_index index.php; -# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; -# include fastcgi_params; -#} +location ~ \.php$ { + root /www; + fastcgi_pass php:9000; + fastcgi_index index.php; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param CONTENT_TYPE $content_type; + fastcgi_param CONTENT_LENGTH $content_length; + fastcgi_param SCRIPT_FILENAME /www/public/$fastcgi_script_name; + include fastcgi_params; +}
It remains to create the file www/public/info.php
with the following code
<?php phpinfo();
Restart our container
docker-compose restart
And now at http://localhost:4400/info.php
information about
php settings
Experiment a little more and create the file www/Test.php
<?php class Test { public function prn() { echo 'Success'; } }
And the contents of the file www/public/info.php
replace with the following:
<?php require_once( implode( DIRECTORY_SEPARATOR, [ dirname(__DIR__), 'Test.php' ] ) ); $test = new Test(); $test->prn();
Now at the address http://localhost:4400/info.php
'success' is displayed, and this
means that php-fpm
scripts are located in the www
folder, and through
browser they are not available. Those. we keep moving in the right direction.
This is perhaps the shortest part.
Redis in this project will not be accessible from the external network, but password protection
set up.
To do this, create a file .env
REDIS_PASSWORD=eustatos
Make changes to docker-compose.yml
build: ./php volumes: - ./www:/www + redis: + image: redis + command: ["sh", "-c", "exec redis-server --requirepass \"${REDIS_PASSWORD}\""]
To test the connection to redis, edit the file www/public/info.php
<?php $redis = new Redis(); // redis $redis->connect( 'redis', 6379 ); // . 'eustatos' - , `.env` $redis->auth($_ENV['REDIS_PASSWORD']); // 'eustatos' $redis->publish( 'eustatos', json_encode([ 'test' => 'success' ]) ); // $redis->close();
Restart the container
docker-compose restart
Now connect to the redis server
docker-compose exec redis bash
Let's go to the command line. 'eustatos' is the password we previously set in
the .env
file
# redis-cli -a eustatos
Subscribe to the 'eustatos' channel (the name is arbitrary, so that everything works,
match the channel name that we defined in the file
www/public/info.php
)
> subscribe eustatos
After all these preparations, go to the browser at
http://localhost:4400/info.php
and watch, as in the terminal, where we
connected to redis appear about the following lines:
1) "message" 2) "eustatos" 3) "{\"test\":\"success\"}"
So we have become even closer to our goal.
Create a folder where our socket.io server files will be located
mkdir socket
Make changes to docker-compose.yml
redis: image: redis command: ["sh", "-c", "exec redis-server --requirepass \"${REDIS_PASSWORD}\""] + socket: + image: node + user: "node" + volumes: + - ./socket:/home/node/app + ports: + - 5000:5000 + working_dir: /home/node/app + command: "npm start"
Go to the socket
folder
cd socket
Install the necessary packages
npm init -y npm i -S socket.io redis express
After that, add lines to the file socket/package.json
{ "name": "socket-php-example", "version": "1.0.0", "main": "index.js", "author": "eustatos <astashkinav@gmail.com>", "license": "MIT", + "scripts": { + "start": "node index.js" + }, "dependencies": { "express": "^4.16.3", "redis": "^2.8.0", "socket.io": "^2.1.0" } }
Create the file socket/index.js
const express = require('express'); const app = express(); const http = require('http').Server(app); const port = process.env.PORT || 5000; app.get( '/', function(req, res, next) { res.send('success'); } ); http.listen( port, function() { console.log('Listen at ' + port); } );
Restart our container
docker-compose restart
After that, the browser at http://localhost:5000
displays "success".
So we are a little closer to our goal. There are very few.
Change the file socket/index.js
const express = require('express'); const app = express(); const http = require('http').Server(app); const io = require('socket.io')(http); // redis const subscriber = require('redis').createClient({ host: 'redis', port: 6379, password: 'eustatos' }); // redis subscriber.on('message', function(channel, message) { // redis socket.io io.emit('eustatosRoom', message); }); // socket.io io.on('connection', function(socket){ // redis 'eustatos' callback subscriber.subscribe('eustatos'); }); const port = process.env.PORT || 5000; http.listen( port, function() { console.log('Listen at ' + port); } );
This completes the socket.io container configuration.
The client application can be deployed in any of our containers, but
for the purity of the experiment, deploy it in a separate container.
We will place the client application files in the client
folder.
mkdir client
Create a file client/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.min.js"></script> <script> const socket = io( window.location.protocol + '//' + window.location.hostname + ':5000' ); socket.on( 'eustatosRoom', function(message) { console.log(JSON.parse(message)); } ); </script> </body> </html>
Change docker-compose.yml
ports: - 5000:5000 command: "npm start" + client: + image: nginx + volumes: + - ./client:/usr/share/nginx/html + ports: + - 8000:80
Restart our container
docker-compose restart
First open in the browser http://localhost:8000
. To demonstrate the result
Our works need to open the developer panel.
Nothing is displayed yet.
Open the address http://localhost:4400/info.php
in another tab or window and look at the console panel of our client’s developer. We should see:
{test: "success"}
This means that our server has successfully transferred data to the client application.
Source: https://habr.com/ru/post/353212/