HortusFox
Overview
HortusFox is a free, open-source, self-hosted collaborative plant and garden management system built on PHP and the Asatru framework. It organises plants by location. It gives you a plant inventory, watering and care task scheduling, a photo gallery, a journal and history view, a calendar, inventory tracking and a collaborative group chat. All of it sits behind an admin dashboard and a REST API.
The SecureAnyCloud image delivers HortusFox fully installed and configured on Ubuntu 24.04. It is a PHP 8.3 application served by nginx over HTTPS with php-fpm, backed by MariaDB 11.4 LTS bound to the loopback interface.
The schema is migrated, and default plant attributes and calendar classes are seeded. An initial workspace and admin account are created, and one starter location is added. You land directly on a working sign-in with nothing to install.
What you get:
- HortusFox 5.8 (MIT licensed), served from
/var/www/hortusfox/public - nginx (TLS on :443, with :80 redirected to HTTPS), PHP 8.3 (php8.3-fpm with OPcache) and MariaDB 11.4 LTS bound to
127.0.0.1 - A per-VM self-signed TLS certificate generated on first boot, so the interface loads over a secure context
- A per-VM administrator password, MariaDB password and cronjob token, all generated at first boot and written to a root-only file. No default or blank login ships in the image.
nginx.service,php8.3-fpm.serviceandmariadb.serviceas systemd units, enabled and active- 24/7 SecureAnyCloud support
Prerequisites
You need:
- An active Azure subscription
- An SSH key pair
- A VNet and subnet in the target region
- Standard_B2s (2 vCPU / 4 GiB RAM) as a good starting size. Scale up for larger collections or more collaborators.
- NSG inbound rules that allow
22/tcpfrom your management network, plus443/tcp(HTTPS) and80/tcp(which redirects to HTTPS) from your users
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal and choose Create a resource. Search the Marketplace for HortusFox by SecureAnyCloud and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTPS (443).
Click Review + create, then Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:hortusfox-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name hortusfox \
--image sac1647283583153:hortusfox-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name hortusfox --port 443 --priority 1010Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
The services that back HortusFox should all report active. The interface answers HTTP 200 over HTTPS, and the plain HTTP port redirects to it.
MariaDB listens only on the loopback interface (127.0.0.1:3306), never on the public network. Run the check:
systemctl is-active nginx php8.3-fpm mariadb curl -ks -o /dev/null -w 'app https -> %{http_code}\n' https://127.0.0.1/auth curl -s -o /dev/null -w 'http redirect -> %{http_code}\n' http://127.0.0.1/ ss -tlnp | grep -E ':443 |:3306 ' | sed 's/ */ /g'Expect three lines of active, then app https -> 200 and http redirect -> 301. MariaDB is bound to 127.0.0.1:3306.
Step 5 - Retrieve your administrator credentials
On the first boot of every VM, a one-shot service (hortusfox-firstboot.service) generates secrets that are unique to that VM. These are a fresh administrator password, a fresh MariaDB password and a fresh cronjob token. The service also generates a per-VM self-signed TLS certificate. No shared or default credentials ship in the image.
Read the credentials file:
sudo cat /root/hortusfox-credentials.txtThe file (mode 0600, root only) contains:
- The administrator email (
hortusfox.admin.user, the fixed valueadmin@hortusfox.local) - The administrator password (
hortusfox.admin.pass) - The sign-in URL
- The database credentials
HortusFox signs in by email.
You can prove the login round trip from the VM's own shell. The script reads the per-VM credentials and posts a real admin sign-in. A signed-in session reaches the dashboard, which carries a Logout control. The script also confirms that a wrong password is rejected and redirected back to the sign-in page:
ADMIN_USER=$(sudo grep '^hortusfox.admin.user=' /root/hortusfox-credentials.txt | cut -d= -f2-)
ADMIN_PASS=$(sudo grep '^hortusfox.admin.pass=' /root/hortusfox-credentials.txt | cut -d= -f2-)
CJ=$(mktemp)
curl -ks -c "$CJ" https://127.0.0.1/auth >/dev/null
curl -ks -b "$CJ" -c "$CJ" -o /dev/null \
--data-urlencode "email=$ADMIN_USER" --data-urlencode "password=$ADMIN_PASS" https://127.0.0.1/login
curl -ks -b "$CJ" -o /tmp/hf-check.html -w 'correct password -> HTTP %{http_code}\n' https://127.0.0.1/ grep -qi logout /tmp/hf-check.html && echo 'signed in (Logout present)' || echo 'not signed in' rm -f "$CJ" /tmp/hf-check.htmlStep 6 - Sign in to HortusFox
Browse to https://<vm-public-ip>/auth and sign in with the administrator email and password from the credentials file.
The image ships a per-VM self-signed certificate, so your browser shows a one-time certificate warning on first visit. Click through it, or install your own domain certificate into /etc/nginx/ssl/.
After you sign in, the dashboard greets you and summarises your plants, locations, tasks and users at a glance.
Step 7 - Add locations and plants
HortusFox organises everything by location, such as a greenhouse, a room, a bed or a windowsill. The image ships with one starter location named Greenhouse, so you can add plants immediately. Create more locations from Admin > Locations.
Choose Add Plant from the top bar to register a plant against a location. Then attach photos, notes, custom attributes and a watering schedule.
The Tasks view manages recurring care work such as watering, feeding and repotting. It has To-Do and Done lists that you can filter.
Step 8 - Plan care with the calendar
The Calendar view records important dates and reminders across a date range that you choose. Seasonal care, fertilising windows and repotting dates all sit in one place.
Other built-in modules are:
- Inventory for pots, soil and supplies
- Search across your collection
- History, a timeline for each plant
- Chat, for teams that share a workspace
Step 9 - Confirm the stack
Check the PHP, MariaDB and application settings:
php -v | head -1 mariadb --version grep -E '^APP_DEBUG|^DB_HOST|^DB_DATABASE' /var/www/hortusfox/.envExpect PHP 8.3.x and MariaDB 11.4.x. The application is configured with APP_DEBUG=false (production posture) against the loopback database hortusfox.
First-boot service and security model
A one-shot hortusfox-firstboot.service runs After=mariadb.service and Before=nginx.service. The per-VM secrets and TLS certificate are therefore in place before the first page is served.
The service writes the credentials file at mode 0600 (root only) and drops a sentinel so that it runs exactly once. Inspect the unit:
systemctl status hortusfox-firstboot.service --no-pager | head -6 sudo stat -c '%a %U:%G %n' /root/hortusfox-credentials.txtAdministration
Do day-to-day administration from the web Admin dashboard (the gear icon in the top bar). You can manage users, locations, workspace settings, themes, backups and the environment.
HortusFox also ships a command-line tool (php asatru <command>) for maintenance and deployment. It is enabled only when APP_DEBUG=true, which this image deliberately sets to false for a production posture. Use the Admin dashboard for routine tasks.
Invite users from Admin > Users. Each user can sign in by email and change their password from their profile. Once SMTP is configured under Admin > Settings, users can also reset a forgotten password by email.
Enabling HTTPS with your own domain
The image already serves HTTPS with a per-VM self-signed certificate. For production, point a real domain at the VM's public IP and open 443/tcp in the NSG. Then replace the self-signed certificate with a trusted one from Let's Encrypt. Replace the example domain with your own:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.comHortusFox derives its links from the host that you browse to. Once you reach the VM by your domain name over HTTPS, the application uses it automatically. No configuration change is needed.
Backup and maintenance
The database and the application tree live on the VM's disk. The tree includes uploaded plant photos under /var/www/hortusfox/public/img. Snapshot the disk in Azure for a point-in-time backup.
Alternatively, dump the database. The database password is in the credentials file:
sudo mariadb-dump hortusfox > hortusfox-backup.sqlKeep the OS patched with sudo apt update && sudo apt upgrade. Unattended security upgrades are enabled by default.
The stack restarts cleanly with sudo systemctl restart nginx php8.3-fpm mariadb.
Support
SecureAnyCloud provides 24/7 support for this image. Contact us by email or chat for help with HortusFox deployment, upgrades, adding locations and plants, task and calendar configuration, SMTP and email reminders, the REST API, performance tuning and database administration.
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on Azure
Launch HortusFox 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
HortusFox is a free, open-source, self-hosted collaborative plant and garden management system built on PHP and the Asatru framework. It organises plants by location. It gives you a plant inventory, watering and care task scheduling, a photo gallery, a journal and history view, a calendar, inventory tracking and a collaborative group chat. All of it sits behind an admin dashboard and a REST API.
The SecureAnyCloud AMI delivers HortusFox fully installed and configured on Ubuntu 24.04 LTS. It is a PHP 8.3 application served by nginx over HTTPS with php-fpm, backed by MariaDB 11.4 LTS bound to the loopback interface.
The schema is migrated, and default plant attributes and calendar classes are seeded. An initial workspace and admin account are created, and one starter location is added. You land directly on a working sign-in with nothing to install. The database and the application tree each live on their own dedicated EBS volume.
What you get:
- HortusFox 5.8 (MIT licensed), served from
/var/www/hortusfox/public - nginx (TLS on :443, with :80 redirected to HTTPS), PHP 8.3 (php8.3-fpm with OPcache) and MariaDB 11.4 LTS bound to
127.0.0.1 - A per-instance self-signed TLS certificate generated on first boot, so the interface loads over a secure context
- A per-instance administrator password, MariaDB password and cronjob token, all generated at first boot and written to a root-only file. No default or blank login ships in the image.
- A production-grade two-disk layout: the MariaDB database (
/var/lib/mysql) and the HortusFox application tree (/var/www, including uploaded plant photos) each on their own independently resizable EBS volume nginx.service,php8.3-fpm.serviceandmariadb.serviceas systemd units, enabled and active- 24/7 SecureAnyCloud support
Prerequisites
You need:
- An active AWS account
- An EC2 key pair in the target region
- A VPC subnet with a security group
- m5.large (2 vCPU / 8 GiB RAM) as a good starting size. Scale up for larger collections or more collaborators.
- Security group inbound rules that allow
22/tcpfrom your management network, plus443/tcp(HTTPS) and80/tcp(which redirects to HTTPS) from your users
Connecting to your instance
Connect over SSH as the default login user for the AMI's operating system. The login user depends on the OS variant.
On Ubuntu 24.04, the SSH login user is ubuntu.
Step 1 - Launch from the AWS Marketplace
Sign in to the AWS Marketplace and search for HortusFox by SecureAnyCloud. Choose Continue to Subscribe and accept the terms. Then choose Continue to Configuration and Continue to Launch.
Pick your region, the m5.large instance type, your VPC subnet and your EC2 key pair. Choose a security group that allows inbound 22 and 443, and 80, which redirects to HTTPS. Then launch the instance.
Step 2 - Launch from the AWS CLI
aws ec2 run-instances \
--image-id <hortusfox-ami-id> \
--instance-type m5.large \
--key-name <your-key-pair> \
--subnet-id <your-subnet> \
--security-group-ids <your-sg> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=hortusfox}]'Make sure that the security group allows inbound 22/tcp (SSH) and 443/tcp (HTTPS) from the appropriate sources.
Step 3 - Connect to your instance
ssh ubuntu@<instance-public-ip>Step 4 - Confirm the services are running
The services that back HortusFox should all report active. The interface answers HTTP 200 over HTTPS, and the plain HTTP port redirects to it.
MariaDB listens only on the loopback interface (127.0.0.1:3306), never on the public network. Run the check:
systemctl is-active nginx php8.3-fpm mariadb curl -ks -o /dev/null -w 'app https -> %{http_code}\n' https://127.0.0.1/auth curl -s -o /dev/null -w 'http redirect -> %{http_code}\n' http://127.0.0.1/ ss -tlnp | grep -E ':443 |:3306 ' | sed 's/ */ /g'Expect three lines of active, then app https -> 200 and http redirect -> 301. MariaDB is bound to 127.0.0.1:3306.
Step 5 - Retrieve your administrator credentials
On the first boot of every instance, a one-shot service (hortusfox-firstboot.service) generates secrets that are unique to that instance. These are a fresh administrator password, a fresh MariaDB password and a fresh cronjob token. The service also generates a per-instance self-signed TLS certificate. No shared or default credentials ship in the image.
Read the credentials file:
sudo cat /root/hortusfox-credentials.txtThe file (mode 0600, root only) contains:
- The administrator email (
hortusfox.admin.user, the fixed valueadmin@hortusfox.local) - The administrator password (
hortusfox.admin.pass) - The sign-in URL
- The database credentials
HortusFox signs in by email.
You can prove the login round trip from the instance's own shell. The script reads the per-instance credentials and posts a real admin sign-in. A signed-in session reaches the dashboard, which carries a Logout control. The script also confirms that a wrong password is rejected and redirected back to the sign-in page:
ADMIN_USER=$(sudo grep '^hortusfox.admin.user=' /root/hortusfox-credentials.txt | cut -d= -f2-)
ADMIN_PASS=$(sudo grep '^hortusfox.admin.pass=' /root/hortusfox-credentials.txt | cut -d= -f2-)
CJ=$(mktemp)
curl -ks -c "$CJ" https://127.0.0.1/auth >/dev/null
curl -ks -b "$CJ" -c "$CJ" -o /dev/null \
--data-urlencode "email=$ADMIN_USER" --data-urlencode "password=$ADMIN_PASS" https://127.0.0.1/login
curl -ks -b "$CJ" -o /tmp/hf-check.html -w 'correct password -> HTTP %{http_code}\n' https://127.0.0.1/ grep -qi logout /tmp/hf-check.html && echo 'signed in (Logout present)' || echo 'not signed in' rm -f "$CJ" /tmp/hf-check.htmlStep 6 - Sign in to HortusFox
Browse to https://<instance-public-ip>/auth and sign in with the administrator email and password from the credentials file.
The image ships a per-instance self-signed certificate, so your browser shows a one-time certificate warning on first visit. Click through it, or install your own domain certificate into /etc/nginx/ssl/.
After you sign in, the dashboard greets you and summarises your plants, locations, tasks and users at a glance.
Step 7 - Add locations and plants
HortusFox organises everything by location, such as a greenhouse, a room, a bed or a windowsill. The image ships with one starter location named Greenhouse, so you can add plants immediately. Create more locations from Admin > Locations.
Choose Add Plant from the top bar to register a plant against a location. Then attach photos, notes, custom attributes and a watering schedule.
The Tasks view manages recurring care work such as watering, feeding and repotting. It has To-Do and Done lists that you can filter.
Step 8 - Plan care with the calendar
The Calendar view records important dates and reminders across a date range that you choose. Seasonal care, fertilising windows and repotting dates all sit in one place.
Other built-in modules are:
- Inventory for pots, soil and supplies
- Search across your collection
- History, a timeline for each plant
- Chat, for teams that share a workspace
Step 9 - Confirm the stack
Check the PHP, MariaDB and application settings:
php -v | head -1 mariadb --version grep -E '^APP_DEBUG|^DB_HOST|^DB_DATABASE' /var/www/hortusfox/.envExpect PHP 8.3.x and MariaDB 11.4.x. The application is configured with APP_DEBUG=false (production posture) against the loopback database hortusfox.
First-boot service and security model
A one-shot hortusfox-firstboot.service runs After=mariadb.service and Before=nginx.service. The per-instance secrets and TLS certificate are therefore in place before the first page is served.
The service writes the credentials file at mode 0600 (root only) and drops a sentinel so that it runs exactly once. Inspect the unit:
systemctl status hortusfox-firstboot.service --no-pager | head -6 sudo stat -c '%a %U:%G %n' /root/hortusfox-credentials.txtData volumes
This AMI uses a production-grade two-disk layout. The MariaDB datadir and the HortusFox application tree each live on their own dedicated EBS volume, so you can resize either tier independently. List the volumes:
lsblk -o NAME,SIZE,MOUNTPOINT | grep -E 'mysql|www' df -h /var/lib/mysql /var/wwwTo grow a tier, expand the EBS volume in the EC2 console. Then extend the filesystem on the instance with sudo growpart and sudo resize2fs. Uploaded plant photos live under /var/www/hortusfox/public/img on the application volume.
Administration
Do day-to-day administration from the web Admin dashboard (the gear icon in the top bar). You can manage users, locations, workspace settings, themes, backups and the environment.
HortusFox also ships a command-line tool (php asatru <command>) for maintenance and deployment. It is enabled only when APP_DEBUG=true, which this image deliberately sets to false for a production posture. Use the Admin dashboard for routine tasks.
Invite users from Admin > Users. Each user can sign in by email and change their password from their profile. Once SMTP is configured under Admin > Settings, users can also reset a forgotten password by email.
Enabling HTTPS with your own domain
The image already serves HTTPS with a per-instance self-signed certificate. For production, point a real domain at the instance's public IP (an Elastic IP is recommended) and open 443/tcp in the security group. Then replace the self-signed certificate with a trusted one from Let's Encrypt. Replace the example domain with your own:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.comHortusFox derives its links from the host that you browse to. Once you reach the instance by your domain name over HTTPS, the application uses it automatically. No configuration change is needed.
Backup and maintenance
The database and the application tree live on dedicated EBS volumes. The tree includes uploaded plant photos under /var/www/hortusfox/public/img. Snapshot the volumes in EC2 for a point-in-time backup.
Alternatively, dump the database. The database password is in the credentials file:
sudo mariadb-dump hortusfox > hortusfox-backup.sqlKeep the OS patched with sudo apt update && sudo apt upgrade. Unattended security upgrades are enabled by default.
The stack restarts cleanly with sudo systemctl restart nginx php8.3-fpm mariadb.
Support
SecureAnyCloud provides 24/7 support for this image. Contact us by email or chat for help with HortusFox deployment, upgrades, adding locations and plants, task and calendar configuration, SMTP and email reminders, the REST API, performance tuning and database administration.
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on AWS
Launch HortusFox Plant Management on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com