Fork me on GitHub

Setting up a memcached server with PHP7.X and a NGINX webserver

Memcached server side

This server has private @IP : 192.168.33.14

Install memcached:

sudo apt-get install memcached

In /etc/memcached.conf, set up memory to 256 Mo:

-m 256

In /etc/memcached.conf, set up listening private @IP of the server:

# Specify which IP address to listen on. The default is to listen on all IP addresses
# This parameter is one of the only security measures that memcached has, so make sure
# it's listening on a firewalled interface.
#-l 127.0.0.2
-l 192.168.33.14

Web server side

This server has private @IP : 192.168.33.11

Install PHP extension

On the server that hosts nginx + php7.0:

sudo apt-get install -y php-memcached

Configure PHP

In /etc/php/7.0/fpm/php.ini:

[Session]
; Handler used to store/retrieve data.
; http://php.net/session.save-handler
#session.save_handler = files
session.save_handler = memcached
session.save_path = 'tcp://192.162.33.14:11211'

Restart services

sudo service php7.0-fpm restart && sudo service nginx restart

Check config

Create a phpinfo.php that calls phpinfo() and check memcached configuration.

Checking

Checking sessions are well handled by memcached

Let's write a simple script to check sessions:

session_start();
if(!isset($_SESSION['visit']))
{   
    echo "This is the first time you're visiting this server\n";
    $_SESSION['visit'] = 0;
}   
else
        echo "Your number of visits: ".$_SESSION['visit'] . "\n";

$_SESSION['visit']++;

echo "Server IP: ".$_SERVER['SERVER_ADDR'] . "\n";
echo "Client IP: ".$_SERVER['REMOTE_ADDR'] . "\n";
print_r($_COOKIE);

Checking memcached key/value server

Let's write a simple script to key/value access:

$mem = new Memcached();
$mem->addServer("192.168.33.14", 11211);
$result = $mem->get("blah");
if ($result) {
    echo $result;
} else {
    echo "No matching key found yet. Let's start adding that now!";
    $mem->set("blah", "I am data!  I am held in memcached!") or die("Couldn't save anything to memcached...");
}   

Dumping all key/value records

Sources

  • https://www.digitalocean.com/community/tutorials/how-to-share-php-sessions-on-multiple-memcached-servers-on-ubuntu-14-04
  • http://www.servermom.org/install-use-memcached-nginx-php-7-ubuntu-16-04/3670/

Configure moodle 3.x session handling with memcached

This procedure has been tested on Moodle version 3.0.6+ with a dedicated memcached server which @IP:port is 192.168.33.14:11211.

Set up a memcached server

see this post.

Configure moodle

Configure session handling in config.php:

/********************************************/
//MEMCACHED SETUP
$CFG->session_handler_class = '\core\session\memcached';
$CFG->session_memcached_save_path = '192.168.33.14:11211';
$CFG->session_memcached_prefix = 'memc.sess.key.';
$CFG->session_memcached_acquire_lock_timeout = 120;
$CFG->session_memcached_lock_expire = 7200;       // Ignored if memcached extension <= 2.1.0
/********************************************/

Checkings

If you print out your cookie from your debug tool in your bowser, you well see a cookie named MoodleSession

In my case it has value 4gp94gr17g78jnh97a6mfml0b4

Moodle database

Now let's check if there is still record in DB for your cookie session:

SELECT * FROM mdl_sessions WHERE sid='4gp94gr17g78jnh97a6mfml0b4';

returns:

2507694 0   4gp94gr17g78jnh97a6mfml0b4  48521       1515679016  1515681908  192.168.33.1    192.168.33.1

What ??? I was expecting to have no more entries in the mdl_sessions table. After searching a little bit more, I found the explanation here:

Normally when you have sessions stored in Memcache/d there will still be a record of the session written to mdl_sessions. The session data is not written to the database, it's only written to the memcache/d server itself. The performance gain is seen because the session data is not written every page view for every user, and thus the table rows are not continually being locked and unlocked.

memcached server

Let's check if there is a key/value record for ou session:

run it:

php memcached.php | grep 4gp94gr17g78jnh97a6mfml0b4

prints:

key: memc.sess.key.4gp94gr17g78jnh97a6mfml0b4

which means that our session is written in memcached! That's ok!

Docker 101: basics

Containers

A container is a way to create isolated env that can run code while sharing a single OS.

Run a container

docker container run -p 9999:80 httpd:2.4

The --detach flag can be used to run the container in background:

docker container run --detach -p 9999:80 httpd:2.4

List containers

docker container ls

Run commands on container

docker container exec my_container_name du -mh

Attaching a Shell to a Container

To get a shell inside the container:

docker container exec -it my_container_name /bin/bash

PATH=$PATH:/usr/games/
export PATH

Dockerfiles

Dockerfile -> create an image -> to generate a container

Inside a file named Dockerfile.

Dockerfile example

FROM httpd:2.4
EXPOSE 80
RUN apt-get update && apt-get install -y fortunes
COPY page.html /var/www/html/
LABEL maintainer="moby-dock@example.com"

Building an Image From a Dockerfile

docker image build --tag web-server:1.0 .

End the command with a single . so it knows to look for the Dockerfile in the same folder that the command is run in.

docker image ls


docker container run -p 80:80 web-server:1.0

Volumes

It is possible to copy files into a container but files will be lost when container stops.

docker container cp page.html my_container_name:/var/www/html/.

A better solution is to use volumes. Data volumes expose files on your host machine to the container.

Creating a Volume

docker run -d -p 80:80 -v /my-files:/var/www/html web-server:1.1

Shared folder between /my-files on host machine and the html folder in the container