Skip to main content
Simbioza

Apache mod_php installation

Apache mod_php: step-by-step installation

This procedure is for Apache running PHP through mod_php. It was performed from a clean 0.2.4 release on the English site SimbiozaEN. Every screenshot below comes from one of those real light-theme installation flows. The lab Apache listened only on 127.0.0.1:8090; a public deployment requires HTTPS. Nginx cannot run Apache's PHP module: use the FPM guide for Nginx.

Replace the example path, URL, Unix account and PHP version with your own values. Keep the one-time installer token, database password and first administrator password out of screenshots and shared logs. Stop at any failed requirement instead of proceeding with a partially working installation.

1. Check the host and obtain one exact release

Check the CLI PHP version and extensions, Composer, Git and Apache. Confirm that the web handler is mod_php with an appropriate prefork MPM: a successful CLI check does not prove what Apache executes. On Debian, install version-matched packages such as apache2, libapache2-mod-php, php-cli, php-sqlite3, php-xml, php-mbstring, php-intl and php-zip. This local verification used Homebrew PHP 8.5 and Apache 2.4.

php -v
php -m
composer --version
git --version
/opt/homebrew/bin/httpd -v
/opt/homebrew/bin/httpd -M | grep -E 'mpm_prefork|php_module|rewrite_module'
id -un
id -Gn

Fetch a tagged release explicitly; do not combine files from several tags. The release has no composer.lock: our fresh lab run of composer install consequently resolved package versions, while the documented command below uses explicit composer update. Do not use it in place of Simbioza's updater on an existing site.

SIMBIOZA_TAG=0.2.4
SIMBIOZA_FETCH_DIR="$(mktemp -d)"
mkdir "$SIMBIOZA_FETCH_DIR/release"
git -C "$SIMBIOZA_FETCH_DIR/release" init -q
git -C "$SIMBIOZA_FETCH_DIR/release" remote add origin https://github.com/kmihalj/Simbioza.git
git -C "$SIMBIOZA_FETCH_DIR/release" fetch --quiet --depth 1 origin "refs/tags/$SIMBIOZA_TAG:refs/tags/$SIMBIOZA_TAG"
git -C "$SIMBIOZA_FETCH_DIR/release" -c advice.detachedHead=false checkout --quiet "$SIMBIOZA_TAG"
mkdir -p /Users/Shared/Simbioza/SimbiozaEN
rsync --archive --exclude=.git/ "$SIMBIOZA_FETCH_DIR/release/" /Users/Shared/Simbioza/SimbiozaEN/
cd /Users/Shared/Simbioza/SimbiozaEN
composer update --with-all-dependencies --optimize-autoloader
composer check-platform-reqs
cat VERSION

The expected value here is 0.2.4. A Linux release directory might instead be /srv/simbioza. Only its public/ directory may be served by the web server; never expose the release root, data/ or config/.

2. Prepare the database, runtime directories and narrow write access

The walkthrough uses SQLite, so no database service is required; the wizard creates a private database. For MySQL or PostgreSQL, create an empty database and a distinct application user without global privileges first. The runtime directories must exist before the first HTTP request, especially data/sessions and data/tmp. Do not make the entire codebase web-writable.

cd /Users/Shared/Simbioza/SimbiozaEN
mkdir -p config data/cache data/logs data/sessions data/setup-requests data/tmp resources/config/menu resources/config/theme
sudo chgrp -R _www config data resources/config/menu resources/config/theme
sudo chmod 3770 config
sudo chmod 2770 resources/config/menu resources/config/theme
sudo chmod -R g+rwX data resources/config/menu resources/config/theme
sudo chmod +a 'user:kmihalj allow read,write,append,execute,delete,readattr,writeattr,readextattr,writeextattr,readsecurity,file_inherit,directory_inherit' config
sudo find data resources/config/menu resources/config/theme -type d -exec chmod +a 'user:kmihalj allow read,write,append,execute,delete,readattr,writeattr,readextattr,writeextattr,readsecurity,file_inherit,directory_inherit' {} +
ls -lde config data data/sessions data/tmp resources/config/menu resources/config/theme

