VPS Installation
Install MediaDesk on your own Ubuntu server with nginx, from an empty server to a live site.
Item: MediaDesk — Multilingual AI-Powered Newsroom ERP
Before You Start
This guide installs MediaDesk on a fresh Ubuntu 24.04 server with nginx. You run every command over SSH. On other Linux systems the package names differ, and the steps stay the same.
| You need | Details |
|---|---|
| A VPS | At least 2 GB RAM and 20 GB disk, with a sudo user |
| A domain | An A record pointing at the server IP. This guide uses news.example.com: replace it with your domain everywhere. |
| The download | MediaDesk-Main_Files.zip. You only install WebSourceCode on the server. |
No SSH access, only a hosting control panel? Follow the cPanel Installation guide instead.
1. Install the Server Software
sudo apt update && sudo apt upgrade -y sudo apt install -y nginx mysql-server unzip supervisor redis-server \ php8.3-fpm php8.3-cli php8.3-mysql php8.3-mbstring php8.3-xml php8.3-curl \ php8.3-gd php8.3-intl php8.3-zip php8.3-bcmath php8.3-redis composer # Node.js 20 (Ubuntu's own package is too old) curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install -y nodejs
Check the versions. You need PHP 8.3 or newer, Composer 2 and Node.js 20 or newer:
php -v && composer --version && node -v
2. Create the Database
Open MySQL with sudo mysql, then run this with your own password:
CREATE DATABASE mediadesk CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'mediadesk'@'localhost' IDENTIFIED BY 'a-strong-password'; GRANT ALL PRIVILEGES ON mediadesk.* TO 'mediadesk'@'localhost'; FLUSH PRIVILEGES; EXIT;
Use this dedicated user, not root. The installer counts every table the user can see, so a user with access to other databases is refused with “already contains tables”, even when the new database is empty.
3. Upload the Files
From your computer, copy the download to the server:
scp MediaDesk-Main_Files.zip [email protected]:~/
On the server, unpack it into the web folder:
unzip -q ~/MediaDesk-Main_Files.zip -d ~/mediadesk-package sudo mkdir -p /var/www/mediadesk sudo chown -R $USER:$USER /var/www/mediadesk cp -a ~/mediadesk-package/Main_Files/WebSourceCode/. /var/www/mediadesk/
4. Install Dependencies and Build
vendor/ and public/build/ are not in the download. These commands create them:
cd /var/www/mediadesk composer install --no-dev --optimize-autoloader npm ci npm run build rm -rf node_modules
Use composer install. Never run composer update: it changes the tested package versions.
5. Create .env and Set Ownership
Create .env from the example. Leave its values as they are: the installer fills in the site address, database details and security key in step 8.
cd /var/www/mediadesk
cp .env.example .env
sudo chown -R www-data:www-data /var/www/mediadesk
sudo find /var/www/mediadesk -type d -exec chmod 755 {} \;
sudo find /var/www/mediadesk -type f -exec chmod 644 {} \;
sudo chmod 640 .envDo not skip this. Without a .env file the installer page answers with a 500 error.
6. Configure PHP and nginx
Raise the PHP limits so large media uploads work:
sudo tee /etc/php/8.3/fpm/conf.d/99-mediadesk.ini > /dev/null <<'EOF' upload_max_filesize = 256M post_max_size = 256M memory_limit = 512M max_execution_time = 300 EOF sudo systemctl restart php8.3-fpm
Create the site with sudo nano /etc/nginx/sites-available/mediadesk:
server {
listen 80;
server_name news.example.com;
root /var/www/mediadesk/public;
index index.php;
charset utf-8;
client_max_body_size 256M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_read_timeout 300;
}
location ~ /\.(?!well-known) {
deny all;
}
}Enable it:
sudo ln -s /etc/nginx/sites-available/mediadesk /etc/nginx/sites-enabled/ sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t && sudo systemctl reload nginx
7. Turn On HTTPS
sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d news.example.com
Certbot adds the certificate to the nginx site and renews it automatically. Do this before the installer, so that the site address you enter there starts with https://.
8. Run the Installer
Open https://news.example.com. It redirects to the installer.
| Screen | What to enter |
|---|---|
| 1. Requirements | Every line must be green. If an extension is red, install its php8.3-… package and restart php8.3-fpm. |
| 2. Database | Site name, site URL https://news.example.com, host localhost, port 3306, database mediadesk, username mediadesk and the password from step 2 |
| 3. Administrator | Your name, e-mail and a password of at least 8 characters. This is your Super Admin login. |
| 4. Done | The installer creates the tables and base data, then closes itself for good. Sign in at /login. |
9. Add the Scheduler
Scheduled articles, renewals, reminders, digests and social posts all depend on this one line. Open the cron table of the web user:
sudo crontab -u www-data -e
Add:
* * * * * cd /var/www/mediadesk && php artisan schedule:run >> /dev/null 2>&1
10. Start the Queue Worker
Newsletters, push alerts and social posts are sent by a background worker. First switch the queue to Redis in /var/www/mediadesk/.env:
QUEUE_CONNECTION=redis
Then create the worker with sudo nano /etc/supervisor/conf.d/mediadesk-worker.conf:
[program:mediadesk-worker] command=php /var/www/mediadesk/artisan queue:work redis --sleep=3 --tries=1 --max-time=3600 user=www-data numprocs=2 process_name=%(program_name)s_%(process_num)02d autostart=true autorestart=true stopasgroup=true stopwaitsecs=3600 redirect_stderr=true stdout_logfile=/var/log/mediadesk-worker.log
Start it:
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl status
11. Finish and Verify
cd /var/www/mediadesk sudo -u www-data php artisan optimize sudo -u www-data php artisan queue:restart sudo -u www-data php artisan mediadesk:doctor
The doctor lists any problem with its fix. Warnings about AI keys and push keys are optional features, which you can add later.
After this, any edit to .env needs sudo -u www-data php artisan optimize and queue:restart again, or the old values stay in use.
Next: After Installing for your site identity, time zone, mail and payment settings.
If Something Goes Wrong
| What you see | Fix |
|---|---|
500 error on /install | .env is missing. Repeat step 5. |
| “Already contains tables” on an empty database | The database user can see other databases. Use the dedicated user from step 2. |
| 500 error on every page, or a Vite manifest error | vendor/ or public/build/ is missing. Repeat step 4, then the chown from step 5. |
| “Permission denied” in the log | Run the chown from step 5 again. |
| 502 Bad Gateway | PHP is not running: sudo systemctl restart php8.3-fpm. Check that the socket path in the nginx site matches. |
| Large uploads fail | Check client_max_body_size in nginx and the limits in step 6. |
| Newsletters stay “sending” | The worker is not running: sudo supervisorctl status. |
The log is at /var/www/mediadesk/storage/logs/laravel.log. More answers are in the Troubleshooting FAQ.