Tutorial

How to Set Up a Redis Server as a Session Handler for PHP on Ubuntu 14.04

Published on August 21, 2015
Default avatar

By Erika Heidi

Developer Advocate

How to Set Up a Redis Server as a Session Handler for PHP on Ubuntu 14.04

Introduction

Redis is an open source key-value cache and storage system, also referred to as a data structure server for its advanced support for several data types, such as hashes, lists, sets, and bitmaps, amongst others. It also supports clustering, which makes it often used for highly-available and scalable environments.

In this tutorial, we’ll see how to install and configure an external Redis server to be used as a session handler for a PHP application running on Ubuntu 14.04.

The session handler is responsible for storing and retrieving data saved into sessions - by default, PHP uses files for that. An external session handler can be used for creating scalable PHP environments behind a load balancer, where all application nodes will connect to a central server to share session information.

Prerequisites

We will be working with two distinct servers in this tutorial. For security and performance reasons, it’s important that both Droplets are located in the same datacenter with private networking enabled. This is what you will need:

  • A PHP web server running LAMP or LEMP on Ubuntu 14.04 - we will refer to this server as web
  • A second, clean Ubuntu 14.04 server where Redis will be installed - we will refer to this server as redis

You’ll need proper SSH access to both servers as a regular user with sudo permission.

For the Redis server, you can also use our Redis One-Click Application and skip to Step 2.

Step 1 — Install the Redis Server

The first thing we need to do is get the Redis server up and running, on our redis Droplet.

We will be using the regular Ubuntu package manager with a trusted PPA repository provided by Chris Lea. This is necessary to make sure we get the latest stable version of Redis.

As a general piece of security advice, you should only use PPAs from trusted sources.

First, add the PPA repository by running:

  1. sudo add-apt-repository ppa:chris-lea/redis-server

Press ENTER to confirm.

Now you need to update the package manager cache:

  1. sudo apt-get update

And finally, let’s install Redis by running:

  1. sudo apt-get install redis-server

Redis should now be installed on your server. To test the installation, try this command:

  1. redis-cli ping

This will connect to a Redis instance running on localhost on port 6379. You should get a PONG as response.

Step 2 — Configure Redis to Accept External Connections

By default, Redis only allows connections to localhost, which basically means you´ll only have access from inside the server where Redis is installed. We need to change this configuration to allow connections coming from other servers on the same private network as the redis server.

The first thing we need to do is find out the private network IP address of the Redis machine. The following steps should be executed on the redis server.

Run ifconfig to get information about your network interfaces:

  1. sudo ifconfig

You should get an output similar to this:

Output
eth0 Link encap:Ethernet HWaddr 04:01:63:7e:a4:01 inet addr:188.166.77.33 Bcast:188.166.127.255 Mask:255.255.192.0 inet6 addr: fe80::601:63ff:fe7e:a401/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:3497 errors:0 dropped:0 overruns:0 frame:0 TX packets:3554 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:4895060 (4.8 MB) TX bytes:619070 (619.0 KB) eth1 Link encap:Ethernet HWaddr 04:01:63:7e:a4:02 inet addr:10.133.14.9 Bcast:10.133.255.255 Mask:255.255.0.0 inet6 addr: fe80::601:63ff:fe7e:a402/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:7 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:648 (648.0 B) TX bytes:578 (578.0 B)

Look for the inet_addr assigned to the eth1 interface. In this case, it’s 10.133.14.9 - this is the IP address we will be using later to connect to the redis server from the web server.

Using your favorite command line editor, open the file /etc/redis/redis.conf and look for the line that contains the bind definition. You should add your private network IP address to the line, as follows:

  1. sudo vim /etc/redis/redis.conf
/etc/redis/redis.conf
bind localhost 10.133.14.9

If you see 127.0.0.1 instead of localhost that’s fine; just add your private IP after what’s already there.

Now you just need to restart the Redis service to apply the changes:

  1. sudo service redis-server restart

If you installed Redis using our One-click application, the service name will be redis instead of redis-server. To restart it, you should run: sudo service redis restart .

With this change, any server inside the same private network will also be able to connect to this Redis instance.

Step 3 — Set a Password for the Redis Server

