SimpleSAMLphp and Docker Step by Step Technical Notes

Run SimpleSAMLphp using Docker

SimpleSAMLphp is a great application with stellar reputation, pretty much the only game in town in the PHP world. However, documentation lacks examples and it is quite technical. The notes below will provide much needed context and example as to how to run SimpleSAMLphp with Docker.

Download source code

First thing is first, we need to download the source code from https://simplesamlphp.org/download/ as outlined in the SimpleSAMLphp documentation. Alternatively, you could download SimpleSAMLphp via composer, but we are going to follow the official documentation and not venture down undocumented paths.

Version of SimpleSAMLphp used is 2.0.0

Building the Docker environment

We are going to start by putting together a Docker environment using docker-compose and then we will configure the environment.

Docker Compose

To start off, you can go to phpdocker.io and generate a PHP Docker environment in 30 seconds and save yourself hours of debugging. Make sure you include the following extensions:

  • Bcmath
  • Mcrypt
  • Mysql
  • Redis
  • Intl
  • sqlite3
  • Xdebug

In code (Dockerfile) this would look like so:

RUN apt-get update; \
    apt-get -y --no-install-recommends install \
        git \
        php8.1-bcmath \
        php8.1-mcrypt \
        php8.1-mysql \
        php8.1-redis \
        php8.1-intl \
        php8.1-sqlite3 \
        php8.1-xdebug; \
    apt-get clean; \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*

After generating a base environment, drag it into your project using your favorite IDE, your directory structure should look like this:

Also make sure to include GIT and MySQL. You can do all that right in the phpdocker.io UI. Generate the Docker environment and add it to your project. Then, kick it off using docker-compose:

docker-compose up

Generate self-signed SSL certificate

SimpleSAMLphp prefers to work over SSL even for development. There is a way to configure it to work over http but the https route is preferred. We will store them in phpdocker/nginx/certificates, you should go ahead and create the certificates directory.

To generate self-signed SSL certificate, we are going to use opnssl and run the following command:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout phpdocker/nginx/certificates/nginx-selfsigned.key -out phpdocker/nginx/certificates/nginx-selfsigned.crt

This will dump our key and crt files right into the desired directory. We will need to mount those endpoints to the webserver container` like so:

            - './phpdocker/nginx/certificates/nginx-selfsigned.key:/etc/ssl/private/nginx-selfsigned.key'
            - './phpdocker/nginx/certificates/nginx-selfsigned.crt:/etc/ssl/certs/nginx-selfsigned.crt'

Here is what your docker-compose should look like

version: '3.1'
services:
    redis:
        image: 'redis:alpine'

    mysql:
        image: 'mysql:8.0'
        working_dir: /application
        volumes:
            - '.:/application'
        environment:
            - MYSQL_ROOT_PASSWORD=root
            - MYSQL_DATABASE=app
            - MYSQL_USER=app
            - MYSQL_PASSWORD=app
        ports:
            - '6202:3306'

    webserver:
        image: 'nginx:alpine'
        working_dir: /application
        volumes:
            - '.:/application'
            - './phpdocker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf'
            - './phpdocker/nginx/certificates/nginx-selfsigned.key:/etc/ssl/private/nginx-selfsigned.key'
            - './phpdocker/nginx/certificates/nginx-selfsigned.crt:/etc/ssl/certs/nginx-selfsigned.crt'
        ports:
            - '6200:443'

    php-fpm:
        build: phpdocker/php-fpm
        working_dir: /application
        volumes:
            - '.:/application'
            - './phpdocker/php-fpm/php-ini-overrides.ini:/etc/php/8.1/fpm/conf.d/99-overrides.ini'

Please rebuild and start your containers like so:

docker-compose down && docker-compose up --build

This will spin up your Docker environment. Now is as good time as ever to run composer install and see if there are any missing extensions. We want to make sure that composer install completes and installs all dependencies of SimpleSAMLphp.

composer install

This is what composer install should look like:

Configuring Nginx

We would need to make some configuration changes to the nginx config. We would need to make it compatible with SimpleSAMLphp. The nginx.conf file is located at phpdocker/nginx/nginx.conf

We would need to also configure this setup to work via SSL and issue self-signed SSL certificates.

Here is what your config file should look like:

server {
    listen                  443 ssl;
    listen                  [::]:443 ssl;

    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_ciphers EECDH+AESGCM:EDH+AESGCM;

    client_max_body_size 108M;

    access_log /var/log/nginx/application.access.log;

    location ^~ / {
        alias /application/www/;
        autoindex on;
        index index.php;

        location ~ ^(?<prefix>/)(?<phpfile>.+?\.php)(?<pathinfo>/.*)?$ {
            include fastcgi_params;
            fastcgi_pass php-fpm:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$phpfile;

            # Must be prepended with the baseurlpath
            fastcgi_param SCRIPT_NAME /$phpfile;

            fastcgi_param PATH_INFO $pathinfo if_not_empty;
        }
    }
}

Minimal configuration of SimpleSAMLphp

The goal of these technical notes are to run SimpleSAMLphp with minimum configuration. We need to ensure the following configuration in config/config.php.

Base URL path

We need the absolute URL with an HTTPS prefix.

'baseurlpath' => 'https://localhost:6200/'
Session cookie secure

This setting will ensure that SimpleSAMLphp will only be accessible via SSL, which is what we want.

'session.cookie.secure' => true
Admin password

You need to update the admin password in order to login as an admin. Using the default password will not let you login even if this is just a local development / experimental deployment.

'auth.adminpassword' => '<some secure value please>'

Test SimpleSAMLphp using your Docker configuration

At this point, we should have the PHP and Nginx containers configured, SSL certificates issued and it is a good time to start it all and see if it lights up like this:

docker-compose down && docker-compose up --build

The command above will bring down all running containers specified in our docker-compose.yml and will rebuild them and spin them up.

You should see the welcome page at: https://localhost:6200 and should look like this:

Next, we would want to login as an admin, we can navigate to https://localhost:6200/module.php/admin and login using the password we defined in the config section above. Login page looks like this

You are done, happy SSO-ing!