{"id":991,"date":"2026-11-03T03:00:00","date_gmt":"2026-11-03T03:00:00","guid":{"rendered":"https:\/\/vpslake.com\/blog\/?p=991"},"modified":"2026-11-03T03:00:00","modified_gmt":"2026-11-03T03:00:00","slug":"install-admidio-lamp-rockylinux-8","status":"publish","type":"post","link":"https:\/\/vpslake.com\/blog\/2026\/11\/03\/install-admidio-lamp-rockylinux-8\/","title":{"rendered":"How to Install Admidio with LAMP on Rocky Linux 8"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Install Admidio with LAMP Stack on Rocky Linux 8 to run a private membership portal with Apache, PHP 8.2, and MariaDB. This guide takes about 15\u201320 minutes on a fresh VPS and finishes with HTTPS and a browser-based 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>Rocky Linux 8.10, updated through the official repositories.<\/li>\n\n\n<li>A fresh VPS with at least 2 GB RAM and 10 GB of available disk space for the application, database, uploads, and backups.<\/li>\n\n\n<li>A root account or a sudo-enabled user connected through SSH.<\/li>\n\n\n<li>A domain such as <code>YOUR_DOMAIN<\/code> with an A record pointing to the server; ports 80 and 443 must be reachable.<\/li>\n\n\n<li>A <a href=\"https:\/\/vpslake.com\/buy-vps\">VPSLake Linux VPS<\/a> with a public IPv4 address.<\/li>\n\n\n<li>A unique database password and a separate strong password for the first Admidio administrator.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Admidio 5.0.16 requires PHP 8.2 or newer and supports MariaDB 10.0 or newer. Rocky Linux 8\u2019s AppStream includes PHP 8.2, while its MariaDB package satisfies the database requirement; the current release and requirements are listed on the official <a href=\"https:\/\/www.admidio.org\/download.php\" target=\"_blank\" rel=\"noopener\">Admidio download page<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Install Apache, PHP, MariaDB, and firewall tools<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Rocky Linux 8 defaults to an older PHP stream, so select PHP 8.2 before installing the web stack and the extensions Admidio uses.<\/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-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\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\">The <code>php<\/code> package supplies Apache\u2019s PHP module on this LAMP setup, so PHP-FPM is not needed. Check that Rocky enabled the intended stream and that both services are running.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php -v\nsudo systemctl is-active httpd mariadb<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>PHP 8.2.x (cli) ...\nactive\nactive<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The official <a href=\"https:\/\/docs.rockylinux.org\/8\/guides\/web\/php\/\" target=\"_blank\" rel=\"noopener\">Rocky Linux PHP documentation<\/a> also uses the PHP 8.2 AppStream and <code>firewalld<\/code> service rules for this release.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Prepare a local MariaDB database<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A separate database account limits Admidio\u2019s access to one schema and keeps MariaDB closed to the public network.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Run the hardening assistant and remove anonymous accounts, remote root access, and the test database when prompted.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mariadb-secure-installation<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create the schema and account. Replace <code>YOUR_DB_PASSWORD<\/code> before executing the block; use a long password that is not reused anywhere else.<\/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\">Do not add a MariaDB rule to <code>firewalld<\/code>. Apache and MariaDB share this server, so the application can use the local socket or <code>localhost<\/code> without exposing port 3306.<\/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\">The virtual host gives Admidio its own document root and allows the rewrite rules shipped in its <code>.htaccess<\/code> files.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Replace <code>YOUR_DOMAIN<\/code> in the following block with the real hostname before running 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<p class=\"wp-block-paragraph\">If DNS has not propagated yet, Apache can still be configured now; the domain must resolve to this VPS before you request a certificate.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Download Admidio and apply SELinux-safe permissions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Download the release ZIP from the project\u2019s official distribution path, then keep application code read-only to the web server and make only Admidio\u2019s data directory writable.<\/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'\nrm -rf \/tmp\/admidio-unpack\nmkdir \/tmp\/admidio-unpack\nunzip -q admidio-5.0.16.zip -d \/tmp\/admidio-unpack\nsrc=$(find \/tmp\/admidio-unpack -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\">Admidio writes its configuration, uploads, and generated files under <code>adm_my_files<\/code>. The persistent file-context rules below let Apache read the code while allowing writes only in that directory.<\/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 reload httpd<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The final Apache check should again show <code>Syntax OK<\/code>. Unlike a broad writable web root, these modes preserve SELinux enforcement and reduce the damage a compromised PHP file could cause.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Run the Admidio browser installer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The web wizard checks the PHP environment, creates Admidio\u2019s tables, and writes its configuration using the database account from Step 2.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open <code>http:\/\/YOUR_DOMAIN\/<\/code> in a browser. Select a language, then enter the following database values:<\/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: the default value<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Continue with the organization name, sender email address, and a new administrator account. When the wizard reaches its completion page, sign in once and remove the downloaded archive.<\/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<p class=\"wp-block-paragraph\">If the installer reports that <code>adm_my_files<\/code> is not writable, stop and fix the ownership and SELinux labels from Step 4 before continuing.<\/p>\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 portal can contain names, email addresses, and other member information, so switch the working HTTP site to HTTPS after the domain resolves correctly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Install Certbot from EPEL and let its Apache plugin create the certificate and redirect.<\/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\">Replace <code>ADMIN_EMAIL<\/code> and <code>YOUR_DOMAIN<\/code> with real values. Port 80 must remain reachable while Let\u2019s Encrypt validates the domain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Test the renewal process 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\">These checks confirm that PHP has the important extensions, MariaDB contains the application database, the services are active, and Apache answers over TLS.<\/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\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\nHTTP\/1.1 200 OK<\/code><\/pre>\n\n\n\n<aside class=\"vl-element vl-cta-banner\" aria-label=\"Host your Admidio portal\">\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\">Host your Admidio portal<\/h3>\n\t\t<p class=\"vl-cta-banner__text\">Launch a secure Rocky Linux VPS for Apache, MariaDB, PHP, and your organization.<\/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 package metadata is stale, or the server is not using the Rocky Linux 8 AppStream repository. Confirm the release and refresh DNF before selecting the stream again.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/etc\/rocky-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\">Check that the request uses <code>YOUR_DOMAIN<\/code>, the virtual host points to <code>\/var\/www\/admidio<\/code>, and SELinux has the expected labels. Reapply the persistent contexts instead of disabling SELinux.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apachectl -S\nsudo restorecon -Rv \/var\/www\/admidio\nls -Zd \/var\/www\/admidio \/var\/www\/admidio\/adm_my_files\nsudo ausearch -m AVC -ts recent<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The application directory should have <code>httpd_sys_content_t<\/code>, while <code>adm_my_files<\/code> should have <code>httpd_sys_rw_content_t<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The installer says <code>could not find driver<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">PHP is running, but the MariaDB PDO driver is absent from the active stream. Install the missing extensions and reload Apache so its PHP module sees them.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dnf install -y php-mysqlnd php-xml php-zip php-gd php-curl php-intl php-mbstring\nsudo systemctl restart httpd\nphp -m | grep -E 'PDO|pdo_mysql|SimpleXML|zip'<\/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 entered in the browser does not match the MariaDB account, or the account was created for a different host. Reset it locally and enter the new value in the installer.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mariadb &lt;&lt;'SQL'\nALTER USER 'admidio'@'localhost' IDENTIFIED BY 'NEW_DB_PASSWORD';\nFLUSH PRIVILEGES;\nSQL<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Replace <code>NEW_DB_PASSWORD<\/code> before running the command and do not put the new password in a public ticket or shell history.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hardening<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Keep Rocky Linux and Admidio updated, and back up both the <code>admidio<\/code> database and <code>\/var\/www\/admidio\/adm_my_files<\/code> before upgrades.<\/li>\n\n\n<li>Leave only SSH, HTTP, and HTTPS enabled in <code>firewalld<\/code>; do not expose MariaDB to the internet.<\/li>\n\n\n<li>Use a different password for the Admidio administrator, database user, and VPS account, then enable available account protections in Admidio.<\/li>\n\n\n<li>Review the per-site Apache logs in <code>\/var\/log\/httpd\/<\/code> when investigating failed requests or repeated login attempts.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Is Rocky Linux 8 compatible with the current Admidio release?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes. The current Admidio release needs PHP 8.2 or newer, and Rocky Linux 8 provides PHP 8.2 through AppStream. Updating Rocky first is important because an untouched installation may still select the older PHP 7.2 stream.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Does Admidio need PHP-FPM on Apache?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. This guide uses Apache\u2019s PHP module from the Rocky package set, which is sufficient for a single-site LAMP installation. PHP-FPM is useful for a different Apache or Nginx design, but adding it here would create an unnecessary second PHP path to maintain.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Can I install Admidio using the VPS IP instead of a domain?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You can use the IP for an initial HTTP test, but a domain is the practical production choice. Let\u2019s Encrypt normally validates a hostname, and the certificate command in this guide expects a DNS record pointing to the VPS.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What should I back up after installation?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Back up the MariaDB <code>admidio<\/code> schema and the complete <code>\/var\/www\/admidio\/adm_my_files<\/code> directory. The data directory contains the generated configuration and member uploads, while the database contains the organization and account records.<\/p>\n\n\n\n<script type=\"application\/ld+json\">{\"@context\": \"https:\/\/schema.org\", \"@type\": \"FAQPage\", \"mainEntity\": [{\"@type\": \"Question\", \"name\": \"Is Rocky Linux 8 compatible with the current Admidio release?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Yes. The current Admidio release needs PHP 8.2 or newer, and Rocky Linux 8 provides PHP 8.2 through AppStream. Updating Rocky first is important because an untouched installation may still select the older PHP 7.2 stream.\"}}, {\"@type\": \"Question\", \"name\": \"Does Admidio need PHP-FPM on Apache?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. This guide uses Apache\u2019s PHP module from the Rocky package set, which is sufficient for a single-site LAMP installation. PHP-FPM is useful for a different Apache or Nginx design, but adding it here would create an unnecessary second PHP path to maintain.\"}}, {\"@type\": \"Question\", \"name\": \"Can I install Admidio using the VPS IP instead of a domain?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"You can use the IP for an initial HTTP test, but a domain is the practical production choice. Let\u2019s Encrypt normally validates a hostname, and the certificate command in this guide expects a DNS record pointing to the VPS.\"}}, {\"@type\": \"Question\", \"name\": \"What should I back up after installation?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Back up the MariaDB `admidio` schema and the complete `\/var\/www\/admidio\/adm_my_files` directory. The data directory contains the generated configuration and member uploads, while the database contains the organization and account records.\"}}]}<\/script>\n\n","protected":false},"excerpt":{"rendered":"Install Admidio with LAMP Stack on Rocky Linux 8 using PHP 8.2, MariaDB, Apache, SELinux-safe permissions, HTTPS, and a guided browser setup.","protected":false},"author":1,"featured_media":992,"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,71,117,73,105],"class_list":["post-991","post","type-post","status-publish","format-standard","has-post-thumbnail","category-guides","category-vps-hosting","tag-admidio","tag-apache","tag-lamp-stack","tag-mariadb","tag-rocky-linux-8","cs-entry"],"_links":{"self":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/991","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=991"}],"version-history":[{"count":1,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/991\/revisions"}],"predecessor-version":[{"id":3862,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/991\/revisions\/3862"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media\/992"}],"wp:attachment":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media?parent=991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/categories?post=991"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/tags?post=991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}