Deploying ElmapiCMS on a VPS
This guide is for a virtual private server (VPS) or dedicated machine where you have SSH access and install the web stack yourself (for example Nginx or Apache, PHP-FPM, and MySQL or MariaDB).
You deploy the full Laravel application—from your Git fork or from elmapicms.zip.
Assumptions: you are comfortable on the command line and can open firewall ports, point DNS at the server, and edit config files. Examples use Ubuntu-style paths and package names; adapt commands for Debian, AlmaLinux, or your distribution.
1. Prerequisites
Before you begin, ensure you have:
- A VPS with root or
sudoSSH access - A domain (or subdomain) whose DNS A (or AAAA) record points at the server’s public IP
- PHP and extensions that meet ElmapiCMS server requirements (PHP ≥ 8.4 and the usual Laravel extensions)
- Composer installed globally or available as
composer - MySQL or MariaDB
- Git (if you deploy by cloning a repository)
2. Prepare your application source
Read Deployment overview for the fork rule. The machine must not use the vendor private repository as its deploy remote.
Ways to get code onto the server:
git cloneyour fork (or your own mirror) into a directory such as/var/www/elmapi.- Upload
elmapicms.zip(CodeCanyon download or your own archive) over SCP/SFTP, extract on the server, then optionallygit initand push to your own remote for future pulls. CodeCanyon package details: For CodeCanyon buyers.
3. Install the web stack
Install a web server, PHP-FPM, and the database client libraries your distribution provides. Exact package names differ by OS; your goal is:
- PHP-FPM running with the extensions required by Laravel and ElmapiCMS
- A vhost whose document root is the application’s
publicdirectory (not the project root)
Nginx (conceptual): root should point to /var/www/elmapi/public (or wherever you cloned the app). Pass PHP to PHP-FPM (for example a location ~ \.php$ block with fastcgi_pass to the FPM socket).
Apache: use mod_php or php-fpm with DocumentRoot set to the same public path.
Configure URL rewriting so requests hit public/index.php(Nginx try_files / Laravel’s suggested snippet, or Apache AllowOverride All with the included .htaccess in public) .
4. Create the database
- Create a database and a user with a strong password.
- Grant that user all privileges on that database only.
- Keep host (
localhostor127.0.0.1if the DB is on the same VPS), database name, username, and password ready for.env.
5. Deploy dependencies and optimize
On the server, from the application root (the directory that contains artisan):
cd /var/www/elmapi
composer install --no-dev --optimize-autoloaderIf you deploy updates from Git, run git pull (or your deployment script), then composer install again when composer.lock changes.
Use a deploy user that owns the application files, and run Artisan as that user—not as root—so permissions stay predictable.
6. File permissions
Ensure the web server user can write Laravel’s writable directories:
storagebootstrap/cache
Typical approach (adjust user/group to match your PHP-FPM pool, often www-data on Ubuntu):
sudo chown -R deploy:www-data storage bootstrap/cache
sudo find storage bootstrap/cache -type d -exec chmod 775 {} \;
sudo find storage bootstrap/cache -type f -exec chmod 664 {} \;7. Configure the environment
- Copy
.env.exampleto.envif.envdoes not exist yet. - Set
APP_URLto your public URL (includinghttps://in production). - Set
DB_*to match the database you created. - For production, set
APP_DEBUG=falseand a strongAPP_KEY(see next section).
APP_URL=https://your-domain.com
APP_DEBUG=false
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=elmapicms
DB_USERNAME=elmapicms_user
DB_PASSWORD=your_strong_password8. Application key, migrations, and seed
From the application root:
php artisan key:generate
php artisan migrate --seed --forceNever commit .env or expose it publicly. Restrict file permissions on the server (chmod 600 .env is a reasonable default).
9. HTTPS
Use Let’s Encrypt (for example Certbot) or your provider’s TLS offering so the site is served over HTTPS and matches APP_URL.
10. Scheduler (cron)
Laravel’s scheduler should run once per minute as the deploy user. Example crontab line (replace paths and PHP binary):
* * * * * cd /var/www/elmapi && /usr/bin/php artisan schedule:run >> /dev/null 2>&111. Queue worker and webhooks
For webhooks to run in the background, set QUEUE_CONNECTION=database (or redis if you run Redis) in .env and keep a queue worker running. See Configuring queues for webhooks for driver details.
On a VPS, use Supervisor, systemd, or another process manager so queue:work restarts if it exits. Example Supervisor program (adjust paths, user, and PHP):
[program:elmapi-queue]
process_name=%(program_name)s
command=/usr/bin/php /var/www/elmapi/artisan queue:work database --queue=webhooks --sleep=3 --tries=3
autostart=true
autorestart=true
user=deploy
redirect_stderr=true
stdout_logfile=/var/www/elmapi/storage/logs/worker.log
stopwaitsecs=3600Webhook jobs use the webhooks queue. The worker must listen to that name (--queue=webhooks).
Reload Supervisor after changing config:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start elmapi-queue:*12. Login
After seeding, a default admin exists. Sign in with:
Email:
[email protected]Password:
passwordChange the email and password after first login.