To add an extra layer of security to your Redis installation, you are encouraged to set a password for accessing the server data. We will edit the same configuration file from the previous step, /etc/redis/redis.conf:

  1. sudo vim /etc/redis/redis.conf

Now, uncomment the line that contains requirepass, and set a strong password:

/etc/redis/redis.conf
requirepass yourverycomplexpasswordhere

Restart the Redis service so the changes take effect:

  1. sudo service redis-server restart

Step 4 — Test Redis Connection and Authentication

To test if all your changes worked as expected, connect to the Redis service from inside the redis machine:

  1. redis-cli -h 10.133.14.9
Output
10.133.14.9:6379>

Even though it´s not mandatory to specify the host parameter here (since we are connecting from localhost), we did it to make sure the Redis service will accept connections targeted at the private network interface.

If you defined a password and now try to access the data, you should get an AUTH error:

  1. keys *
Output
(error) NOAUTH Authentication required.

To authenticate, you just need to run the AUTH command, providing the same password you defined in the /etc/redis/redis.conf file:

  1. AUTH yourverycomplexpasswordhere

You should get an OK as response. Now if you run:

  1. keys *

The output should be similar to this:

Output
(empty list or set)

This output just means your Redis server is empty, which is exactly what we expected, since the web server is not yet configured to use this Redis server as a session handler.

Keep this SSH session opened and connected to the redis-cli while we perform the next steps - we will get back to the redis-cli prompt to check if the session data is being properly stored, after we make the necessary changes to the web server.

Step 5 — Install the Redis Extension on the Web Server

The next steps should be executed on the web server. We need to install the PHP Redis extension, otherwise PHP won’t be able to connect to the Redis server.

First, update your package manager cache by running:

  1. sudo apt-get update

Then install the php5-redis package:

  1. sudo apt-get install php5-redis

Your web server should now be able to connect to Redis.

Step 6 — Set Redis as the Default Session Handler on the Web Server

Now we need to edit the php.ini file on the web server to change the default session handler for PHP. The location of this file will depend on your current stack. For a LAMP stack on Ubuntu 14.04, this is usually /etc/php5/apache2/php.ini. For a LEMP stack on Ubuntu 14.04, the path is usually /etc/php5/fpm/php.ini.

If you are unsure about the location of your main php.ini file, an easy way to find out is by using the function phpinfo(). Just place the following code in a file named info.php inside your web root directory:

  1. <?php
  2. phpinfo();

When accessing the script from your browser, look for the row containing “Loaded Configuration File”, and you should find the exact location of the main php.ini loaded.

Don’t forget to remove the info.php file afterwards, as it contains sensitive information about your environment.

Open your php.ini file and search for the line containing session.save_handler. The default value is files. You should change it to redis.

On LAMP environments:

  1. sudo vim /etc/php5/apache2/php.ini

On LEMP environments:

  1. sudo vim /etc/php5/fpm/php.ini
[label /etc/php5/fpm/php.ini] 
session.save_handler = redis

Now you should find the line containing session.save_path. Uncomment it and change the value so it contains the Redis connection string. The content should follow this format, all in one line: tcp://IPADDRESS:PORT?auth=REDISPASSWORD

[label /etc/php5/fpm/php.ini] 
session.save_path = "tcp://10.133.14.9:6379?auth=yourverycomplexpasswordhere"

You only need to provide the parameter auth if you did set a password when configuring Redis.

Save the file and restart the php service.

On LAMP environments:

  1. sudo service apache2 restart

On LEMP environments:

  1. sudo service php5-fpm restart

Step 7 — Test Redis Session Handling

To make sure your sessions are now handled by Redis, you will need a PHP script or application that stores information on sessions. We are going to use a simple script that implements a counter - each time you reload the page, the printed number is incremented.

Create a file named test.php on the web server and place it inside your document root folder:

  1. sudo vim /usr/share/nginx/html/test.php

