A Very Simple PHP Image Gallery
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
seiichiro 9e3d2bf72a Replace ' in the Whole Image Path 9 months ago
cache Initial Git Commit 1 year ago
conf Move config.php to config.sample.php, Adapt Readme 1 year ago
css Added a Crude Responsive Menu 11 months ago
fonts Add All Font Files 1 year ago
img Handle Unknown Image Types Gracefully 1 year ago
js Initial Git Commit 1 year ago
lib Always use JPEG for Thumbnails 10 months ago
tpl Allow Double Quotes in Image Filenames 9 months ago
.gitignore Move config.php to config.sample.php, Adapt Readme 1 year ago
README.md Even More Readme Adaption 1 year ago
favicon.ico Initial Git Commit 1 year ago
index.php Replace ' in the Whole Image Path 9 months ago


Very Simple PHP Gallery

This is a very simple PHP based image Gallery. It takes all images from one or (or potentially multiple) directories and presents them as a simple web gallery. It will autogenerate thumbnails for the gallery overview and also do variable pagination. There are some simple keyboard shortcuts as well.

DISCLAIMER: This was just quickly hacked together, it might not be up to any quality or security standards. Use at your own risk, especially if exposed to the internet unprotected.

Running it

Copy conf/config.sample.php to config.php and edit accordingly.

A webserver with PHP (tested with 7.4 and 8.0) support and the php-gd and php-exif extensions (for thumbnails) is required. An example config for nginx with php-fpm might look something like this:

worker_processes  4;

events {
    worker_connections  256;

http {
  include       mime.types;
  default_type  application/octet-stream;

  access_log    /var/log/nginx/access.log;
  error_log     /var/log/nginx/error.log info;

  sendfile        on;
  keepalive_timeout  65;

  upstream php-default-handler {
    server unix:/run/php-fpm7/php-fpm.sock;

  server {
    listen 80;
    listen [::]:80;
    server_name gallery.example.com;

    fastcgi_buffers 64 4K;

    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

    add_header Referrer-Policy                      "no-referrer"   always;
    add_header X-Content-Type-Options               "nosniff"       always;
    add_header X-Download-Options                   "noopen"        always;
    add_header X-Frame-Options                      "SAMEORIGIN"    always;
    add_header X-Permitted-Cross-Domain-Policies    "none"          always;
    add_header X-Robots-Tag                         "none"          always;
    add_header X-XSS-Protection                     "1; mode=block" always;

    fastcgi_hide_header X-Powered-By;

    root /var/www/gallery;

    auth_basic           'Picture Gallery';
    auth_basic_user_file /etc/nginx/gallery.users;

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;

    location ~ ^/(?:lib|conf|tpl|cache)(?:$|/)  { return 404; }

    location ~ \.php(?:$|/) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        set $path_info $fastcgi_path_info;

        try_files $fastcgi_script_name =404;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param HTTPS on;

        fastcgi_param modHeadersAvailable true;         # Avoid sending the security headers twice
        fastcgi_param front_controller_active true;     # Enable pretty urls
        fastcgi_pass php-default-handler;

        fastcgi_intercept_errors on;
        fastcgi_read_timeout 300s;
        fastcgi_request_buffering off;

    location ^~ /images {
      alias /path/to/imagedir;

    location ^~ /thumbs {
      alias /path/to/thumbnail/cache;

    location ~ \.(?:css|js|jpeg|png|jpg|webm|webp|gif)$ {
        expires 6M;

    location / {
      index index.php;