Install Piwigo Photo Gallery on CentOS 7

Table of Contents

Introduction

Piwigo is a full-featured photo gallery that can be self-hosted. This may be a preferred option if you don't feel like entrusting your photos and content to a third-party running closed-source software. This is a mature open-source project that had its start in 2001 as PhpWebGallery.

We are going to go through the install process for Piwigo. The requirements are fairly flexible. We'll need to choose a webserver (Apache, Nginx, or Lighttpd), install a database (MySQL compatible), PHP 5 along with a few extensions, and ImageMagick. For this tutorial lets go with Lighttpd and MariaDB.

To get started, make sure you have a CentOS 7 server provisioned with SSH access available. Most commands in this tutorial assume you are logged in as a user with sudo access. If you choose to run as root, then you can remove sudo from the beginning of the examples.

Installation

Lighttpd

We'll start off with installation of the web server, Lighttpd. It is available for CentOS 7 as a package in the EPEL repository. To install the EPEL repo, run:

sudo yum install epel-release

You'll be prompted to install the epel-release package and will likely need to confirm the import of a GPG key.

Then we can check for available updates:

sudo yum check-update

The list of available updates will vary quite a bit depending on when you last updated your server. Install all available updates unless you have some good reason not to.

sudo yum update

Install Lighttpd and a couple other packages we'll need later on:

  • lighttpd-fastcgi will let Lighttpd integrate with PHP-FPM.
  • policycoreutils-python will let us manage SELinux.

    sudo yum install lighttpd lighttpd-fastcgi policycoreutils-python

Configure the server to start lighttpd during boot:

sudo systemctl enable lighttpd

Start the daemon right now:

sudo systemctl start lighttpd

Add a firewall rule to permit access to port 80 that will survive reboots:

sudo firewall-cmd --permanent --add-port=80/tcp

Open port 80 right now:

sudo firewall-cmd --add-port=80/tcp

sudo firewall-cmd --reload

Edit /etc/lighttpd/lighttpd.conf and make a couple changes. We don't need to use ipv6 for this tutorial, so lets disable it. Around line 93, change it so that:

 90 ##
 91 ## Use IPv6?
 92 ##
 93 server.use-ipv6 = "enable"

becomes:

 server.use-ipv6 = "disable"

Note: As a reminder, if you are using vi and want to see line numbers, you can escape to command mode, and run :set nu to get them to display.

Also drop down to around line 209 and change:

207 ## With SELinux enabled, this is denied by default and needs to be allowed
208 ## by running the following once : setsebool -P httpd_setrlimit on
209 #server.max-fds = 2048

so that line 209 is uncommented:

 server.max-fds = 2048

Now run sudo sestatus and if it shows that SELinux is enabled and enforcing, then you want to run:

sudo setsebool -P httpd_setrlimit on

and then restart Lighttpd:

sudo systemctl stop lighttpd

sudo systemctl start lighttpd

Making those changes will prevent this warning (regarding file descriptors) from appearing in /var/log/messages when the server starts.

centos lighttpd: 2017-11-10 21:29:56: (server.c.1441) can't have more connections than fds/2:  1024 1024

Instead, you should see this logged (sudo tail /var/log/messages):

Nov 10 21:42:12 centos setsebool: The httpd_setrlimit policy boolean was changed to on by root
Nov 10 21:42:25 centos systemd: Started Lightning Fast Webserver With Light System Requirements.
Nov 10 21:42:25 centos systemd: Starting Lightning Fast Webserver With Light System Requirements...

If you open your browser and visit the IP address of your CentOS 7 server (http://YOUR_SERVER_IP), you should see the default Lighttpd index page.

Lighttpd Default Index Page

MariaDB

Next up is a database. You could use the versions of either MySQL or MariaDB included in the default repositories, but we'll go ahead and add a specific repository from MariaDB.org in order to get the latest 10.2 release of MariaDB.

We'll need to create a new file /etc/yum.repos.d/MariaDB.repo file with the following contents.

# MariaDB 10.2 CentOS repository list - created 2017-11-10 20:37 UTC
# http://downloads.mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

Then run:

sudo yum install MariaDB-server MariaDB-client

You should see quite a bit of output including this:

Dependencies Resolved

============================================================================================================================
 Package                                Arch                  Version                          Repository              Size
============================================================================================================================
Installing:
 MariaDB-client                         x86_64                10.2.10-1.el7.centos             mariadb                 48 M
 MariaDB-compat                         x86_64                10.2.10-1.el7.centos             mariadb                2.8 M
 replacing  mariadb-libs.x86_64 1:5.5.56-2.el7
 MariaDB-server                         x86_64                10.2.10-1.el7.centos             mariadb                108 M
Installing for dependencies:
 MariaDB-common                         x86_64                10.2.10-1.el7.centos             mariadb                155 k
 boost-program-options                  x86_64                1.53.0-27.el7                    base                   156 k
 galera                                 x86_64                25.3.20-1.rhel7.el7.centos       mariadb                8.0 M
 libaio                                 x86_64                0.3.109-13.el7                   base                    24 k
 perl-Compress-Raw-Bzip2                x86_64                2.061-3.el7                      base                    32 k
perl-Compress-Raw-Zlib                 x86_64                1:2.061-4.el7                    base                    57 k
 perl-DBI                               x86_64                1.627-4.el7                      base                   802 k
 perl-Data-Dumper                       x86_64                2.145-3.el7                      base                    47 k
 perl-IO-Compress                       noarch                2.061-2.el7                      base                   260 k
 perl-Net-Daemon                        noarch                0.48-5.el7                       base                    51 k
 perl-PlRPC                             noarch                0.2020-14.el7                    base                    36 k

Transaction Summary
============================================================================================================================
Install  3 Packages (+11 Dependent packages)

Total download size: 168 M
Is this ok [y/d/N]:

Answer with y to continue. You'll also have to confirm the GPG key.

Retrieving key from https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
Importing GPG key 0x1BB943DB:
 Userid     : "MariaDB Package Signing Key <package-signing-key@mariadb.org>"
 Fingerprint: 1993 69e5 404b d5fc 7d2f e43b cbcb 082a 1bb9 43db
 From       : https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
Is this ok [y/N]:

When the installation completes we will set MariaDB to start during boot:

sudo systemctl enable mariadb

Start MariaDB right now:

sudo systemctl start mariadb

And then secure the installation with a password:

sudo mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
  SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] Y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

