PiGallery2
Overview
PiGallery2 3.5.2 on Ubuntu 24.04 LTS is a ready-to-run image from SecureAnyCloud for Microsoft Azure. PiGallery2 is an open source, self-hosted photo gallery. It reads a folder of photos, keeps your folder structure, indexes the files into a small SQLite database, makes thumbnails and serves a web gallery with search, a map of geotagged photos, faces, albums and password-protected sharing links. Your photos stay on your own VM.
What you get:
- HTTPS and a unique admin password from the first boot. PiGallery2 listens on 127.0.0.1 only. nginx serves it on port 443 with a certificate generated on your VM, port 80 redirects to HTTPS, and requests for a host name the VM does not serve get no answer. PiGallery2's own login is on. The
adminpassword is generated on first boot and written to/root/pigallery2-credentials.txt(readable by root only), and PiGallery2 stores only a bcrypt hash of it. The upstream fallback loginadmin/adminis never created, and no secret is baked into the image. - The empty-password login fix. In PiGallery2 3.5.2, a login with a known user name and an empty password is accepted. The PiGallery2 developers fixed this in their code in May 2026, but no release contains the fix yet. This image applies that fix (upstream commit bf910bed3) to 3.5.2, plus a SecureAnyCloud guard that stops a malformed sign-in request from restarting PiGallery2. The image's self test checks that empty, blank, wrong-case and malformed passwords are refused.
- A current runtime and refreshed dependencies. PiGallery2 runs on Node.js 22.23.4 LTS (the October 2026 security release), with image processing by sharp 0.35.5 (libvips 8.18). The libraries pinned by PiGallery2 3.5.2 carried known high and critical vulnerabilities, so they are updated here. The finished tree is scanned against the OSV vulnerability database, with no known advisories at build time. The build record is in
/usr/share/doc/pigallery2/BUILD-PROVENANCE.txt. - Hardened defaults. PiGallery2 runs as its own unprivileged user under a locked-down systemd unit that never writes a core dump. PiGallery2 and nginx are blocked from the Azure instance metadata service and the Azure wire server. Client addresses come from the connection, not from headers a client can forge. Repeated sign-in attempts are rate limited, and a browser request that changes something and comes from another web site is refused. Extensions (third-party server code) and browser uploads are off until you turn them on. SSH refuses root logins.
- A dedicated data disk. Your photos, the index, the thumbnails and PiGallery2's configuration live on their own 20 GiB data disk mounted at
/var/lib/pigallery2, which you can grow on its own. - Photos only. The image ships without FFmpeg, so PiGallery2's video support is switched off. Video files in your photo folder are skipped (no video thumbnails, playback or conversion). See Step 5 if you need videos.
- No sample content. The gallery starts empty and you add your own photos.
- Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
What is on the image: PiGallery2 3.5.2 (/opt/pigallery2/app), Node.js 22.23.4 (/opt/pigallery2/node), nginx, Ubuntu 24.04 LTS, cloud-init and the Azure Linux Agent.
Recommended size: Standard_B2s or larger. Making thumbnails for a large library is CPU-heavy, and a bigger size indexes faster.
Prerequisites
- An Azure subscription with permission to create virtual machines, and an SSH key pair (or a password) for the VM's administrator account.
- A network security group that allows TCP 443 (the gallery) and TCP 80 (redirect to HTTPS) from the people who will use it, and TCP 22 (SSH, also how you copy photos in) from your own networks only.
Deploy from the Azure Portal
- Find PiGallery2 on Ubuntu 24.04 LTS by SecureAnyCloud in the Azure Marketplace and select Create.
- Choose your subscription, resource group, region and a size (Standard_B2s or larger).
- Set the administrator user name and your SSH public key (or a password).
- On the Disks tab, note the 20 GiB data disk that holds your photos. You can grow it after deployment (Step 12).
- On the Networking tab, allow 443 and 80 from your users and 22 from your own networks only.
- Select Review + create, then Create.
Deploy from the Azure CLI
Replace each value in angle brackets with your own:
az vm image terms accept --urn sac1647283583153:pigallery2-ubuntu-24-04:default:latest
az vm create --resource-group <your-resource-group> --name pigallery2 \
--image sac1647283583153:pigallery2-ubuntu-24-04:default:latest \
--size Standard_B2s --admin-username azureuser --ssh-key-values ~/.ssh/id_rsa.pub \
--public-ip-sku Standard
az vm open-port --resource-group <your-resource-group> --name pigallery2 --port 443 --priority 1001
az vm open-port --resource-group <your-resource-group> --name pigallery2 --port 80 --priority 1002Then connect over SSH as the administrator account you chose:
ssh azureuser@<public-ip>Check the services
First boot takes a few seconds. After that, PiGallery2, nginx and the first-boot unit are active:
systemctl is-active pigallery2 nginx pigallery2-firstbootactive active activenginx is the only web listener. PiGallery2 itself (a Node.js process) listens on 127.0.0.1:8080 only:
sudo ss -tlnp | awk 'NR==1 || /nginx|sshd|:8080 /' | awk '{print $1, $4, $6}' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g'State Local Peer LISTEN 0.0.0.0:22 users:(("sshd"),("systemd")) LISTEN 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx")) LISTEN 0.0.0.0:443 users:(("nginx"),("nginx"),("nginx")) LISTEN 127.0.0.1:8080 users:(("node")) LISTEN [::]:22 users:(("sshd"),("systemd")) LISTEN [::]:80 users:(("nginx"),("nginx"),("nginx")) LISTEN [::]:443 users:(("nginx"),("nginx"),("nginx"))Check the runtime, the PiGallery2 release and the data disk:
/opt/pigallery2/node/bin/node --version jq -r .version /opt/pigallery2/app/package.json findmnt -no TARGET,FSTYPE,SIZE /var/lib/pigallery2v22.23.4 3.5.2 /var/lib/pigallery2 ext4 19.5GGet your URL and password
sudo cat /root/pigallery2-credentials.txtThe file holds the address PiGallery2 is served on (your VM's public IP address by default) and the admin password generated on this VM:
# PiGallery2 3.5.2 - generated on first boot by pigallery2-firstboot.service. Unique to this VM; keep it safe. PIGALLERY2_URL=https://<public-ip>/ PIGALLERY2_USER=admin PIGALLERY2_PASS=<24 letters and digits>
# Sign in to the gallery with this user name and password. Only a bcrypt hash of the password is stored by PiGallery2.
# Add photos: copy them into /var/lib/pigallery2/images (azureuser can write there), then open the
# gallery (folders are indexed when you browse them; Settings -> Indexing rescans everything).
# Change the host name:
sudo pigallery2-set-host <dns-name>
# Change the password:
sudo pigallery2-set-password (prompts)Add your photos
PiGallery2 reads photos from /var/lib/pigallery2/images, and its folders become albums in the gallery. On first boot, the VM's administrator account (the user name you chose at deployment) is added to the pigallery2 group, which can write to that folder. You can therefore copy photos straight in over SSH. From your own computer, for example:
rsync -av --progress ~/Pictures/Your-Photos/ azureuser@<public-ip>:/var/lib/pigallery2/images/(scp -r and SFTP clients work too.) Keep the hidden file .sac-gallery-root in the folder. PiGallery2 will not index an empty photo folder, which protects its index if the storage is missing, and this file keeps a new gallery working. The file is never shown in the gallery.
PiGallery2 indexes a folder the first time someone opens it, and picks up new and removed files when the folder is opened again. To index the whole library at once (recommended after a large copy), sign in and open Settings from the menu at the top right. Switch the mode (top right) to Advanced, then choose Run now: Indexing in the Indexing section. Thumbnails are made as you browse, and the Photo section has a job that makes them ahead of time.
Check the photo folder and the members of the pigallery2 group (your administrator account):
ls -ld /var/lib/pigallery2/images getent group pigallery2drwxrwsr-x 2 pigallery2 pigallery2 4096 Oct 23 09:23 /var/lib/pigallery2/images pigallery2:x:988:azureuserVideos are not included. This image is for photos. It does not ship FFmpeg, the tool PiGallery2 needs to read video files. On Ubuntu 24.04, FFmpeg and the libraries it brings in receive security updates only through Ubuntu Pro (ESM Apps), which a Marketplace VM is not attached to. Video support is therefore off in PiGallery2's configuration, and video files you copy into the photo folder are not shown. If you need videos, you can add FFmpeg yourself and attach your own Ubuntu Pro subscription with sudo pro attach to receive its security updates. Then turn video support on and restart PiGallery2:
sudo apt-get install ffmpeg
sudo sh -c 'umask 077 && jq ".Media.Video.enabled = true" /var/lib/pigallery2/config/config.json > /root/pg2-config.json && install -o pigallery2 -g pigallery2 -m 0600 /root/pg2-config.json /var/lib/pigallery2/config/config.json && rm /root/pg2-config.json'
sudo systemctl restart pigallery2Sign in
Open PIGALLERY2_URL in your browser. The certificate is self-signed (generated on your VM), so accept the browser warning once, or use your own name and certificate (Step 10). Sign in as admin with PIGALLERY2_PASS:
The gallery opens on your photo folder, with subfolders first and then the photos in it, grouped by date:
The images in these screenshots are generated patterns and fractals. The image itself ships with an empty gallery.
Browse, search and share
Open a folder to see its photos as a grid. The bar at the top shows where you are and how many items there are, and lets you download, filter, sort and group them:
Click a photo to open it full screen. The arrows move between photos, the play button starts a slideshow and the i button shows its details (file, size, date and, when the photo has them, camera, lens and location):
The search box finds photos by file name, folder, date, place, camera and keywords. Share creates a link to the current folder for people without a login, optionally with a password and an expiry. A share link uses your configured address (Step 10). Albums saves searches, Faces lists the people tagged in your photos' metadata, and the map shows geotagged photos. Your browser loads the map tiles from OpenStreetMap.
Settings
Signed in as admin, open Settings from the menu at the top right. Basic mode shows the main options. Advanced shows everything else, including the indexing and thumbnail jobs and the user list (Add user), where you can give other people their own logins and roles:
PiGallery2 keeps its settings in /var/lib/pigallery2/config/config.json. Only the pigallery2 user can read it, because it holds the session signing keys and the admin password hash. These are the settings that make up this image's security model:
sudo python3 -c 'import json; c=json.load(open("/var/lib/pigallery2/config/config.json")); print(json.dumps({"Server":{k:c["Server"][k] for k in ("host","port","publicUrl","trustProxy")},"Users":{"authenticationRequired":c["Users"]["authenticationRequired"]},"Media":{"Video":{"enabled":c["Media"]["Video"]["enabled"]}},"Extensions":{"enabled":c["Extensions"]["enabled"]},"Upload":{"enabled":c["Upload"]["enabled"]}},indent=2))'{ "Server": { "host": "127.0.0.1", "port": 8080, "publicUrl": "https://<public-ip>", "trustProxy": "loopback" }, "Users": { "authenticationRequired": true }, "Media": { "Video": { "enabled": false } }, "Extensions": { "enabled": false }, "Upload": { "enabled": false } }Keep Host 127.0.0.1, Port 8080, Trust Proxy loopback and Password protection on. PiGallery2 must be reachable only through nginx, and with password protection off, anyone who can reach the VM gets full admin rights. Three features are off on this image:
- Upload lets signed-in users upload photos through the browser. nginx accepts uploads of up to 1 GiB per request.
- Extensions download and run third-party server code from a repository on the internet. Extensions with dependencies need npm, which this image does not ship. Turn extensions on only for code you trust.
- Video needs FFmpeg, which this image does not ship (see Step 5).
Check the security model
The image ships a self test that checks the login over HTTPS. It confirms that the gallery refuses you without signing in. It confirms that a wrong password, the right password in the wrong case, a blank password, an empty, null or missing password, and admin / admin are all refused and leave no session behind. It also confirms that the password from your credentials file is accepted and that PiGallery2 listens on 127.0.0.1 only:
sudo /usr/local/sbin/pigallery2-selftestOK: https://<public-ip>/ refuses no session / wrong / wrong case / whitespace / admin:admin / empty / null / missing password, logs in with the per-VM password, app on 127.0.0.1:8080 onlyThese checks confirm that plain HTTP redirects to HTTPS and that the gallery's API refuses you until you sign in. They also confirm that a sign-in with an empty password is rejected, a sign-in posted from another web site is refused, and a request for a host name the VM does not serve gets no answer:
H=$(sudo sed -nE 's#^PIGALLERY2_URL=https://([^/]+)/.*#\1#p' /root/pigallery2-credentials.txt)
curl -s -o /dev/null -w 'plain HTTP: %{http_code} -> %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/"
curl -sk -o /dev/null -w 'gallery API without signing in: %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/pgapi/gallery/content/"
curl -sk -w '\n' --resolve "$H:443:127.0.0.1" -H 'Content-Type: application/json' -H "Origin: https://$H" --data '{"loginCredential":{"username":"admin","password":""}}' "https://$H/pgapi/user/login" | cut -c1-80
curl -sk -o /dev/null -w 'sign in posted from another web site: %{http_code}\n' --resolve "$H:443:127.0.0.1" -H 'Origin: https://evil.example' -H 'Content-Type: application/json' --data '{}' "https://$H/pgapi/user/login"
curl -s -o /dev/null -w 'unknown host name: %{http_code}\n' -H 'Host: evil.example' http://127.0.0.1/ || trueplain HTTP: 301 -> https://<public-ip>/ gallery API without signing in: 401 {"error":{"code":50,"message":"not all parameters are included for loginCredenti sign in posted from another web site: 403 unknown host name: 000PiGallery2 and nginx cannot reach the Azure instance metadata service or the wire server, and PiGallery2 never writes a core dump. nginx passes PiGallery2 the configured host and overwrites the client address with the address of the connection. Secrets are readable by root only (or by PiGallery2, for its own configuration):
systemctl show pigallery2 nginx -p Id -p IPAddressDeny
systemctl show pigallery2 -p LimitCORE grep -E 'proxy_set_header (Host|X-Real-IP|X-Forwarded-For) ' /etc/nginx/pigallery2-proxy.conf
sudo stat -c '%a %U:%G %n' /root/pigallery2-credentials.txt /var/lib/pigallery2/config/config.json /etc/nginx/ssl/pigallery2.keyIPAddressDeny=168.63.129.16/32 169.254.169.254/32 Id=pigallery2.service IPAddressDeny=168.63.129.16/32 169.254.169.254/32 Id=nginx.service LimitCORE=0 proxy_set_header Host $pg_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; 600 root:root /root/pigallery2-credentials.txt 600 pigallery2:pigallery2 /var/lib/pigallery2/config/config.json 600 root:root /etc/nginx/ssl/pigallery2.keySSH refuses root logins, empty passwords and X11 forwarding. Whether SSH accepts passwords at all follows the choice you made at deployment:
sudo sshd -T | grep -E '^(permitrootlogin|x11forwarding|permitemptypasswords) 'permitrootlogin no x11forwarding no permitemptypasswords noThe certificate was generated on this VM and lists the VM's own addresses:
H=$(sudo sed -nE 's#^PIGALLERY2_URL=https://([^/]+)/.*#\1#p' /root/pigallery2-credentials.txt)
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -subject -ext subjectAltNamesubject=CN = <public-ip>, O = sac X509v3 Subject Alternative Name: IP Address:<public-ip>, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhostYour own DNS name and certificate
Point a DNS record at the VM, then set the name PiGallery2 is served on. The helper creates a new self-signed certificate for the name, updates nginx, PiGallery2's public URL (used in share links) and the URL in /root/pigallery2-credentials.txt, restarts PiGallery2 and keeps the name across reboots:
sudo pigallery2-set-host <your-domain>To use a certificate from your own certificate authority instead, copy it over the generated pair and reload nginx. Running pigallery2-set-host again replaces it with a self-signed certificate:
sudo install -m 0644 <your-domain>.crt /etc/nginx/ssl/pigallery2.crt
sudo install -m 0600 <your-domain>.key /etc/nginx/ssl/pigallery2.key
sudo nginx -t && sudo systemctl reload nginxChange the password
Run the helper on the VM. It prompts for the new password twice, so the password never appears on a command line. It stores the password as a bcrypt hash in PiGallery2's database and configuration, updates PIGALLERY2_PASS in /root/pigallery2-credentials.txt and restarts PiGallery2:
sudo pigallery2-set-passwordThe helper also resets a forgotten password. To give other people their own logins, use Add user under Settings (Advanced mode, Users). Each user signs in with their own password and role.
Storage, backups and server components
To grow the data disk, stop (deallocate) the VM and increase the disk's size in the portal or with az disk update --size-gb. Start the VM, then grow the file system (it is mounted by UUID with nofail):
sudo resize2fs "$(findmnt -no SOURCE /var/lib/pigallery2)"Your originals are the photo folder. PiGallery2 rebuilds the index and thumbnails when they are missing, and your albums, shares and users live in the database. Back up /var/lib/pigallery2/images, /var/lib/pigallery2/db and /var/lib/pigallery2/config, or snapshot the data disk with Azure Backup or a disk snapshot.
Server components and where they live:
- PiGallery2 3.5.2: /opt/pigallery2/app
- Node.js 22.23.4 runtime: /opt/pigallery2/node/bin/node
- Data disk: /var/lib/pigallery2 (20 GiB, ext4)
- Your photos: /var/lib/pigallery2/images
- Configuration: /var/lib/pigallery2/config/config.json (pigallery2, 0600)
- Index database (SQLite): /var/lib/pigallery2/db
- Thumbnails: /var/lib/pigallery2/tmp
- systemd unit: pigallery2.service (user pigallery2, 127.0.0.1:8080)
- nginx site: /etc/nginx/sites-available/sac-pigallery2
- Certificate and key: /etc/nginx/ssl/
- First-boot script: /usr/local/sbin/pigallery2-firstboot.sh
- Host name helper: /usr/local/sbin/pigallery2-set-host
- Password helper: /usr/local/sbin/pigallery2-set-password
- Self test: /usr/local/sbin/pigallery2-selftest
- Credentials: /root/pigallery2-credentials.txt (mode 0600)
- Licences, build record and dependency scan: /usr/share/doc/pigallery2/
Security recommendations
- Allow port 22 in the network security group from your own networks only, and open 80 and 443 only to the people who should see the gallery.
- Keep the admin password private, and change it if it may have leaked (Step 11). Give other people their own users rather than the admin login.
- Use your own DNS name and a certificate your users trust (Step 10), so nobody learns to click through certificate warnings.
- Give share links a password and an expiry when they leave your organisation.
- Keep the operating system patched. Unattended security upgrades are on, and
sudo apt-get update && sudo apt-get upgradeapplies everything else.
Support and licensing
PiGallery2 is free software under the MIT licence (Copyright bpatrik). A copy is at /usr/share/doc/pigallery2/LICENSE, and the Node.js licence is at /usr/share/doc/pigallery2/NODE-LICENSE. This image runs the PiGallery2 3.5.2 release from https://github.com/bpatrik/pigallery2 with the runtime, dependency and security changes listed in /usr/share/doc/pigallery2/BUILD-PROVENANCE.txt. There is no per-user or per-CPU licence fee. The SecureAnyCloud charge covers hardening, first-boot setup, image maintenance and 24/7 support.
- Email: sales@secureanycloud.com
- Website: https://secureanycloud.com
- Support: 24/7, with a 24 hour response SLA
Deploy on Azure
Launch PiGallery2 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
PiGallery2 on Ubuntu 24.04 LTS is a ready-to-run AMI from SecureAnyCloud for AWS. PiGallery2 is a fast, open source, directory-first photo gallery and management server. You point it at a folder of photos and videos, and it serves a browser gallery that preserves your directory structure, generates thumbnails, reads EXIF metadata, and adds search, maps, face grouping and secure sharing.
The image installs the latest stable PiGallery2 release and pins the exact version (recorded in /opt/pigallery2/VERSION). PiGallery2 runs on Node.js 22 LTS under systemd as the unprivileged pigallery2 system user and binds to loopback only (127.0.0.1:8080). nginx is the only network-facing component. It terminates TLS on port 443 and reverse proxies to PiGallery2, and port 80 redirects to HTTPS. Your photos, the thumbnail cache and the SQLite index live on a dedicated data volume mounted at /var/lib/pigallery2, which is provisioned automatically with every instance.
Secure by default. When password protection is enabled, PiGallery2 otherwise creates a well-known default administrator, which would leave the gallery open to anyone who can reach it. This image turns authentication on and generates a unique administrator credential on each instance's first boot. Only a one-way bcrypt hash of the password is written to the configuration, and the plain password is placed in a root-only file for the administrator to read. There are no shared or default credentials, and nothing is baked into the image.
What you get:
- The latest stable PiGallery2 release, installed on Node.js 22 LTS and run under systemd as the unprivileged
pigallery2system user. - PiGallery2 bound to loopback only (
127.0.0.1:8080), so it is never exposed to the network directly. - nginx terminating TLS on :443 and reverse proxying to PiGallery2, with HSTS and security headers.
- Port
:80returning a301redirect to HTTPS for every path except an unauthenticated/healthzendpoint (HTTP 200) for load balancer probes. - Authentication on by default with a unique admin credential generated per instance on first boot. Only the one-way bcrypt hash is stored in the configuration, and the plain password lands in a root-only file.
- A dedicated data volume mounted at
/var/lib/pigallery2holding your photos (images/), the thumbnail cache (tmp/) and the SQLite index (db/). The volume is captured into the AMI, so every instance is provisioned with it. - A small set of sample photos, so the gallery is populated the moment you sign in. Replace them with your own.
- ffmpeg installed for video thumbnails and transcoding.
- A self-signed TLS certificate regenerated per instance on first boot. Its Subject Alternative Names include the instance public IP, hostname and
127.0.0.1. Replace it with your own CA-signed certificate. - A built-in self test at
/usr/local/bin/pigallery2-selftestthat checks the authenticated login and gallery listing end to end over TLS. - Ubuntu 24.04 LTS base with the latest security patches applied at build time.
- 24/7 SecureAnyCloud support with a 24 hour response SLA.
Connecting to your instance
Connect over SSH on port 22 as the default login user for the operating system variant you launched. Use the private key of the EC2 key pair you selected at launch.
- Ubuntu 24.04: SSH login user ubuntu
ssh -i /path/to/your-key.pem ubuntu@<public-ip>Prerequisites
- An AWS account with permission to launch EC2 instances.
- An EC2 key pair for administrative SSH access to the instance as the
ubuntuuser. - A security group that allows inbound TCP
443(HTTPS) and80(redirect) from the networks that should reach the gallery, and22(SSH) from your management network only. - An instance type of m5.large or larger (recommended).
Launch from the AWS Marketplace
Find the PiGallery2 listing in the AWS Marketplace. Choose Continue to Subscribe, then Continue to Configuration and Continue to Launch.
Select the region, the m5.large (or larger) instance type, your VPC and subnet, and your EC2 key pair.
Configure the security group to allow inbound 443 and 80 from your users, and restrict 22 to your management network.
Launch the instance. When it is running, browse to https://<public-ip>/.
Launch from the AWS CLI
Launch the AMI from the command line and restrict SSH to your management network. Replace the example values with your own:
aws ec2 run-instances \
--image-id <pigallery2-ami-id> \
--instance-type m5.large \
--key-name your-key \
--security-group-ids <sg-id> \
--subnet-id <subnet-id> \
--associate-public-ip-addressWhen the instance is running, browse to https://<public-ip>/.
Retrieve your per-instance admin credential
Authentication is on by default. Each instance generates its own admin user name and password on first boot and writes them to a root-only file. Read the file over SSH:
ssh -i /path/to/your-key.pem ubuntu@<public-ip> 'sudo cat /root/pigallery2-credentials.txt'The file contains the PIGALLERY2_USER, PIGALLERY2_PASS and PIGALLERY2_URL for this instance. Keep the file secret. The configuration stores only a one-way bcrypt hash of the password, never the plain text.
Sign in to the gallery
Browse to https://<public-ip>/. The certificate is self-signed per instance, so your browser shows a certificate warning the first time. Accept it to continue, or put a CA-signed certificate in front, as covered in Step 9. PiGallery2 then shows a login screen.
Sign in with the user name and password from Step 3. PiGallery2 opens on the gallery and shows the photos in your media folder as a responsive grid. The included sample photos are visible immediately. The top bar carries the Gallery, Albums and Faces navigation, a search box and the signed-in admin user.
View and browse your photos
Click any photo to open it full screen in the lightbox. Use the arrow keys or the on-screen arrows to move between photos, and use the toolbar to see photo information, go full screen or start a slideshow. Your directory structure is preserved, so subfolders of your media folder appear as albums you can browse into.
Add your own photos
Your gallery reads from /var/lib/pigallery2/images on the dedicated data volume. Copy your own photos and videos into that folder, keeping any subfolder structure you want as albums. Then fix ownership so the service can read them, and browse the gallery to index them:
# Copy your photos into the gallery folder (use sudo; the folder is owned by the service user)
sudo cp -r ~/my-photos/. /var/lib/pigallery2/images/
sudo chown -R pigallery2:pigallery2 /var/lib/pigallery2/imagesPiGallery2 indexes a directory the first time it is browsed, and a background job keeps the index up to date. Thumbnails and transcoded videos are written to /var/lib/pigallery2/tmp, and the SQLite index is written to /var/lib/pigallery2/db, both on the same data volume. The data volume is captured with the AMI and reattached to every instance, so your photos and index survive a redeploy of the OS disk.
Manage settings as an administrator
The signed-in admin user can open the Settings page to manage users, media handling, sharing, indexing and more. The Server section shows the loopback bind (127.0.0.1:8080) that nginx proxies to. The Users section shows that password protection is enabled with the per-instance admin account enforced.
Verify the deployment
SSH to the instance as ubuntu and confirm that the services are running and PiGallery2 is bound to loopback only:
systemctl is-active pigallery2 nginx
sudo ss -tlnp | grep 8080Both services report active, and PiGallery2 listens on 127.0.0.1:8080 only. nginx is the only component exposed on :80 and :443:
active active LISTEN 0 511 127.0.0.1:8080 0.0.0.0:*Run the built-in self test. It reads this instance's credential and checks the full round trip over TLS. An unauthenticated gallery request is refused, a login with the per-instance credential succeeds, and the gallery lists the sample photos. The PiGallery2 default admin/admin login is rejected because it was never shipped:
sudo /usr/local/bin/pigallery2-selftestOK pigallery2 self-test passed: unauth rejected, per-VM login OK, gallery lists samples, admin/admin rejected (TLS)TLS, authentication and the per-instance certificate
nginx terminates TLS on port 443 and redirects plain HTTP on port 80 to HTTPS. Confirm the redirect and the unauthenticated health probe from the instance:
curl -s -o /dev/null -w 'port 80 -> HTTP %{http_code}\n' http://127.0.0.1/
curl -sk -o /dev/null -w 'healthz over TLS -> HTTP %{http_code}\n' https://127.0.0.1/healthzPort 80 returns 301 and the health endpoint returns 200:
port 80 -> HTTP 301 healthz over TLS -> HTTP 200An unauthenticated request to the gallery API is refused (NOT_AUTHENTICATED), while a login with this instance's credential returns the admin user. The self-signed certificate is regenerated per instance on first boot, with the instance public IP and hostname in its Subject Alternative Names.
Replace the self-signed certificate
The per-instance certificate is self-signed, so browsers warn on first use. For a public deployment, use a certificate from a trusted authority. The simplest way is to point a DNS name at the instance and obtain a free certificate with Certbot:
# Point https://<your-domain> at this instance first, then:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>Alternatively, terminate TLS at an Application Load Balancer in front of the instance and forward traffic to port 443.
Check the installed versions
The PiGallery2 and Node.js versions installed in the image are recorded on the instance at /opt/pigallery2/VERSION:
cat /opt/pigallery2/VERSIONpigallery2_version=3.5.2 node_version=v22.23.1Security notes
No default login. Authentication is on by default, and a unique admin credential is generated on each instance's first boot. Only a one-way bcrypt hash is stored in the configuration, and the plain password lives in the root-only file /root/pigallery2-credentials.txt. The PiGallery2 default admin/admin account is never shipped.
Loopback-only application. PiGallery2 binds to 127.0.0.1:8080 and is reachable only through the nginx TLS reverse proxy on :443. Keep it that way, and let nginx (or a load balancer) be the only network-facing component.
Data on a dedicated volume. Your photos, thumbnail cache and index live on the data volume at /var/lib/pigallery2, separate from the OS disk. Back up this volume to protect your library.
Restrict access. Allow 443 only from the networks that need it, and keep 22 restricted to your management network. Replace the self-signed certificate with a CA-signed one.
Rotate the credential from the admin Settings page (change the admin password), or place your own identity-aware proxy in front.
Support
This image is backed by 24/7 SecureAnyCloud support with a 24 hour response SLA. Contact sales@secureanycloud.com for assistance. PiGallery2 is open source software distributed under the MIT License and is free. The SecureAnyCloud charge covers packaging, hardening, security patching, image maintenance and support.
Deploy on AWS
Launch PiGallery2 with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com