Skip to content

Getting started

Backend installation

This guide installs on a plain server. With Docker, follow Docker Deployment instead; the installer step is the same.

Requirements

  • PHP 8.4 with the extensions ctype, iconv, intl, mbstring, pdo_mysql, gd (built with WebP) and zip; exif and apcu are recommended.
  • MySQL 8.
  • Composer 2 and Node 22 (only to build; not needed at runtime).
  • A web server pointing at public/: Caddy or FrankenPHP, nginx with PHP-FPM, or Apache.
  • A process manager (systemd or Supervisor) for the worker.

Steps

git clone <repository> classifieds && cd classifieds
composer install --no-dev --optimize-autoloader
npm ci && npm run build

Set the environment as real variables of the web server and the worker (not in a file under the project):

VariableValue
APP_ENVprod
APP_DEBUG0
APP_SECRETa long random string (openssl rand -hex 32); also signs the app's sign-in tokens
DATABASE_URLmysql://user:password@host:3306/database?serverVersion=8.0.30&charset=utf8mb4
MESSENGER_TRANSPORT_DSNdoctrine://default?auto_setup=0
MAILER_DSNyour email provider, e.g. mailgun+api://KEY:DOMAIN@default?region=eu
SEND_EMAIL1
SEARCH_FULLTEXToptional, 1 by default: the search box uses the database's full-text index on titles (MySQL 8 or MariaDB 10.6+). Set 0 only on a database without full-text search; it then scans titles, which is slower on large sites.
SENTRY_DSNoptional
FB_ID, FB_SECREToptional, Facebook sign-in
EXPO_DSNoptional, push notifications

Then run the installer:

php bin/console app:install

It checks the server, creates the tables, asks for the platform name, public address, country, language, currency, support email and the first admin, adds the terms and privacy pages and imports the country's regions and localities. Add --template=general (or another marketplace template, Platform Configuration) to start with a full catalogue, and --demo for sample content. For scripted installs pass the answers as options:

php bin/console app:install --no-interaction \
  --name="Velo Market" --url=https://velo.example.com --country=RO --locale=ro --currency=RON \
  --support-email=help@velo.example.com --admin-email=owner@velo.example.com --admin-password='...'

The worker

[program:classifieds-worker]
command=php /srv/app/bin/console messenger:consume async scheduler_default --time-limit=3600 --memory-limit=256M
directory=/srv/app
user=www-data
autostart=true
autorestart=true
stopwaitsecs=30

Without it no email or push leaves and the daily jobs never run (see scheduled-jobs.md).

Web server

Point the document root at public/, send every request that is not a file to public/index.php, compress responses, and cache /build/* and /uploads/* for a year (Cache-Control: public, max-age=31536000, immutable); their file names change whenever their content does. docker/production/Caddyfile is a complete example.

First sign-in

Open https://your-domain/admin and sign in with the admin from the installer, then continue with Platform Configuration.

Found a mistake? Tell us.