Important: Make a note of the password you set, as we'll need it shortly when adding a database for Piwigo to use.

PHP

Piwigo does not show PHP 7 as a requirement, so we will utilize the current version of PHP 5.4 available in the default CentOS 7 repositories. While we are installing PHP, lets include a few other packages necessary to finish up this tutorial.

  • php-gd lets us upload images directly from the Piwigo web interface.
  • php-mysqlnd is needed to let PHP communicate with MariaDB via the mysqli extension.
  • ImageMagick is used to resize and manipulate images.

    sudo yum install php-fpm php-gd php-mysql ImageMagick

You'll be presented with a big block of output related to packages and dependencies that should end with this prompt:

Transaction Summary
======================================================================================================================================
Install  4 Packages (+53 Dependent packages)

Total download size: 21 M
Installed size: 69 M
Is this ok [y/d/N]:

There are a large number of dependencies for these packages. Go ahead and respond with y and it should all install quickly.

We are going to switch the user that php-fpm runs as to have it match lighttpd for convenience.

sudo vi /etc/php-fpm.d/www.conf

Modify lines 39 and 40 so that this:

35 ; Unix user/group of processes
36 ; Note: The user is mandatory. If the group is not set, the default user's group
37 ;       will be used.
38 ; RPM: apache Choosed to be able to access some dir as httpd
39 user = apache
40 ; RPM: Keep a group allowed to write in log dir.
41 group = apache

becomes:

user = lighttpd

group = lighttpd

Save the file and exit.

Now we will edit /etc/php.ini to set our timezone on or about line 878.

sudo vi /etc/php.ini

You can get there quickly by searching for "timezone". You should see these lines:

875 [Date]
876 ; Defines the default timezone used by the date functions
877 ; http://php.net/date.timezone
878 ;date.timezone =

You should uncomment line 878 and set an appropriate timezone value. The comments indicate where you can locate information on valid timezone values. I'm going to use "America/Los_Angeles" as I'm on the Pacific coast of the USA.

date.timezone = "America/Los_Angeles"

Now we need to enable FastCGI support by editing /etc/lighttpd/modules.conf:

sudo vi /etc/lighttpd/modules.conf

Uncomment line 138 so that this:

135 ##
136 ## FastCGI (mod_fastcgi)
137 ##
138 #include "conf.d/fastcgi.conf"

becomes:

include "conf.d/fastcgi.conf"

Then save and exit.

Now to configure PHP support in /etc/lighttpd/conf.d/fastcgi.conf:

vi /etc/lighttpd/conf.d/fastcgi.conf

Near the top of the file, right above the commented "## PHP Example", you can place these lines:

fastcgi.server += ( ".php" =>
    ((
            "host" => "127.0.0.1",
            "port" => "9000",
            "broken-scriptfilename" => "enable"
    ))
)

Go ahead and save and exit the editor. Lets start up php-fpm and restart lighttpd:

sudo systemctl enable php-fpm

sudo systemctl start php-fpm

sudo systemctl restart lighttpd

The last few lines of /var/log/messages should indicate this worked:

Nov 10 22:30:50 centos systemd: Reloading.
Nov 10 22:30:55 centos systemd: Starting The PHP FastCGI Process Manager...
Nov 10 22:30:55 centos systemd: Started The PHP FastCGI Process Manager.
Nov 10 22:31:03 centos systemd: Stopping Lightning Fast Webserver With Light System Requirements...
Nov 10 22:31:03 centos systemd: Started Lightning Fast Webserver With Light System Requirements.
Nov 10 22:31:03 centos systemd: Starting Lightning Fast Webserver With Light System Requirements...

We can double-check everything is good by creating a test_page.php and checking it in our browser.

sudo vi /var/www/lighttpd/test_page.php

Paste these contents into the file:

<?php
  phpinfo();