The ACL syntax above is macOS-specific. On Linux use narrowly scoped setfacl entries and inherited defaults for the web and maintenance accounts. After installation verify that the maintainer can read private files the wizard created with mode 0600; a POSIX ACL mask may otherwise deny access. Never use chmod 777 as a workaround.

3. Configure Apache and verify the real handler

The lab used a separate loopback-only Apache instance. The excerpt shows the actual alias and mod_php handler; a public deployment should use a TLS virtual host on port 443 with DocumentRoot /srv/simbioza/public and a valid certificate. Do not attach both a mod_php and an FPM handler to the same application.

Listen 127.0.0.1:8090
LoadModule mpm_prefork_module lib/httpd/modules/mod_mpm_prefork.so
LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so
LoadModule php_module /opt/homebrew/opt/php/lib/httpd/modules/libphp.so
User _www
Group _www
Alias /SimbiozaEN "/Users/Shared/Simbioza/SimbiozaEN/public"
<Directory "/Users/Shared/Simbioza/SimbiozaEN/public">
    Options -Indexes +FollowSymLinks
    AllowOverride All
    Require local
    DirectoryIndex index.php
    <FilesMatch "\.php$">
        SetHandler application/x-httpd-php
    </FilesMatch>
</Directory>
/opt/homebrew/bin/httpd -t -f /opt/homebrew/etc/httpd/extra/httpd-simbioza-install-guides.conf
sudo /opt/homebrew/bin/httpd -k graceful -f /opt/homebrew/etc/httpd/extra/httpd-simbioza-install-guides.conf
curl -I http://127.0.0.1:8090/SimbiozaEN/

Syntax OK validates only the configuration grammar. Follow it with a real HTTP request and confirmation of the PHP version and identity used by Apache. For a public host replace Require local with your access rule, enable HTTPS and redirect plain HTTP. Do not expose an installer token over the public internet.

4. Prepare optional packages, then create a one-time installer URL

mod_php has no privileged Composer helper, so the release owner prepares packages in the CLI before opening the wizard. With no list, php scripts/installation_packages.php prepare prepares every optional module; in the updated wizard all start selected and you deselect what you do not need. For a smaller set, run, for example, php scripts/installation_packages.php prepare --modules=theme,calendar,email, check php scripts/installation_packages.php status, and deselect the others in the wizard. To select no optional module, use --modules=; the temporary Backup still imports the starter guides. After installation, the release owner runs php scripts/installation_packages.php cleanup. The screenshots record the 0.2.4 test, where only Theme was prepared. The token returned by the last command is intentionally omitted below.

cd /Users/Shared/Simbioza/SimbiozaEN
php scripts/installation_packages.php prepare
php scripts/installation_packages.php status
php bin/simbioza install:prepare --base-url=http://127.0.0.1:8090/SimbiozaEN

5. English installation: each screen

On a browser whose system language is Croatian, the wizard initially appeared in Croatian. We explicitly selected English in its header before capturing these steps. This changes the wizard language; the site's primary language is selected separately in the application form.

