{"id":989,"date":"2026-11-02T18:00:00","date_gmt":"2026-11-02T18:00:00","guid":{"rendered":"https:\/\/vpslake.com\/blog\/?p=989"},"modified":"2026-11-02T18:00:00","modified_gmt":"2026-11-02T18:00:00","slug":"install-admidio-lamp-almalinux-8","status":"publish","type":"post","link":"https:\/\/vpslake.com\/blog\/2026\/11\/02\/install-admidio-lamp-almalinux-8\/","title":{"rendered":"How to Install Admidio with LAMP on AlmaLinux 8"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Install Admidio with LAMP Stack on AlmaLinux 8 by deploying Apache, MariaDB, and PHP 8.2, then completing the membership-management installer in your browser. Allow about 15\u201320 minutes for a clean VPS, including the initial HTTPS setup.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>AlmaLinux 8.10 on a fresh VPS, with system updates available.<\/li>\n\n\n<li>At least 2 GB RAM and 10 GB free disk space for the application, database, uploads, and backups.<\/li>\n\n\n<li>Root access or a sudo-enabled user connected over SSH.<\/li>\n\n\n<li>A domain such as <code>YOUR_DOMAIN<\/code> with an A record pointing to the VPS; ports 80 and 443 must be reachable.<\/li>\n\n\n<li>A Linux server from <a href=\"https:\/\/vpslake.com\/buy-vps\">VPSLake<\/a> with a public IPv4 address.<\/li>\n\n\n<li>A long database password and a separate administrator password for the Admidio web installer.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Admidio 5 requires PHP 8.2 or newer and supports MariaDB 10 or newer. AlmaLinux 8.10 includes the PHP 8.2 Application Stream, so this guide selects that stream rather than installing the old PHP version that may be enabled by default. See the official <a href=\"https:\/\/www.admidio.org\/download.php\" target=\"_blank\" rel=\"noopener\">Admidio download page<\/a> for the current release and requirements.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Install the LAMP packages<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use AlmaLinux\u2019s <code>dnf<\/code> modules to select PHP 8.2, then install Apache, MariaDB, the PHP extensions Admidio needs, and the tools used later for extraction and SELinux labeling.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dnf -y update\nsudo dnf module reset php -y\nsudo dnf module enable php:8.2 -y\nsudo dnf install -y httpd mariadb-server php php-cli php-common php-fpm php-curl php-gd php-intl php-mbstring php-mysqlnd php-opcache php-pdo php-xml php-zip unzip curl policycoreutils-python-utils firewalld mod_ssl\nsudo systemctl enable --now firewalld httpd mariadb php-fpm\nsudo firewall-cmd --permanent --zone=public --add-service=ssh\nsudo firewall-cmd --permanent --zone=public --add-service=http\nsudo firewall-cmd --permanent --zone=public --add-service=https\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Confirm that the selected PHP stream and both LAMP services are available before adding the application.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php -v\nsudo systemctl is-active httpd mariadb php-fpm<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>PHP 8.2.x (cli) ...\nactive\nactive\nactive<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Secure MariaDB and create the Admidio database<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The hardening script removes default accounts and test data; the SQL that follows gives Admidio access only to its own local database.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mysql_secure_installation<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When prompted, remove anonymous users, prevent remote root login, remove the test database, and reload the privilege tables. The exact root-password questions depend on the MariaDB package already installed on the VPS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a database and a dedicated account. Replace <code>YOUR_DB_PASSWORD<\/code> with a unique password before running this block; do not reuse the VPS or Admidio administrator password.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mariadb &lt;&lt;'SQL'\nCREATE DATABASE admidio CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\nCREATE USER 'admidio'@'localhost' IDENTIFIED BY 'YOUR_DB_PASSWORD';\nGRANT ALL PRIVILEGES ON admidio.* TO 'admidio'@'localhost';\nFLUSH PRIVILEGES;\nSQL<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The database remains bound to the server\u2019s local MariaDB socket, so there is no reason to open port 3306 in the firewall.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Create the Apache virtual host<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A dedicated virtual host keeps Admidio\u2019s files separate from other sites and enables its <code>.htaccess<\/code> rules.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Replace every <code>YOUR_DOMAIN<\/code> token in this block with the real hostname before you run it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir -p \/var\/www\/admidio\nsudo tee \/etc\/httpd\/conf.d\/YOUR_DOMAIN.conf &gt; \/dev\/null &lt;&lt;'APACHE'\n&lt;VirtualHost *:80&gt;\n    ServerName YOUR_DOMAIN\n    DocumentRoot \/var\/www\/admidio\n\n    &lt;Directory \/var\/www\/admidio&gt;\n        Options -Indexes +FollowSymLinks\n        AllowOverride All\n        Require all granted\n    &lt;\/Directory&gt;\n\n    DirectoryIndex index.php index.html\n    ErrorLog \/var\/log\/httpd\/YOUR_DOMAIN-error.log\n    CustomLog \/var\/log\/httpd\/YOUR_DOMAIN-access.log combined\n&lt;\/VirtualHost&gt;\nAPACHE\nsudo apachectl configtest\nsudo systemctl reload httpd<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Syntax OK<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Download Admidio and set safe permissions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Download the current release from the project\u2019s official download endpoint, make the web server the owner only of Admidio\u2019s data directory, and apply SELinux rules that survive a relabel or reboot.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd \/tmp\ncurl -fL -o admidio-5.0.16.zip 'https:\/\/sourceforge.net\/projects\/admidio\/files\/Admidio\/5.0.x\/admidio-5.0.16.zip\/download'\nsudo rm -rf \/tmp\/admidio-extract \/var\/www\/admidio\nsudo mkdir -p \/tmp\/admidio-extract \/var\/www\/admidio\nunzip -q admidio-5.0.16.zip -d \/tmp\/admidio-extract\nsrc=$(find \/tmp\/admidio-extract -mindepth 1 -maxdepth 2 -type f -name index.php -print -quit)\ntest -n \"$src\"\nsudo cp -a \"$(dirname \"$src\")\"\/. \/var\/www\/admidio\/<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Keep application code owned by root and writable application data owned by Apache. This avoids making the whole web root writable.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo chown -R root:apache \/var\/www\/admidio\nsudo find \/var\/www\/admidio -type d -exec chmod 0755 {} \\;\nsudo find \/var\/www\/admidio -type f -exec chmod 0644 {} \\;\nsudo chown -R apache:apache \/var\/www\/admidio\/adm_my_files\nsudo find \/var\/www\/admidio\/adm_my_files -type d -exec chmod 0750 {} \\;\nsudo find \/var\/www\/admidio\/adm_my_files -type f -exec chmod 0640 {} \\;\nsudo semanage fcontext -a -t httpd_sys_content_t '\/var\/www\/admidio(\/.*)?'\nsudo semanage fcontext -a -t httpd_sys_rw_content_t '\/var\/www\/admidio\/adm_my_files(\/.*)?'\nsudo restorecon -Rv \/var\/www\/admidio\nsudo apachectl configtest\nsudo systemctl restart php-fpm httpd<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The expected final check is <code>Syntax OK<\/code>; <code>restorecon<\/code> may also print the files whose labels it changed. Do not delete <code>adm_my_files<\/code>: Admidio uses it for its generated configuration, uploads, and other user data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Complete the Admidio web installer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The browser wizard writes <code>config.php<\/code>, checks PHP extensions, and creates the application tables from the database details you prepared.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open <code>http:\/\/YOUR_DOMAIN\/<\/code> in a browser. Choose a language, then enter these values when the database page appears:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Database type: MariaDB or MySQL<\/li>\n\n\n<li>Database host: <code>localhost<\/code><\/li>\n\n\n<li>Database name: <code>admidio<\/code><\/li>\n\n\n<li>Database user: <code>admidio<\/code><\/li>\n\n\n<li>Database password: the value used for <code>YOUR_DB_PASSWORD<\/code><\/li>\n\n\n<li>Database port: leave the default unless you changed MariaDB\u2019s port<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Continue with your organization name, sender email address, and the first administrator account. When the wizard finishes, sign in with that administrator account and remove the temporary ZIP file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rm -f \/tmp\/admidio-5.0.16.zip<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 6: Enable HTTPS with Let\u2019s Encrypt<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The membership portal handles personal data, so redirect its HTTP traffic to HTTPS after DNS resolves to this server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Run this only after <code>YOUR_DOMAIN<\/code> points to the VPS and port 80 is reachable from the internet. Replace <code>ADMIN_EMAIL<\/code> with an address that receives certificate notices.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dnf install -y epel-release\nsudo dnf install -y certbot python3-certbot-apache\nsudo certbot --apache --redirect --agree-tos --no-eff-email -m ADMIN_EMAIL -d YOUR_DOMAIN<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Certbot updates the Apache configuration and installs automatic renewal hooks. Test renewal without replacing the live certificate:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot renew --dry-run<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Congratulations, all simulated renewals succeeded<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Verify the installation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Check PHP\u2019s required extensions, the database\u2019s presence, and the public HTTPS response. A <code>200<\/code> or an expected redirect from the application confirms that Apache is serving Admidio.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php -m | grep -E 'curl|gd|intl|mbstring|PDO|pdo_mysql|SimpleXML|zip'\nsudo mariadb -e \"SHOW DATABASES LIKE 'admidio';\"\nsudo systemctl is-active httpd mariadb php-fpm\ncurl -I https:\/\/YOUR_DOMAIN\/<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>curl\ngd\nintl\nmbstring\nPDO\npdo_mysql\nSimpleXML\nzip\nadmidio\nactive\nactive\nactive\nHTTP\/1.1 200 OK<\/code><\/pre>\n\n\n\n<aside class=\"vl-element vl-cta-banner\" aria-label=\"Run Admidio on AlmaLinux\">\n\t<div class=\"vl-cta-banner__content\">\n\t\t<p class=\"vl-cta-banner__eyebrow\">Linux VPS hosting<\/p>\n\t\t<h3 class=\"vl-cta-banner__title\">Run Admidio on AlmaLinux<\/h3>\n\t\t<p class=\"vl-cta-banner__text\">Deploy a reliable Linux VPS for your Apache, MariaDB, and PHP membership portal.<\/p>\n\t<\/div>\n\t<a class=\"vl-cta-banner__button\" href=\"\/buy-vps\" aria-label=\"View Linux VPS\">View Linux VPS<\/a>\n<\/aside>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><code>No matching module streams for php:8.2<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The server is probably not on the AlmaLinux 8.10 repositories or its DNF metadata is stale. Refresh metadata and confirm the release, then enable the stream again.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/etc\/almalinux-release\nsudo dnf clean all\nsudo dnf makecache\nsudo dnf module list php\nsudo dnf module enable php:8.2 -y<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Apache returns <code>403 Forbidden<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The usual causes are an incorrect virtual-host path or an SELinux label that does not allow Apache to read the files. Check the vhost, reapply the persistent contexts, and inspect recent denials.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apachectl -S\nsudo restorecon -Rv \/var\/www\/admidio\nsudo ausearch -m AVC -ts recent<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the denial names <code>adm_my_files<\/code>, confirm that directory has the <code>httpd_sys_rw_content_t<\/code> type and that its owner is <code>apache<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The installer reports a missing PHP extension<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The PHP CLI and Apache module must use the same PHP stream. Check the version and loaded modules, install the missing package from the enabled 8.2 stream, and restart Apache.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php -v\nphp -m\nsudo dnf module list php\nsudo systemctl restart httpd<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><code>Access denied for user 'admidio'@'localhost'<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The password in the browser must exactly match the password used when the MariaDB account was created. Reset that account locally, then enter the new value in the installer.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mariadb\nALTER USER 'admidio'@'localhost' IDENTIFIED BY 'NEW_DB_PASSWORD';\nFLUSH PRIVILEGES;\nEXIT<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Hardening<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Keep AlmaLinux and Admidio updated, and take a database plus <code>\/var\/www\/admidio\/adm_my_files<\/code> backup before upgrades.<\/li>\n\n\n<li>Leave MariaDB on localhost and expose only SSH, HTTP, and HTTPS through <code>firewalld<\/code>.<\/li>\n\n\n<li>Use a separate administrator password for Admidio and enable its available two-factor authentication after signing in.<\/li>\n\n\n<li>Review <code>\/var\/log\/httpd\/YOUR_DOMAIN-access.log<\/code> and <code>\/var\/log\/httpd\/YOUR_DOMAIN-error.log<\/code> when diagnosing failed requests.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Can Admidio run on AlmaLinux 8?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes. AlmaLinux 8.10 provides the PHP 8.2 stream required by the current Admidio release, and MariaDB from the distribution meets Admidio\u2019s database requirement. Keep the server on the supported 8.x update channel.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Do I need to expose MariaDB to the internet?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. The Apache and PHP application runs on the same VPS as MariaDB, so <code>localhost<\/code> is enough. Keeping port 3306 closed reduces the number of services reachable from outside.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Why does Admidio need a writable <code>adm_my_files<\/code> directory?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The installer stores <code>config.php<\/code> there, and the application uses the directory for uploads and generated data. Only that directory is writable by Apache in this guide; the application code remains owned by root.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Can I install Admidio without a domain name?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You can test the initial HTTP page with the VPS IP address, but HTTPS certificates normally require a domain name that resolves publicly. Use a domain before creating the production installation and administrator account.<\/p>\n\n\n\n<script type=\"application\/ld+json\">{\"@context\": \"https:\/\/schema.org\", \"@type\": \"FAQPage\", \"mainEntity\": [{\"@type\": \"Question\", \"name\": \"Can Admidio run on AlmaLinux 8?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Yes. AlmaLinux 8.10 provides the PHP 8.2 stream required by the current Admidio release, and MariaDB from the distribution meets Admidio\u2019s database requirement. Keep the server on the supported 8.x update channel.\"}}, {\"@type\": \"Question\", \"name\": \"Do I need to expose MariaDB to the internet?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. The Apache and PHP application runs on the same VPS as MariaDB, so `localhost` is enough. Keeping port 3306 closed reduces the number of services reachable from outside.\"}}, {\"@type\": \"Question\", \"name\": \"Why does Admidio need a writable `adm_my_files` directory?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"The installer stores `config.php` there, and the application uses the directory for uploads and generated data. Only that directory is writable by Apache in this guide; the application code remains owned by root.\"}}, {\"@type\": \"Question\", \"name\": \"Can I install Admidio without a domain name?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"You can test the initial HTTP page with the VPS IP address, but HTTPS certificates normally require a domain name that resolves publicly. Use a domain before creating the production installation and administrator account.\"}}]}<\/script>\n\n","protected":false},"excerpt":{"rendered":"Install Admidio with LAMP Stack on AlmaLinux 8 using PHP 8.2, MariaDB, Apache, SELinux-safe permissions, HTTPS, and a guided browser setup for production.","protected":false},"author":1,"featured_media":990,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_singular_sidebar":"","csco_page_header_type":"","csco_page_load_nextpost":"","footnotes":""},"categories":[5,9],"tags":[116,94,71,117,73],"class_list":["post-989","post","type-post","status-publish","format-standard","has-post-thumbnail","category-guides","category-vps-hosting","tag-admidio","tag-almalinux-8","tag-apache","tag-lamp-stack","tag-mariadb","cs-entry"],"_links":{"self":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/989","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/comments?post=989"}],"version-history":[{"count":1,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/989\/revisions"}],"predecessor-version":[{"id":3857,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/989\/revisions\/3857"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media\/990"}],"wp:attachment":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media?parent=989"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/categories?post=989"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/tags?post=989"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}