?>

Save, exit, and then bring up http://YOUR_SERVER_IP/test_page.php and you should see:

PHP Info Page

Configuration

Prepare a Piwigo Database

The Piwigo installation will need to have access to a database, so lets create one, along with a user specifically for Piwigo.

mysql -u root -p -e "CREATE DATABASE piwigodb"

Enter the database password that you set earlier during the run ofmysql_secure_installation.

Now we'll add the user, assign them a password, and give them full permissions to piwigodb:

mysql -u root -p -e "GRANT ALL PRIVILEGES ON piwigodb.* to 'piwigouser'@'localhost' IDENTIFIED BY 'SoMePaSsWoRd'"

Note: Please change SoMePaSsWoRd to a password of your choice.

Finally we'll reload the database privileges:

mysql -u root -p -e "FLUSH PRIVILEGES"

Allow Piwigo Write Access to the Web Root

We checked on SELinux earlier, but just to confirm:

sudo sestatus

If it responds with:

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

Then SELinux is "enabled" and "enforcing". We need to adjust the security context to permit lighttpd and php-fpm to write into our web root /var/www/lighttpd

semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/lighttpd(/.*)?"

We don't expect any output from that command. Now run:

restorecon -R -v /var/www/lighttpd

Which should result in some output as the context of various files is adjusted.

restorecon reset /var/www/lighttpd context system_u:object_r:httpd_sys_content_t:s0->system_u:object_r:httpd_sys_rw_content_t:s0
restorecon reset /var/www/lighttpd/light_logo.png context system_u:object_r:httpd_sys_content_t:s0->system_u:object_r:httpd_sys_rw_content_t:s0
restorecon reset /var/www/lighttpd/poweredby.png context system_u:object_r:httpd_sys_content_t:s0->system_u:object_r:httpd_sys_rw_content_t:s0
restorecon reset /var/www/lighttpd/light_button.png context system_u:object_r:httpd_sys_content_t:s0->system_u:object_r:httpd_sys_rw_content_t:s0
restorecon reset /var/www/lighttpd/favicon.ico context system_u:object_r:httpd_sys_content_t:s0->system_u:object_r:httpd_sys_rw_content_t:s0
restorecon reset /var/www/lighttpd/index.html context system_u:object_r:httpd_sys_content_t:s0->system_u:object_r:httpd_sys_rw_content_t:s0
restorecon reset /var/www/lighttpd/test_page.php context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_sys_rw_content_t:s0

We can confirm by looking for httpd_sys_rw_content_t in the output of:

sudo ls -Z lighttpd

-rw-r--r--. root root system_u:object_r:httpd_sys_rw_content_t:s0 favicon.ico
-rw-r--r--. root root system_u:object_r:httpd_sys_rw_content_t:s0 index.html
-rw-r--r--. root root system_u:object_r:httpd_sys_rw_content_t:s0 light_button.png
-rw-r--r--. root root system_u:object_r:httpd_sys_rw_content_t:s0 light_logo.png
lrwxrwxrwx. root root system_u:object_r:httpd_sys_rw_content_t:s0 poweredby.png -> /usr/share/pixmaps/poweredby.png
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_rw_content_t:s0 test_page.php

Install Piwigo

Well, that was quite a bit of prep work, and now that it is completed, lets finally move on to install Piwigo itself.

This section is just simpler to run as root due to permissions, so please use sudo su - if you are not already root.

We'll use curl to download the install script directly from the Piwigo website.

curl "http://piwigo.org/download/dlcounter.php?code=netinstall" > /var/www/lighttpd/piwigo_install.php

Now switch to your browser and visit http://YOUR_SERVER_IP/piwigo_install.php where you should see the NetInstall page.

Piwigo NetInstall

If you happened to skip the SELinux configuration, or have some sort of permissions/ownership issue that is preventing write access to /var/www/lighttpd/, then you may see this screen instead.

Piwigo NetInstall Write Access Issue

Lets proceed by pressing the big Retrieve and unzip Piwigo button. It will download and unzip the install files. You'll see this screen once it completes.

Piwigo NetInstall Proceed

Press the "Install Piwigo Now" button to proceed.

Piwigo NetInstall Proceed

You'll need to complete the fields on that screen. In the "Database configuration" section, the "User" will be piwigouser with the password that you set earlier. The "Database name" will be piwigodb.

In the "Administration configuration" section, you can set those values as you see fit.

Piwigo NetInstall Values

Press the Start installation button to finish up. You should be rewarded with a congratulatory screen.

Piwigo NetInstall Congrats

If you Visit the gallery you can take a quick tour of Piwigo.

Piwigo Start Tour

You will end up in the Admin section of Piwigo. You can Start the Tour or use the deactivate the tour message.

Piwigo Default Gallery

Conclusion

At this point I'll turn you loose to play around with Piwigo further. There are a number of plugins available via the Administration interface that can be installed to add features to your gallery.

Please comment below if you ran into any issues following this tutorial. I'll see what I can do to lend a hand in getting them resolved. Stay tuned for a follow-up tutorial on securing your new Piwigo gallery with SSL/TLS.