English installer requirements screen; every check passes.
Screen 1 — requirements. Review PHP, required extensions, database drivers, writable runtime paths, migrations and bundled starter packages one row at a time. Every required check must pass before Continue is enabled. These are results from the independent EN installation, not a translated picture of another site.
English installer SQLite database selection and connection test.
Screen 2 — database. SQLite is selected for this isolated site, so the network host and credential fields do not apply. Test connection and continue opens a real connection and runs a probe query. With MySQL or PostgreSQL, enter the empty database and dedicated DB user's connection data prepared earlier.
Blank English site, language, module and first-administrator form.
Screen 3 — before entry. The form groups the application name, primary and available languages, time zone, optional modules and first admin credentials. English is the primary language here; Croatian and English are initially available. Theme is selectable because it was prepared in the CLI, while other unprepared packages remain visible with a clear explanation.
Completed EN application and admin form with masked password fields.
Screen 3 — completed form. The test site is named “Simbioza EN” and uses its own first-admin login. The local default time zone was UTC; choose your actual location if different. Use a unique strong password, record it in a password manager and never copy it into installation notes.
English final review of SQLite, language, theme, timezone and admin.
Screen 4 — review. Compare the site name, database, EN primary language, available languages, Theme, time zone, login identifier and e-mail against your plan. Passwords are deliberately absent from the review HTML. Only then select Install Simbioza; this applies migrations and creates the first administrator.
English installer success confirmation.
Screen 5 — success. The confirmation means migrations, selected modules, initial guides and admin creation completed. The one-time URL can no longer be reused. If instead you see an error, inspect the job and technical logs before retrying; do not blindly run the installer twice.
English local sign-in screen after selecting English.
First sign-in. Follow Open sign in and use the newly created login identifier and password. The browser may still prefer Croatian based on its OS language; select English in the header to make the login screen match this guide. That browser choice does not alter stored page languages.
Fresh English Simbioza home page after the first admin sign-in.
First application view. Verify the real rendered theme, navigation and starter content, not merely an HTTP status code. Open Settings → Setup and modules to check that Theme is enabled. Also confirm there are no PHP warnings and that the new installation has its own SQLite file and sessions.

6. Final checks and supported maintenance

Remove the temporary Backup package unless you explicitly selected Backup as a module. Run each check from the English site directory. In this test the login URL returned HTTP 200, the locked installer URL returned 404, and the site had 22 executed migrations with zero pending.

cd /Users/Shared/Simbioza/SimbiozaEN
php scripts/installation_packages.php cleanup
vendor/bin/hph modules migrate-status
composer check-platform-reqs
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8090/SimbiozaEN/auth/login
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8090/SimbiozaEN/install

The Settings → Setup and modules page can enable or disable an already installed module under mod_php. Adding/removing Composer packages, installing language packages and upgrading the application are CLI tasks run as the Unix owner of the code, never as Apache or root:

vendor/bin/hph modules list
vendor/bin/hph modules add calendar --fresh
vendor/bin/hph modules disable calendar
vendor/bin/hph modules enable calendar
vendor/bin/hph modules backups calendar
vendor/bin/hph modules remove calendar --yes
vendor/bin/hph modules add calendar --restore
vendor/bin/hph languages available
vendor/bin/hph languages install de
vendor/bin/hph languages update
php update.php --check
php update.php

Disabling keeps data; removing first makes a module data backup and then removes the package. Before a production upgrade separately back up the database, config/, uploaded files and themes. Afterward check migrations and real login and page rendering. Do not replace the updater with a bare composer update on an existing site: Simbioza's updater preserves the selected optional-module set.

References: release 0.2.4, Apache LoadModule, PHP with Apache. For Nginx or production FPM, continue with the sibling FPM guide.

Attachments

File Version File type Size Uploaded by
SimbiozaEN-08-home.png v1 image/png 190.7 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaEN-07-login.png v1 image/png 150.0 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaEN-06-success.png v1 image/png 54.5 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaEN-05-review.png v1 image/png 82.3 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaEN-04-application-filled.png v1 image/png 175.2 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaEN-03-application-blank.png v1 image/png 162.9 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaEN-02-database.png v1 image/png 72.0 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaEN-01-prerequisites.png v1 image/png 138.6 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaHR-08-home.png v1 image/png 202.8 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaHR-07-login.png v1 image/png 152.3 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaHR-06-success.png v1 image/png 55.5 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaHR-05-review.png v1 image/png 83.9 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaHR-04-application-filled.png v1 image/png 182.9 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaHR-03-application-blank.png v1 image/png 170.1 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaHR-02-database.png v1 image/png 71.9 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM
SimbiozaHR-01-prerequisites.png v1 image/png 145.8 KB Krešimir Mihalj · Sep 28, 2026, 6:55 PM

Comments

0

There are no comments yet.

You must sign in to add a comment.

Created: Krešimir Mihalj Sep 28, 2026, 6:27 PM · Last modified: Krešimir Mihalj Sep 30, 2026, 11:26 AM