Don’t forget to change /usr/share/nginx/html to reflect your document root path.

  1. [label /usr/share/nginx/html/test.php]
  2. <?php
  3. //simple counter to test sessions. should increment on each page reload.
  4. session_start();
  5. $count = isset($_SESSION['count']) ? $_SESSION['count'] : 1;
  6. echo $count;
  • $_SESSION['count'] = ++$count;
  • Point your browser to http://web/test.php in order to access the script. It should increment the number each time you reload the page.

    Now you should have session information stored on the Redis server. To verify, go back to your SSH session on the redis machine, where we previously connected to the Redis service using redis-cli. Fetch the content again with keys *:

    1. keys *

    And you should get an output similar to this:

    Output
    1) "PHPREDIS_SESSION:j9rsgtde6st2rqb6lu5u6f4h83"

    This shows that the session information is being stored on the Redis server. You can connect additional web servers to the Redis server in a similar way.

    Conclusion

    Redis is a powerful and fast key-value storage service that can also be used as session handler for PHP, enabling scalable PHP environments by providing a distributed system for session storage. For more information about scaling PHP applications, you can check this article: Horizontally Scaling PHP Applications.

    Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

    Learn more about us


    About the authors
    Default avatar

    Developer Advocate

    Dev/Ops passionate about open source, PHP, and Linux.



    Still looking for an answer?

    Ask a questionSearch for more help

    Was this helpful?
     
    10 Comments
    

    This textbox defaults to using Markdown to format your answer.

    You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

    How do you handle cleaning up expired sessions using this method? Will allkeys-lru maxmemory-policy work, or does an explicit expiration need to be set?

    If you are using PHP 7.0 FPM, whether you are using Nginx or Apache, if you realise the instructions above doesn’t work for you, and redis-cli doesn’t show your saved session.

    you should go to the following file

     /etc/php/7.0/mods-available/redis.ini
    

    and add the following lines

    session.save_handler = redis
    session.save_path = "tcp://127.0.0.1:6379?auth=supercomplexpasswordthatyousetbefore"
    

    save and exit, and restart php fpm

    sudo service php7.0-fpm restart
    

    Your session should now show when you type keys *

    I’m using Ubuntu 16.04

    ahah if you don’t mention to remove the “;” bracket off from session.save_path line…

    It’s your fault not mine

    You cant forget to install php5-redis or php5.6-redis

    I’m using php 7. The test.php prints nothing, after i type keys * it always prints empty list or set. I try to run my Magento 2 website and i got an error:

    "Warning: SessionHandler::read(): open(tcp://167.99.64.XXX:6379?auth=veryExtremePassword/sess_aa6qg576stfhnqedoto6ccpdq2, O_RDWR) failed: No such File or Directory

    @erikaheidi Hey Erika! Thanks for this much!

    I am trying to setup redis in an environment, where I need wordpress to connect securely to a VPS (Digital Ocean droplet) hosting a redis server.

    I have managed this:

    Webserver - > SSH RSA PK AUTH - > Redis VPS

    Now I need this:

    Authenticated Web Server - > Redis Instance - > Object Cache - > Session Handling - > DB store

    Is that doable?

    All default TCP connections are blocked on the droplet Only SSH via RSA is allowed on the droplet

    Hi,

    Can anyone help me with the setup of multi master node redis setup?

    FYI:

    I had used apg to generate a 72 character-long password for my Redis Server and found that tcp:// requests were failing. The password string contained several non-alphanumeric (ie special) characters.

    Solved by:

    Encode the string before sending to a port. I had success with:

    • php: urlencode() - longer
    • -and-
    • js: encodeURIComponent() - shorter

    So in a server environment with a web server and a database server, where would you advise Redis to be installed for best performance?

    Also in this tutorial is redis performing object-caching?

    Thanks, JL

    Great how to! Easy to follow for a novice. Would love to see a how to for getting a php page to make redis set/get calls! I am not having much luck following what’s out on the web.

    Thanks, Jason

    Try DigitalOcean for free

    Click below to sign up and get $200 of credit to try our products over 60 days!

    Sign up

    Join the Tech Talk
    Success! Thank you! Please check your email for further details.

    Please complete your information!

    Get our biweekly newsletter

    Sign up for Infrastructure as a Newsletter.

    Hollie's Hub for Good

    Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

    Become a contributor

    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

    Welcome to the developer cloud

    DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

    Learn more
    DigitalOcean Cloud Control Panel