Skip to main content
This guide covers deploying MediPro to a Linux production server running Apache or Nginx.

Server requirements

RequirementMinimum version / notes
PHP8.2+ with pdo, mbstring, tokenizer, xml, ctype, json, bcmath, fileinfo extensions
Composer2.x
Node.js18+ (required for npm run build and Puppeteer)
npm9+
Web serverApache 2.4+ or Nginx 1.18+
DatabaseSQLite, MySQL 8+, or PostgreSQL 14+
Set APP_DEBUG=false in production. Leaving debug mode enabled exposes stack traces, environment variables, and internal application details to anyone who triggers an error.

Deployment steps

1

Clone the repository

Clone the project to your server’s web root or a dedicated application directory:
git clone <repository-url> /var/www/medipro
2

Install PHP dependencies

Install production PHP dependencies only — development tools (Pint, Pail, Sail, PHPUnit) are excluded:
composer install --no-dev --optimize-autoloader
3

Configure environment variables

Copy the example file and edit it for production:
cp .env.example .env
At minimum, update the following values:
APP_NAME="MediPro"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://your-domain.example.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=medipro
DB_USERNAME=medipro_user
DB_PASSWORD=strong-password-here
4

Generate the application key

php artisan key:generate
This writes a unique APP_KEY into your .env file. Sessions and encrypted values depend on this key — keep it secret and do not rotate it without planning a migration of existing sessions.
5

Run database migrations

Apply all migrations to the production database. The --force flag is required when APP_ENV=production:
php artisan migrate --force
6

Build front-end assets

Install Node dependencies and compile all CSS and JavaScript for production:
npm install && npm run build
Vite outputs compiled assets to the public/build/ directory. The resources/ source files are not served directly.
7

Set file permissions

The web server process must be able to write to storage/ and bootstrap/cache/:
chown -R www-data:www-data storage bootstrap/cache
chmod -R 775 storage bootstrap/cache
Replace www-data with the user your web server runs as (e.g., nginx, apache, or caddy).
8

Configure the web server

Point the web server document root to the public/ directory. See the Nginx and Apache sections below for sample configurations.
9

Copy datos.xlsx to public/

MediPro requires a datos.xlsx spreadsheet in the public/ directory for aluminium profile name lookup. This file is not committed to the repository and must be placed manually:
cp /path/to/datos.xlsx /var/www/medipro/public/datos.xlsx
datos.xlsx is not included in the repository (it is gitignored or otherwise not committed). You must obtain this file separately and place it in public/ before the configurator can look up profile names. The application will fail to resolve profile data without it.

Web server configuration

Nginx configuration

A minimal Nginx server block for MediPro:
server {
    listen 80;
    listen [::]:80;
    server_name your-domain.example.com;

    root /var/www/medipro/public;
    index index.php;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_hide_header X-Powered-By;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
For HTTPS, obtain a certificate (e.g., via Let’s Encrypt / Certbot) and add a second server block redirecting port 80 to 443.

Apache configuration

Enable mod_rewrite and create a virtual host pointing to public/:
<VirtualHost *:80>
    ServerName your-domain.example.com
    DocumentRoot /var/www/medipro/public

    <Directory /var/www/medipro/public>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/medipro-error.log
    CustomLog ${APACHE_LOG_DIR}/medipro-access.log combined
</VirtualHost>
Laravel ships with a public/.htaccess file that handles URL rewriting for Apache.

Production optimisations

After deploying, run the Artisan cache commands to pre-compile configuration, routes, and views:
php artisan config:cache
php artisan route:cache
php artisan view:cache
Once config:cache has been run, changes to .env have no effect until you run php artisan config:clear or config:cache again. Always re-run config:cache after updating environment variables.
If your application writes user-uploaded files to storage/app/public/ and serves them through the public disk, create the symbolic link:
php artisan storage:link
This creates public/storagestorage/app/public.

Queue worker

MediPro uses the database queue driver (QUEUE_CONNECTION=database). Run a queue worker as a long-lived background process to process jobs:
php artisan queue:work
In production, manage the worker with a process supervisor such as Supervisor or systemd so that it restarts automatically on failure. A minimal Supervisor configuration:
[program:medipro-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/medipro/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/log/medipro-worker.log
stopwaitsecs=3630
Restart workers after every deployment so they pick up code changes:
php artisan queue:restart

PDF generation (Browsershot)

MediPro uses spatie/browsershot for PDF generation. Browsershot requires Node.js and Puppeteer to be installed on the server:
npm install --global puppeteer
or install it locally within the project:
npm install puppeteer
Puppeteer downloads a bundled Chromium binary on first install. On headless Linux servers you may also need to install Chromium’s system dependencies:
# Debian / Ubuntu
apt-get install -y \
  libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 \
  libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 \
  libxfixes3 libxrandr2 libgbm1 libasound2

Deployment checklist

  • APP_ENV=production
  • APP_DEBUG=false
  • APP_KEY is set and non-empty
  • APP_URL matches the public domain
  • Database credentials are correct
  • storage/ is writable by the web server user
  • bootstrap/cache/ is writable by the web server user
  • public/datos.xlsx is present
  • npm run build has been run and public/build/ exists
  • php artisan migrate --force
  • php artisan config:cache
  • php artisan route:cache
  • php artisan view:cache
  • php artisan storage:link (if using public disk)
  • Queue worker is running and supervised
  • php artisan queue:restart was run after the latest deployment

Build docs developers (and LLMs) love