Get PNLCS running
PNLCS is a Laravel application. It runs anywhere PHP 8.4, MySQL or MariaDB and a web server are available. To look around first, the live demo is a real installation.
docker pull panelica/pnlcs-runtime
Three ways to install
| Way | Best for | Time | Guide |
|---|---|---|---|
| Docker | Trying PNLCS, or running it as one container | About 5 minutes | Commands |
| Your own server | A VPS or dedicated server without Docker: Ubuntu, Debian, AlmaLinux or Rocky Linux | About 30 minutes | Commands |
| Inside a hosting panel | A server that already runs Panelica, cPanel or similar | About 20 minutes | Guide |
Quick start with Docker
The official image bundles PHP-FPM 8.4, nginx, Node.js 20 and supervisor, and fetches the latest code on first start.
- Start the containersReplace
changemewith your own passwords first. - Wait 3 to 5 minutesThe first start installs dependencies and builds the frontend.
- Open /installThe wizard checks requirements, creates your admin account, then locks itself.
$ docker network create pnlcs-net $ docker run -d --name pnlcs-db --network pnlcs-net \ -e MYSQL_ROOT_PASSWORD=changeme \ -e MYSQL_DATABASE=pnlcs -e MYSQL_USER=pnlcs \ -e MYSQL_PASSWORD=changeme \ mariadb:11 $ docker run -d --name pnlcs --network pnlcs-net \ -p 8090:80 \ -e DB_HOST=pnlcs-db -e DB_DATABASE=pnlcs \ -e DB_USERNAME=pnlcs -e DB_PASSWORD=changeme \ -e APP_URL=http://localhost:8090 \ panelica/pnlcs-runtime:1.4
Install on your own server, without Docker
PNLCS runs as a normal Laravel application on PHP-FPM 8.4, MySQL or MariaDB and Nginx. The commands below cover Ubuntu 24.04, Debian 13 and AlmaLinux 9; Rocky Linux 9 uses the AlmaLinux commands. Replace example.com with your own address.
-
Prepare the server
PHP 8.4 with its extensions, a database, Nginx, Node.js 20 to build the frontend, and Composer. Skip this if they are already installed.
Ubuntu 24.04 ships PHP 8.3, so PHP 8.4 comes from the ondrej PPA. Debian 13 has PHP 8.4 itself, ships MariaDB instead of MySQL and has no
php8.4-imappackage. On AlmaLinux and Rocky, PHP 8.4 comes from the Remi repository.Terminal$ sudo apt update $ sudo apt install -y software-properties-common git unzip curl cron $ sudo add-apt-repository -y ppa:ondrej/php $ sudo apt update $ sudo apt install -y php8.4-fpm php8.4-cli php8.4-mysql php8.4-mbstring \ php8.4-xml php8.4-curl php8.4-zip php8.4-gd php8.4-bcmath php8.4-intl php8.4-imap $ sudo apt install -y mysql-server nginx $ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - $ sudo apt install -y nodejs $ curl -sS https://getcomposer.org/installer | php $ sudo mv composer.phar /usr/local/bin/composer
Terminal$ sudo apt update $ sudo apt install -y git unzip curl cron $ sudo apt install -y php8.4-fpm php8.4-cli php8.4-mysql php8.4-mbstring \ php8.4-xml php8.4-curl php8.4-zip php8.4-gd php8.4-bcmath php8.4-intl $ sudo apt install -y mariadb-server nginx $ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - $ sudo apt install -y nodejs $ curl -sS https://getcomposer.org/installer | php $ sudo mv composer.phar /usr/local/bin/composer
Terminal$ sudo dnf install -y epel-release https://rpms.remirepo.net/enterprise/remi-release-9.rpm $ sudo dnf module reset php -y $ sudo dnf module enable php:remi-8.4 -y $ sudo dnf install -y php php-fpm php-mysqlnd php-mbstring php-xml php-gd \ php-bcmath php-intl php-imap php-pecl-zip \ mysql-server nginx git unzip cronie policycoreutils-python-utils $ curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash - $ sudo dnf install -y nodejs $ curl -sS https://getcomposer.org/installer | php $ sudo mv composer.phar /usr/local/bin/composer $ sudo systemctl enable --now php-fpm mysqld nginx
-
Install the application
The PNLCS directory belongs to the web server user, and every
composer,artisanandnpmcommand runs as that user. Thepnhelper does this for you. If root owns the directory, the install wizard and later updates fail.Choose one database password and use it in both the
CREATE USERand the.envline. Thepnhelper lasts only for the current shell session; define it again after you log back in.Do not run
db:seed. The install wizard seeds the database and creates the administrator you choose.Terminal$ sudo git clone https://github.com/Panelica/pnlcs.git /var/www/pnlcs $ sudo chown -R www-data:www-data /var/www/pnlcs $ cd /var/www/pnlcs $ pn() { sudo -u www-data HOME=/tmp/pnlcs-home COMPOSER_HOME=/tmp/pnlcs-home/composer "$@"; } $ pn composer install --no-dev --optimize-autoloader --no-interaction $ sudo mysql -e "CREATE DATABASE pnlcs CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'pnlcs'@'localhost' IDENTIFIED BY 'choose-a-strong-password'; GRANT ALL PRIVILEGES ON pnlcs.* TO 'pnlcs'@'localhost'; FLUSH PRIVILEGES;" $ pn cp .env.example .env $ pn sed -i 's|^APP_URL=.*|APP_URL=http://example.com|; s|^DB_PASSWORD=.*|DB_PASSWORD=choose-a-strong-password|' .env $ sudo chmod 640 .env $ pn php artisan key:generate $ pn php artisan migrate --force $ pn npm ci $ pn npm run build $ pn php artisan storage:link $ pn php artisan optimize
Terminal$ sudo git clone https://github.com/Panelica/pnlcs.git /var/www/pnlcs $ sudo chown -R apache:apache /var/www/pnlcs $ cd /var/www/pnlcs $ pn() { sudo -u apache HOME=/tmp/pnlcs-home COMPOSER_HOME=/tmp/pnlcs-home/composer "$@"; } $ pn /usr/local/bin/composer install --no-dev --optimize-autoloader --no-interaction $ sudo mysql -e "CREATE DATABASE pnlcs CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'pnlcs'@'localhost' IDENTIFIED BY 'choose-a-strong-password'; GRANT ALL PRIVILEGES ON pnlcs.* TO 'pnlcs'@'localhost'; FLUSH PRIVILEGES;" $ pn cp .env.example .env $ pn sed -i 's|^APP_URL=.*|APP_URL=http://example.com|; s|^DB_PASSWORD=.*|DB_PASSWORD=choose-a-strong-password|' .env $ sudo chmod 640 .env $ pn php artisan key:generate $ pn php artisan migrate --force $ pn npm ci $ pn npm run build $ pn php artisan storage:link $ pn php artisan optimize $ sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/pnlcs/storage(/.*)?" $ sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/pnlcs/bootstrap/cache(/.*)?" $ sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/pnlcs/\.env" $ sudo restorecon -R /var/www/pnlcs $ sudo setsebool -P httpd_can_network_connect_db 1 $ sudo setsebool -P httpd_can_network_connect 1
-
Point Nginx at public/
The document root is the
public/directory, never the project root: the project root holds.env. Remove the default site so the server’s address does not keep showing the Nginx welcome page.Apache and Caddy work too, with the same rules: document root
public/, PHP through PHP-FPM 8.4, and every request that is not a file rewritten toindex.php.Terminal$ sudo tee /etc/nginx/sites-available/pnlcs > /dev/null <<'EOF' server { listen 80; server_name example.com; root /var/www/pnlcs/public; index index.php; charset utf-8; client_max_body_size 64M; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass unix:/run/php/php8.4-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } } EOF $ sudo ln -s /etc/nginx/sites-available/pnlcs /etc/nginx/sites-enabled/ $ sudo rm -f /etc/nginx/sites-enabled/default $ sudo nginx -t && sudo systemctl reload nginx
Terminal$ sudo tee /etc/nginx/conf.d/pnlcs.conf > /dev/null <<'EOF' server { listen 80; server_name example.com; root /var/www/pnlcs/public; index index.php; charset utf-8; client_max_body_size 64M; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass unix:/run/php-fpm/www.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } } EOF $ sudo nginx -t && sudo systemctl reload nginx
-
Finish in the browser, then schedule and secure
Open
http://example.com/install. The wizard checks the requirements, creates your administrator and then closes itself.One cron line for the web server user drives invoices, reminders, suspensions, SSL checks and backups. Queued jobs need no separate worker; the same cron line processes them.
Terminal$ cd /var/www/pnlcs $ WEB_USER=www-data # AlmaLinux, Rocky: apache $ (sudo crontab -u $WEB_USER -l 2>/dev/null; echo '* * * * * cd /var/www/pnlcs && php artisan schedule:run >> /dev/null 2>&1') | sudo crontab -u $WEB_USER - $ sudo apt install -y certbot python3-certbot-nginx # Ubuntu, Debian $ sudo certbot --nginx -d example.com $ pn sed -i 's|^APP_URL=http://|APP_URL=https://|' .env $ pn php artisan optimize
Requirements
A small installation is comfortable on 2 GB of memory with the database on the same machine.
| PHP | 8.4 or newer |
|---|---|
| Database | MySQL 8.0 or MariaDB 10.6+ |
| Web server | Nginx or Apache with PHP-FPM |
| Node.js | 18+ (20 LTS recommended), only to build the frontend |
| Composer | 2.x |
| Memory | 1 GB works for a small install; 2 GB is comfortable |
| Disk | About 130 MB for the app; allow at least 2 GB free as data grows |
After installing
- Setup checklistCompany details, email, a gateway, a server and your first product.
- Your first saleFrom an empty catalog to a paid, provisioned order.
- Security checklistHTTPS, debug off, two-factor for staff, backups that leave the server.
- UpdatingPull the latest release without losing data.
- BackupsWhat to back up, including the application key.
- FAQCommon questions.