Actions

Using PHP from docker

From LimeSurvey Manual

Revision as of 13:59, 10 November 2021 by Ollehar (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This document describes how to setup PHP-FPM inside a docker image, using nginx, MySQL and PHP 7.4.

Docker

Dockerfile content:

FROM php:7.4-fpm
RUN docker-php-ext-install mysqli pdo pdo_mysql

To add support for Postgres and GD, use:

FROM php:7.4-fpm
RUN apt-get update
RUN apt-get install -y libpq-dev
RUN apt-get install -y zlib1g-dev libzip-dev libpng-dev
RUN apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libgd-dev
RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql
RUN docker-php-ext-configure gd --with-jpeg=/usr/include/ --with-freetype=/usr/include/
RUN docker-php-ext-install gd
RUN docker-php-ext-install zip
RUN docker-php-ext-install mysqli pdo pdo_mysql pdo_pgsql

For support for SQL Server (mssql), use https://github.com/HasHolding/php-mssql

Build with

# docker build -t my7.4-fpm:latest .

Run with (example with mount points to /var/www/limesurvey):

 # docker run -v /var/www/limesurvey:/var/www/html:rw -v /tmp:/tmp:rw -v /tmp/runtime:/var/www/html/tmp/runtime:rw -v /tmp/assets:/var/www/html/tmp/assets:rw -v /tmp/upload:/var/www/html/upload:rw my7.4-fpm:latest

Replace `/var/www/limesurvey` with your local repo location.

You need to create the folders `/tmp` and `/tmp/runtime` and `/tmp/assets` and `/tmp/upload`. Also see tempdir in config.php.

Easy to replace my7.4-fpm with any PHP version.

nginx

(/etc/nginx/sites-available/default):

location ~ \.php$ {
  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_pass 172.17.0.2:9000;
  fastcgi_index index.php;
  include fastcgi_params;
  root /var/www/html/;
}
root /var/www/html;  # Corresponding folder in docker image
location /tmp/assets {
  alias /tmp/assets;
}
location /assets {
  alias /var/www/limesurvey/assets;
}
location /third_party {
  alias /var/www/limesurvey/third_party;
}
location /themes {
  alias /var/www/limesurvey/themes;
}

config.php

For MySQL running natively:

       'connectionString' => 'mysql:host=172.17.0.1;port=3306;dbname=limesurvey;',
   'tempdir' => '/tmp',

Possible error:

Host '172.17.0.2' is not allowed to connect to this MySQL server

Solution (MySQL 8):

mysql> CREATE USER 'root'@'%' IDENTIFIED BY 'root';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;

For postgres:

'connectionString' => 'pgsql:host=172.17.0.3;port=5432;user=postgres;password=mysecretpassword;dbname=limesurvey;',

NB, 172.17.0.3 depends on the docker image running postgres.

MySQL

I needed to create a user that is allowed to connect from the docker ip, like so:

CREATE USER 'root'@'172.17.0.2' IDENTIFIED BY '<password>';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'172.17.0.2' WITH GRANT OPTION;
FLUSH PRIVILEGES;

where 172.17.0.2 is the IP of the docker PHP FPM pool.

Also make sure remote access is enabled (since docker is "remote"). Run

mysqld --verbose --help | grep bind-address

It should show "bind-address 0.0.0.0". If it doesn't, change config with

vim /etc/mysql/mysql.conf.d/mysqld.cnf

and then restart the MySQL service.

Postgres

To start the postgres docker container, run

# docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres

If it's already created but not started (due do reboot or sim):

# docker start some-postgres

To access postgres through CLI:

# docker exec -it --user postgres some-postgres psql

SQL Server (mssql)

Instructions: https://stackoverflow.com/a/52821353/2138090

Pull with

# docker pull mcr.microsoft.com/mssql/server:2019-latest

Run with

# docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=password123PASSWORD' -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest

Log in with command-line with

# docker exec -it <container id or name> /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P password123PASSWORD

Command-line instructions for SQL Server

Connection string can look like:

'connectionString' => 'sqlsrv:Server=172.17.0.4;Database=limesurvey',

(There is an example config in config folder.)

IP depends on your docker image running. How to get IP of docker container

Command-line

PHP inside docker can be run from command-line too. Here's one example to use php -l for php 8.0:

sudo docker pull php:8.0-cli
sudo docker run -v $(pwd):/app:ro -w /app --rm php:8.0-cli php -l application/helpers/adodb/adodb-time.inc_helper.php