Zenphoto
Overview
ZenphotoCMS (Zenphoto) is a mature, open source photo gallery and lightweight content management system. You organize images and videos into albums and sub-albums, and Zenphoto publishes them as a themed web gallery. The gallery includes thumbnails, EXIF and IPTC metadata, tags, search, RSS feeds and per-album access control.
Its Zenpage module adds pages and a news blog, and its backend manages uploads, users, themes and plugins. This guide covers deploying and using ZenphotoCMS 1.6.8 on Ubuntu 24.04 from SecureAnyCloud on Microsoft Azure.
What you get:
- HTTPS and a unique admin password from the first boot. nginx serves Zenphoto 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. The
adminpassword, and Zenphoto's per-install password salt (which also keys its form tokens and cookies), are generated on first boot. The password is written to/root/zenphoto-credentials.txt(readable by root only). Nothing secret is baked into the image. - No web installer, ever. Zenphoto's setup wizard was completed when the image was built and then locked with Zenphoto's own protection. The web server refuses the setup pages, and the web server user cannot unlock them. A fresh Zenphoto install would give the first visitor full admin rights until an administrator exists. On this image, the gallery does not start until first boot has created the administrator.
- No database password at all. Zenphoto reaches MariaDB as the system user
www-dataover the local socket, and MariaDB checks the connecting process instead of a password. MariaDB listens on 127.0.0.1 only. The database is created on first boot, so no database from the build ships in the image. - Security fixes that are not in a release yet. ZenphotoCMS 1.6.8 is the newest release, but the Zenphoto developers have fixed several security issues since then in their code. This image applies those fixes (search sorting, the GoogleMap plugin's map page, the rating plugin and backup restore). It also applies a SecureAnyCloud fix for links such as javascript:... that got through Zenphoto's description filter. It updates the editor (TinyMCE 7.9.3), the file manager (elFinder 2.1.70) and the HTML sanitizer (htmLawed 1.2.15) to versions without known advisories. The patch is at /usr/share/doc/sac/zenphoto-1.6.8-sac-security.patch.
- Hardened defaults. PHP runs only for Zenphoto's own scripts. The configuration, logs, backups and uploaded files are never served or executed. nginx, PHP-FPM, MariaDB and the first boot service are blocked from the Azure Instance Metadata Service and the wire server. Client addresses come from the connection, not from headers a client can forge. A browser request that changes something and comes from another web site is refused.
- One place for your data. Your photos (
albums), uploads, the image cache and the MariaDB database live under/dataon the OS disk. They are easy to back up and to move to a data disk of your own (Step 11). - 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: ZenphotoCMS 1.6.8 (/var/www/zenphoto), nginx, PHP 8.3 FPM, MariaDB 10.11, Ubuntu 24.04 LTS, cloud-init and the Azure Linux Agent.
Default user: the admin user you choose (examples use azureuser). Architecture: x64, Gen2. Recommended size: Standard_B2s.
Prerequisites
- An Azure subscription and a subscription to this offer in Azure Marketplace.
- An SSH public key or a password for the VM's admin user.
- A network security group that allows TCP 443 (the gallery and its backend) and TCP 80 (redirects to HTTPS) from the people who will use it. It must allow TCP 22 (SSH) from your own networks only. Do not open 3306, because MariaDB listens on the VM only.
Deploy the virtual machine
In Azure Marketplace, search for ZenphotoCMS, select the SecureAnyCloud offer and click Create. On the Basics tab, choose your subscription, resource group and region, and name the VM. Choose Standard_B2s or larger and set the administrator account.
Under Inbound port rules, allow SSH (22), HTTP (80) and HTTPS (443). On the Disks tab, size the OS disk for your photos plus roughly a third again for Zenphoto's resized copies. Click Review + create, then Create.
With the Azure CLI, replace the values in angle brackets:
az vm image terms accept --urn sac1647283583153:zenphoto-ubuntu-24-04:default:latest
az vm create --resource-group <your-resource-group> --name zenphoto \
--image sac1647283583153:zenphoto-ubuntu-24-04:default:latest \
--size Standard_B2s --admin-username azureuser --ssh-key-values ~/.ssh/id_rsa.pub --os-disk-size-gb 128
az vm open-port --resource-group <your-resource-group> --name zenphoto --port 80,443 --priority 900Connect to your VM
ssh azureuser@<vm-public-ip>Check the services
First boot takes a few seconds. After that, nginx, PHP-FPM, MariaDB and the first boot unit are active:
systemctl is-active nginx php8.3-fpm mariadb zenphoto-firstbootactive active active activenginx is the only web listener, and MariaDB listens on 127.0.0.1 only:
sudo ss -tlnp | awk 'NR==1 || /nginx|sshd|mariadb/' | 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:3306 users:(("mariadbd")) LISTEN [::]:22 users:(("sshd"),("systemd")) LISTEN [::]:80 users:(("nginx"),("nginx"),("nginx")) LISTEN [::]:443 users:(("nginx"),("nginx"),("nginx"))This command shows the release and what the image carries on top of it:
cat /etc/sac/zenphoto-release.txtsac: ZenphotoCMS 1.6.8 (GPL-2.0-or-later) from the upstream v1.6.8 tag; setup completed at build time and protected. Carries: zenphoto-1.6.8-sac-security.patch (sha256 210d8d9cbd0fe665c8e03824cf9751e5bd7475b180f9a374f892fe95b9f71757; upstream master d0a9edb4df, 6feaa5401f, 33ec9ab613, 0e5e3b7ada; sac kses scheme-separator fix), htmLawed 1.2.15, TinyMCE 7.9.3, elFinder 2.1.70.Get your URL and password
The credentials file holds the address Zenphoto is served as, the backend address and the admin user. By default the address is your VM's public IP address, taken from the Azure Instance Metadata Service:
sudo grep -E '^ZENPHOTO_(URL|ADMIN_URL|ADMIN_USER)=' /root/zenphoto-credentials.txtZENPHOTO_URL=https://20.42.94.124/ ZENPHOTO_ADMIN_URL=https://20.42.94.124/zp-core/admin.php ZENPHOTO_ADMIN_USER=adminThis command prints the admin password, which was generated on this VM:
sudo grep '^ZENPHOTO_ADMIN_PASSWORD=' /root/zenphoto-credentials.txt | cut -d= -f2-<ZENPHOTO_ADMIN_PASSWORD>The rest of the file explains the database account (there is no database password) and the helper commands used in Steps 9 and 10.
Open the gallery and sign in
Open ZENPHOTO_URL in your browser. The certificate is self-signed and was generated on your VM, so accept the browser warning once, or use your own name and certificate (Step 9). The gallery starts empty. Once you add albums, the front page lists them.
The images in these screenshots are sample pictures. The image itself ships with an empty gallery.
Open ZENPHOTO_ADMIN_URL, or add /zp-core/admin.php to the address, and sign in as admin with the password from Step 4:
The Overview tab shows the installation (Zenphoto 1.6.8, PHP 8.3, MariaDB, the GD image library), utility functions and gallery statistics.
The notice "There is no mail handler configured" is expected. E-mail (password reset links, comment notifications) needs a mail plugin and your own mail server settings, under Plugins and Options.
Upload photos
Choose the Upload tab, pick an existing album or type a title for a new one, then add images (GIF, JPEG, PNG, WEBP or a ZIP of images). One request can carry up to 256 MB.
For large collections, copy folders straight into the album folder over SSH. Every folder becomes an album, and Zenphoto picks them up the next time the gallery is opened. The album folder belongs to www-data, so copy to your home directory first and then move the files in. For example, from your own computer:
rsync -av --progress ~/Pictures/Your-Photos/ azureuser@<vm-public-ip>:Your-Photos/Then on the VM:
sudo mv ~/Your-Photos /var/www/zenphoto/albums/
sudo chown -R www-data:www-data /var/www/zenphoto/albums/Your-PhotosManage albums
The Albums tab lists your albums with their thumbnails, sub-album and image counts, and publish, view, refresh and delete actions. Drag albums to set the order, or click one to edit its title, description, tags, thumbnail, password and publishing.
Visitors open an album to see its thumbnails. They open an image to see it full size, with next and previous links.
Other backend tabs cover the rest of the gallery:
- Users creates further accounts and sets what each may do, for example upload to their own album only.
- Themes switches the gallery's look.
- Plugins turns on optional features (comments, contact form, Zenpage pages and news, maps, user registration).
- Options holds the gallery title, image sizes, watermarks, search and security settings.
Check the security model
The image ships a self-test that proves the login over HTTPS. The admin password from your credentials file signs in, and blank, whitespace, common and malformed (array) passwords are refused with Zenphoto's own error and no session:
sudo /usr/local/sbin/zenphoto-cred-roundtrip.shOK per-instance admin signs in over HTTPS; blank, whitespace, weak and array passwords refused without a sessionPlain HTTP redirects to HTTPS. The setup pages, the configuration folder, backups and stray PHP files are refused. 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#^ZENPHOTO_URL=https://([^/]+)/.*#\1#p' /root/zenphoto-credentials.txt)
curl -s -o /dev/null -w 'plain HTTP: %{http_code} -> %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/" for p in /zp-core/setup/ /zp-core/setup.php /zp-data/zenphoto.cfg.php /backup/ /uploaded/x.php; do
curl -sk -o /dev/null -w "$p: %{http_code}\n" --resolve "$H:443:127.0.0.1" "https://$H$p"; done
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' --data 'login=1&user=admin&pass=x' "https://$H/zp-core/admin.php"
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://20.42.94.124/ /zp-core/setup/: 404 /zp-core/setup.php: 404 /zp-data/zenphoto.cfg.php: 404 /backup/: 404 /uploaded/x.php: 404 sign in posted from another web site: 403 unknown host name: 000The database account has no password. The value in Zenphoto's configuration is only a dummy value that Zenphoto requires, and MariaDB ignores it for a socket account:
sudo mariadb -N -e "SELECT CONCAT(User,'@',Host,' ',JSON_VALUE(Priv,'\$.plugin')) FROM mysql.global_priv WHERE User='www-data'"
sudo grep -B2 "^\$conf\['mysql_pass'\]" /var/www/zenphoto/zp-data/zenphoto.cfg.phpwww-data@localhost unix_socket // sac: NOT a password. MariaDB authenticates www-data by the local socket peer (unix_socket) and ignores // this value; Zenphoto only requires the field to be non-empty. No database password exists on this instance. $conf['mysql_pass'] = 'unix_socket-auth-no-password'; // Supply your Database password.nginx, PHP-FPM, MariaDB and the first boot service cannot reach the Azure Instance Metadata Service or the wire server. A separate zenphoto-netinfo.service, which runs no PHP, reads the VM's addresses for the certificate. The secrets are readable by root only:
systemctl show nginx php8.3-fpm mariadb zenphoto-firstboot -p Id -p IPAddressDeny
sudo stat -c '%a %U:%G %n' /root/zenphoto-credentials.txt /etc/ssl/zenphoto/zenphoto.keyIPAddressDeny=169.254.169.254/32 168.63.129.16/32 Id=nginx.service IPAddressDeny=169.254.169.254/32 168.63.129.16/32 Id=php8.3-fpm.service IPAddressDeny=169.254.169.254/32 168.63.129.16/32 Id=mariadb.service IPAddressDeny=169.254.169.254/32 168.63.129.16/32 Id=zenphoto-firstboot.service 600 root:root /root/zenphoto-credentials.txt 600 root:root /etc/ssl/zenphoto/zenphoto.keyYour own DNS name and certificate
Point a DNS record at the VM. A static public IP keeps the address stable. Then set the name Zenphoto is served as.
The command below mints a new self-signed certificate for the name. It also updates nginx, which hands the name to Zenphoto so its links and feeds use it, and the URLs in /root/zenphoto-credentials.txt. The name is kept across reboots:
sudo zenphoto-set-hostname <your-domain>To use a certificate from your own certificate authority instead, copy it over the generated pair and reload nginx. Running zenphoto-set-hostname again replaces it with a self-signed one:
sudo install -m 0644 <your-domain>.crt /etc/ssl/zenphoto/zenphoto.crt
sudo install -m 0600 <your-domain>.key /etc/ssl/zenphoto/zenphoto.key
sudo nginx -t && sudo systemctl reload nginxChange the password
Change your password in the backend under Users. Open the admin user, type the new password twice and apply.
If you lose the password, run the helper on the VM. It sets a new random password, prints it once and updates /root/zenphoto-credentials.txt. Zenphoto's sign-in cookie is derived from the stored password, so changing it signs that user out everywhere:
sudo zenphoto-set-passwordStorage, backups and server components
Your albums, uploads, image cache and the MariaDB data are under /data on the OS disk and bind-mounted into place. A backup of /data (and the database dump below) therefore holds everything.
To give them more room, grow the OS disk in the Azure portal and restart the VM. Cloud-init grows the root file system at boot. Alternatively, attach a data disk, copy /data onto it with the services stopped, and mount it at /data.
Back up /data/zenphoto/albums (your originals) and the database (sudo mariadb-dump zenphoto > zenphoto.sql), or snapshot the OS disk. The image cache is rebuilt when missing. Zenphoto's own Backup/Restore utility writes database backups to /var/www/zenphoto/backup, which the web server never serves.
Running Zenphoto's setup again. Setup is locked on this image. You only need it after you upgrade Zenphoto's files yourself. In that case, follow these steps:
- Rename the protected setup scripts back as root (
cd /var/www/zenphoto/zp-core/setup && for f in *.php.xxx; do sudo mv "$f" "${f%.xxx}"; done). - Comment out the two lines in
/etc/nginx/zenphoto-setup-lock.conf, then reload nginx. - Run setup from the backend, then reverse both steps.
The Run setup and restore scripts buttons in the backend do not work while the lock is in place.
Component paths on the image:
- ZenphotoCMS 1.6.8: /var/www/zenphoto (root owned).
- Configuration: /var/www/zenphoto/zp-data/zenphoto.cfg.php (www-data, 0640; holds no secret).
- Data folder: /data (on the OS disk).
- Your albums: /data/zenphoto/albums, mounted at /var/www/zenphoto/albums.
- Uploads and image cache: /data/zenphoto/uploaded, /data/zenphoto/cache.
- MariaDB data: /data/mysql, mounted at /var/lib/mysql.
- nginx site: /etc/nginx/sites-available/sac-zenphoto.
- Certificate and key: /etc/ssl/zenphoto/.
- First boot script: /usr/local/sbin/zenphoto-firstboot.sh.
- Address lookup: /usr/local/sbin/zenphoto-netinfo (zenphoto-netinfo.service).
- Host name helper: /usr/local/sbin/zenphoto-set-hostname.
- Password helper: /usr/local/sbin/zenphoto-set-password.
- Self-test: /usr/local/sbin/zenphoto-cred-roundtrip.sh.
- Credentials: /root/zenphoto-credentials.txt (mode 0600).
- Security patch and library licenses: /usr/share/doc/sac/.
Security recommendations
- Allow port 22 in the network security group from your own networks only. 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 10). Give other people their own users with only the rights they need.
- Use your own DNS name and a certificate your users trust (Step 9), so nobody learns to click through certificate warnings.
- Turn on optional plugins (comments, registration, the elFinder file manager, maps) only when you need them, and keep their spam protection on.
- Keep the operating system patched. Unattended security upgrades are on, and
sudo apt-get update && sudo apt-get upgradeapplies everything else.
Support and licensing
ZenphotoCMS is free software under the GNU General Public License, version 2 or later (/var/www/zenphoto/LICENSE). TinyMCE is under GPL 2.0 or later, elFinder under the BSD 3-clause license, and htmLawed under LGPL 3 or GPL 2 or later. Their licenses are in /usr/share/doc/sac/ and the Zenphoto tree.
This image runs the ZenphotoCMS 1.6.8 release from https://github.com/zenphoto/zenphoto with the security changes listed above. There is no per-user or per-CPU license fee. The image price covers SecureAnyCloud's hardening, first boot setup and support.
- Email: sales@secureanycloud.com
- Website: https://secureanycloud.com
- Support: 24/7, with a 24 hour response SLA
Deploy on Azure
Launch ZenphotoCMS 1.6.8 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
This image runs ZenphotoCMS behind nginx with PHP-FPM 8.3 and OPcache enabled, with all the extensions ZenphotoCMS needs (gd, exif, intl, mbstring, mysqli, curl and zip). MariaDB provides the database, on the same instance and bound to the loopback interface only. ImageMagick and Ghostscript are installed so ZenphotoCMS can generate high-quality image thumbnails.
The setup wizard has already been run and its setup environment protected, so the first request lands directly on a working public gallery.
What you get:
- A working gallery on first request. There is no install wizard to work through, and a small sample album ships so the gallery is populated on first view.
- Per-instance secrets. A fresh administrator password and a fresh MariaDB password are generated on the first boot of every deployed instance, so two instances launched from the same Amazon Machine Image never share secrets. Both passwords are written to
/root/zenphoto-credentials.txtwith mode 0600, so that only the root user can read them. - Separate storage tiers. The whole ZenphotoCMS tree, including the gallery
albums, upload staging, image cache and configuration, lives under/var/wwwon a dedicated EBS volume separate from the operating system disk. The MariaDB data directory sits on its own EBS volume at/var/lib/mysql. Each tier can be resized independently of the others. - No reconfiguration for host names. ZenphotoCMS derives its base URL from the request host, so it works on whatever hostname or IP address you reach it on.
Prerequisites
Before you deploy this image, you need:
- An Amazon Web Services account where you can launch EC2 instances.
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products.
- An EC2 key pair in the target Region for SSH access to the instance.
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network. It must also allow inbound ports 80 and 443 from the networks your visitors and editors will reach ZenphotoCMS on.
- The AWS CLI (version 2) installed locally, if you plan to deploy from the command line.
Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for ZenphotoCMS. Select the SecureAnyCloud listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings, select your VPC and subnet, and either create or select a security group. It must allow inbound port 22 from your management network and inbound ports 80 and 443 from the networks your visitors use. Leave the root volume at the default size or larger.
Select Launch instance. First boot initialization takes a few seconds after the instance state becomes Running and the status checks pass.
Launch the Instance from the AWS CLI
This command launches an instance from the SecureAnyCloud ZenphotoCMS Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing. Replace <key-name> with your EC2 key pair name and <subnet-id> with your subnet ID. Replace <security-group-id> with a security group that opens ports 22, 80, and 443 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--metadata-options "HttpTokens=required,HttpEndpoint=enabled" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=zenphoto}]'Connecting to your instance
Connect over SSH on port 22 as the default login user for the operating system variant you launched. For Ubuntu 24.04 LTS, the login user is ubuntu. The image derives all secrets on first boot, so there is no shared password.
Connect with ssh -i <path-to-key.pem> ubuntu@<instance-public-ip>, substituting your key path and the instance's public IP address.
Connect and Retrieve Initial Credentials
On the first boot of the instance, a one-shot service rotates the MariaDB password and the ZenphotoCMS administrator password to values unique to that instance. It writes them to a root-only file. Retrieve them over SSH:
sudo cat /root/zenphoto-credentials.txtThe file lists the administrator user (admin) and password, the browse and backend URLs, and the MariaDB database name, user and password. Store the administrator password somewhere safe and treat the file as sensitive.
Verify the Stack is Running
Confirm that the three services are active and that the application answers on the loopback interface:
systemctl is-active nginx php8.3-fpm mariadb curl -s http://127.0.0.1/healthz curl -s -o /dev/null -w 'gallery HTTP %{http_code}\n' http://127.0.0.1/You should see active three times, ok from the health endpoint, and gallery HTTP 200.
Browse the Public Gallery
Open http://<instance-public-ip>/ in a browser. The public gallery renders immediately, with the seeded sample album already visible, so the page is never empty on first view.
Click an album to browse its images as a thumbnail grid. Click a thumbnail to open the single image view with its EXIF and IPTC metadata, tags and comments.
First Login to the Backend
Browse to http://<instance-public-ip>/zp-core/admin.php and sign in with the admin user and the password from /root/zenphoto-credentials.txt.
After you sign in, you land on the backend Overview. It shows the installation information (ZenphotoCMS version, PHP and MariaDB versions, gallery theme and statistics) and the utility functions for managing your gallery.
Change the Administrator Password and Create Albums
From the backend, open Users to change the administrator password and set your own name and email. Then open Albums to create your first real album. You can remove the seeded sac-sample album once you have your own content.
Use Upload to add images and videos to an album. ZenphotoCMS generates the thumbnails and sized images automatically.
Themes
Open Themes in the backend to preview and activate a different gallery theme. ZenphotoCMS ships with several themes, and more are available from the ZenphotoCMS extensions site. The active theme controls the look of your public gallery without touching your images or albums.
The Zenpage CMS (Pages and News)
ZenphotoCMS includes the Zenpage CMS for static pages plus a news and blog section. Enable and configure it under Options, and manage its content from the Pages and News backend tabs. Your site can then be a gallery and a simple website at the same time.
Users and Per Album Access Control
Open Users to create additional accounts with scoped rights. Set per-album access control so that specific albums are visible only to signed-in users or to particular users. This lets you publish a public portfolio while keeping private albums restricted.
Enable HTTPS with Let's Encrypt
ZenphotoCMS is served over plain HTTP on port 80, so you can front it with TLS. To terminate HTTPS directly on the instance, point a DNS name at the instance and install a certificate with certbot:
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.comCertbot obtains a certificate, edits the nginx site to serve HTTPS, and installs a renewal timer. ZenphotoCMS follows the request host automatically, so you do not need to reconfigure the application.
Storage Layout
The application tree and the database sit on their own EBS volumes. You can resize each one independently of the operating system disk:
df -hT /var/www /var/lib/mysql/var/www holds the ZenphotoCMS code, the gallery albums, upload staging, the image cache and the configuration. /var/lib/mysql holds the MariaDB data directory. Snapshot these volumes to back up your gallery and its database.
Backups and Maintenance
Back up the gallery by snapshotting the two EBS volumes. Alternatively, export a database dump and archive the albums directory:
sudo mysqldump zenphoto > /tmp/zenphoto-db.sql
sudo tar -czf /tmp/zenphoto-albums.tgz -C /var/www/zenphoto albumsKeep the operating system patched with sudo apt-get update && sudo apt-get upgrade. Manage the services with systemctl (nginx, php8.3-fpm, mariadb).
Screenshots
Support
SecureAnyCloud provides 24/7 technical support for this ZenphotoCMS image by email at sales@secureanycloud.com and by live chat. We help with deployment and initial configuration, theming and gallery layout, user accounts and per-album access control, the Zenpage CMS, version upgrades and migration, MariaDB database administration, and troubleshooting. Critical issues receive a one hour average response time.
Deploy on AWS
Launch ZenphotoCMS on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com