How to install Salon Booking OS
19 min read
Salon Booking OS by OsDotâ„¢ installs through its browser installer. No command line is needed for the installation itself. You use the command line (or your hosting’s cron settings) afterwards for the scheduled tasks: eight of them, and a ninth in the licensed edition (see Scheduled tasks (cron)).
Video tutorials #
How to install Salon Booking OS by OsDotâ„¢ 1.0.0 on your own hosting
How to back up and update Salon Booking OS by OsDotâ„¢ 1.0.0
Before you start #
Have these ready:
- An empty database and a database user for it, with these privileges on that database: SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP and REFERENCES. This version creates no database triggers, so the TRIGGER privilege is not needed. On shared hosting enter the full names your control panel shows, prefix included (for example
account_salon); the names may contain hyphens. The installer never writes into a database that already holds data. - A site address on HTTPS, at the root of a host name (for example
https://booking.example.com/). Plainhttp://is accepted only for a local development host. Installing into a sub-folder (https://example.com/booking/) is not supported. - The exact address you will use. The site answers at the host name you enter in step 4. Its
www.counterpart (or the bare domain, when you enteredwww.) is sent on to that address with a permanent redirect; any other name — a temporary address from your host, for example — shows a short page that names the site’s address. Decide on one address before you install. To move the site to another address later, see Moving to another address below. - Access to your hosting’s files — a file manager, FTP/SFTP or SSH. The first step asks you to open a file on the server.
- In the licensed edition, your license key, from your purchase e-mail (see Software license).
What the installer checks #
The installer’s Server requirements step is the one place that checks your server. Each line shows a result and, when something is wrong, what to change. A failed check stops the installation until it is fixed; a warning lets you continue.
| Check | What it needs |
|---|---|
| PHP version | PHP 8.3 or later. This is a hard minimum: below it the application does not start at all. |
| PHP extensions | intl, mbstring, pdo_mysql, openssl, sodium, curl, json, ctype, fileinfo, gd and simplexml. With WebP support in gd, the website’s pictures are published as WebP, and as AVIF as well where the host’s gd can write AVIF; without WebP they are published as JPEG or PNG. |
| Writable folders | tmp/, logs/, storage/ and config/ must be writable by the web server. |
| Memory | memory_limit of at least 128 MB; 256 MB is recommended. |
| Upload sizes | “Largest upload” (upload_max_filesize) and the form size (post_max_size) are shown for your information. This version sets no minimum for them, so they give no warning. |
| URL rewriting | Requests must reach the application’s front controller (Apache: mod_rewrite and the shipped webroot/.htaccess). |
| HTTPS | The installer page must be served over HTTPS, or through a proxy the site trusts that reports HTTPS (see Behind a proxy or a TLS terminator): a forwarded https from a proxy the site does not trust is a warning that shows the line to add. A local development host is the exception. |
| Web folder | When the web server’s document root is not the webroot folder, the installer checks that a private test file under storage/ cannot be fetched from the site’s address: the line fails when private files are reachable, and warns when the site cannot reach itself to check. The test file is removed at once. |
| Design files | The stylesheets, scripts and fonts of the built-in modules are in the public web folder (webroot/os_dot/). If some are missing, pages load more slowly but still work: upload the release package’s webroot/ folders again. |
| License server (licensed edition) | The server must reach the publisher’s license server over HTTPS, with its certificate verified. A name that cannot be resolved, a timeout or a certificate that cannot be verified fails the line, with the reason and what to check. |
The Database step then tests the connection and checks the database server:
| Check | What it needs |
|---|---|
| Database connection | The host, port, database name, user and password you enter. |
| utf8mb4 support | Full UTF-8 (4-byte) text. |
| sql_mode | The server’s SQL mode is reported; a value the application cannot work with is refused. |
| Schema privileges | The privileges listed under Before you start (TRIGGER is not needed). |
| Binary logging | Reported only: this version creates no triggers, so binary logging on the server is fine. |
| Existing data | The database must not already hold tables. Existing data is never overwritten. |
| Database series | The step names your database server and version and compares them with the supported list it shows. A series past its end of life, or one not yet certified for this version, gives a clear warning: you may continue at your own risk by ticking the confirmation. A version below the minimum the application needs is refused. |
After the installation, the same database warning stays visible to the owner in the administration area and in the output of php bin/cake.php upgrade check, until the database runs a supported series. It never blocks the site.
Where the web root goes #
The web server must only ever serve the application’s webroot folder. Everything else — configuration, stored keys, logs, the application code and its components — must never be reachable over the web. There are two ways to get there; use the first one your hosting allows.
Route 1: point the address at webroot (hosts that let you choose the folder) #
- Upload the contents of the package’s
Web/folder next to your web folders, for example into/home/youraccount/salon/, so thatconfig/,storage/and the other folders sit outside any web folder. - In your hosting panel, add the domain, subdomain or add-on domain for the salon (for example
booking.example.com) and set its document root to the application’swebrootfolder (/home/youraccount/salon/webroot). cPanel and Plesk let you choose the folder when you add a subdomain or a domain. - Open that address in your browser: the installer starts.
Route 2: upload into the host’s public_html (hosts with a fixed web folder) #
Many shared hosts give each website a fixed public_html folder and no way to change its document root. On Apache or LiteSpeed hosting the application works there too: its top folder carries a small .htaccess file that sends every request on to webroot/, so the other folders are never served.
- In your hosting panel, create the website for the salon’s address (for example
booking.example.com). Wait until its SSL certificate is active. - Open the website’s
public_htmlfolder in the panel’s file manager and delete the host’s placeholder page (oftendefault.phporindex.html), so the folder is empty. - Upload the contents of the package’s
Web/folder intopublic_html, so thatpublic_htmlitself holdsbin/,config/,src/,webroot/and the file.htaccess(not aWeb/folder inside it). The quickest way: on your computer, open theWeb/folder, select everything in it and make a ZIP of the selection (on a Mac, press Cmd+Shift+. first: Finder hides.htaccessuntil hidden files are shown); upload that ZIP intopublic_htmland extract it there with the file manager, then delete the ZIP. Extracting on the server keeps.htaccess; if you upload the files one by one instead, make sure your FTP program or file manager shows and uploads hidden files (names starting with a dot) — without.htaccessthe site cannot run safely. - Open your address in the browser. The installer starts; its Server requirements step checks that a private test file under
storage/cannot be fetched from your address. If that line fails, your host ignores.htaccess: do not continue — ask your host to allow.htaccessfiles with URL rewriting (mod_rewrite,AllowOverride All), or use Route 1. - After the installation, check it once yourself: open
https://booking.example.com/composer.jsonandhttps://booking.example.com/config/app_local.php. Each must show the site’s own page (its start page or “Page not found”), never the file’s text.
Route 2 needs Apache or LiteSpeed with .htaccess files allowed. On Nginx only Route 1 is safe.
If your host allows neither route, this version cannot be installed safely there. Installing into a sub-folder of another site (for example example.com/booking/) is not supported either: an upload into a folder of an address, or (on Apache and LiteSpeed) one without webroot/.htaccess, shows a short page that says what to do instead of the installer.
The administration area’s icons and font are included ready-made in webroot/vendor/, the stylesheets, scripts and fonts of the built-in modules in webroot/os_dot/, and each website theme’s default hero picture as AVIF and WebP files in webroot/img/theme-defaults/. You do not run npm, an image tool or any other build step on the server, and nothing has to be copied or linked into the web root.
Website images: Apache and Nginx #
Pictures uploaded through the media library are kept privately under storage/; their public versions go to the web root’s media/ folder. The installer prepares that folder with its own rules: scripts are refused and only the picture files are served.
- Apache: the web root must allow these rules —
AllowOverridewith at leastOptions AuthConfig FileInfo(AllowOverride Allcovers it). - Nginx: add this block inside the site’s
serverblock, before any PHP location:
location ^~ /media/ {
autoindex off;
add_header X-Content-Type-Options "nosniff" always;
add_header Content-Security-Policy "default-src 'none'; sandbox" always;
location ~ "^/media/[a-f0-9]{32}\.(avif|webp|jpg|png)$" {
types { image/avif avif; image/webp webp; image/jpeg jpg; image/png png; }
add_header X-Content-Type-Options "nosniff" always;
add_header Content-Security-Policy "default-src 'none'; sandbox" always;
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
return 403;
}After the installation, check the folder from the site’s folder: php bin/cake.php media check-public --url=https://booking.example.com. PASS means that scripts are refused and pictures are served. PHP’s upload folder (upload_tmp_dir) may lie outside open_basedir; only the site’s storage/ folder must be inside it.
Behind a proxy or a TLS terminator #
If the site sits behind a reverse proxy, a load balancer or a CDN that ends HTTPS — the visitor’s browser speaks HTTPS to the proxy, and the proxy plain HTTP to your server — tell the site which proxy to trust. Without it the site sees every request as coming from the proxy’s address over plain HTTP: the API refuses calls with https_required, and sign-in limits count every visitor as one.
Add the proxy’s address, or its network range, to config/app_local.php, inside the 'OsDot' => [ … ] block:
'trustedProxies' => ['203.0.113.10'],List exact addresses or ranges such as 10.0.0.0/8 (IPv4 or IPv6); a wildcard or “everything” is refused. Only a request that comes from a listed proxy has its X-Forwarded-For (the visitor’s address) and X-Forwarded-Proto (whether the visitor used HTTPS) read; a request from anywhere else changes nothing. The list is empty as shipped: a site without a proxy needs nothing here. The Server requirements step warns when it sees a forwarded https from a proxy the site does not trust, and shows the line to add.
Where PHP’s OPcache does not check file times (opcache.validate_timestamps=0, a common production setting), an edit of config/app_local.php — OsDot.trustedProxies above all — takes effect only once PHP restarts. Restart PHP from your hosting panel (or ask your host) after the change.
The seven steps #
- Welcome — prove that you control this hosting account. On the first visit the installer writes a one-time setup token into
storage/install/setup-token.txt. It is never shown on the page. Open that file with your file manager, FTP/SFTP client or SSH session, copy its content and paste it into the form. If you prefer, delete the file and create it yourself with a value of your own (16–256 printable characters on one line) before you paste that value. Repeated wrong tokens from one address are paused for a few minutes. - Server requirements. Fix every failed check, then reload the page (see What the installer checks).
- Database. Enter the connection details and test them. If the database series gives a warning, read it and tick the confirmation to continue at your own risk.
- Site setup. Enter the site name, the canonical site address (
https://…), the time zone and the currency. Choose them now, carefully:- The site name shows in page titles, the administration header, the website’s header and the e-mails. It is required. You can change it later under System → Website settings.
- The site address is the exact address of Before you start.
- The time zone is required and starts unselected (“Choose your time zone”): the zones are grouped by region with their names, and your browser’s zone is suggested for you to confirm. Choose the salon’s own zone (for example “Eastern Time (New York)” or “United Kingdom Time (London)”). After the installation the zone belongs to the salon’s Location page (Salon → Location), as the page says. Set it before you take bookings: appointments are kept as moments in time, so changing the zone afterwards shows every existing appointment at a different local time (for example five hours off), and you would have to move them by hand.
- The currency accepts any ISO 4217 code and suggests common ones; USD is preselected. Set it before you add services: a service keeps the currency it was created in (see Services catalogue).
The page says that this version installs without demo data: there is no installation mode to choose.
- Owner account. Enter the owner’s name, the e-mail address the owner signs in with, and a password (twice). Only a hash of the password is kept. This is the only account the installer creates; your team’s sign-ins are added afterwards (see Your team’s sign-ins).
- Install. The installer runs its phases one after another and lists each result. Before it writes anything to the database, it confirms that the uploaded files are a complete package of this product (Package check). It stops where it needs you:
- Software license activation (licensed edition), before any database table is created. Enter the Software license key from your purchase: only the key, never an order number or an account password. The installer confirms it with the license server; a key that is refused stops the phase with the reason, so you can try again with the right key, and nothing has been written to the database yet. See Software license.
- About your salon, two optional questions:
- Language and formats — English at launch: choose one of the English formats listed (United States is preselected; the others include the United Kingdom, Australia, Canada, Ireland, India, New Zealand, Singapore, South Africa and the United Arab Emirates). Each choice says whether times on the administration pages are 12-hour (
9:30 PM) or 24-hour (21:30). You can change it later under System → Website settings. - Salon’s country — two letters, for example
US,GBorIN(UKworks too and is stored asGB). It is the country phone numbers are read in: staff can type a number of that country without the country code, and the booking pages preselect it for a client’s phone number. Leave it empty if you prefer: no country is ever assumed, and international numbers always work.
- Language and formats — English at launch: choose one of the English formats listed (United States is preselected; the others include the United Kingdom, Australia, Canada, Ireland, India, New Zealand, Singapore, South Africa and the United Arab Emirates). Each choice says whether times on the administration pages are 12-hour (
The country is stored on the salon’s Location, together with the time zone you chose in step 4. Both can be changed later on Salon → Location. A wrong value stops the phase with its reason. What you typed is shown again, with the format you chose still selected: correct it and run the phase again.
- Choose Website Theme: the three website themes — Linen (light by default), Onyx (dark by default) and Bloom (light by default). Linen is preselected; continuing without a choice keeps it. You can change the theme, its colours and fonts later under Appearance.
The other phases need nothing from you. They create the folder for the website’s published pictures (Public images folder), put the site’s main pages into the header menu and the footer (Website menus), add Team sign-in to the website’s footer (Website footer) and prepare the home page (Website home page): a first slide with the salon’s name and a Contact us button (the theme’s own picture shows until you choose one), and the page’s sections in order — the slides, Popular right now, Services & prices, the shop’s Salon care at home, Recent work, Our team, Visit us, questions and the latest posts — and add three unpublished legal page drafts (Legal page drafts): Terms & Conditions, Cancellation Policy and Privacy Policy, each to review with your own lawyer and publish yourself (see Website and team). Each section shows only once it has something to show. Change the slide and add an About us button under Website → Homepage once your About page is published. Recent work stays hidden until you add the salon’s own pictures under Appearance → Images: the themes ship no sample pictures for it, so nothing on your website suggests work the salon did not do.
- Success. The last page confirms the installation, links to the sign-in page and lists what to do before you go live: the scheduled tasks, the backup set, a note to set up the site’s e-mail under System → E-mail (SMTP) before you invite your team (confirmations, reminders, sign-in codes and staff invitations go out by e-mail; text messages are optional), and where enquiries from the website’s contact page wait. In the licensed edition it also reminds you to schedule the daily license confirmation. It is shown only once: print it, or find the same list later under System → Before you go live (the owner). From now on every
/installaddress answers “Already installed”, and there is no reset or reinstall route.
If an installation stops part way, Start over on the installer’s pages removes its progress and the configuration file it wrote, after a confirmation. It never touches the database: it names the database and its tables, which you empty yourself before you install again.
Right after the installation #
- Add the scheduled tasks. Each command names
bin/cake.phpby its full path (nocd, no quotes), so it works in every hosting panel’s cron, also where the command runs without a shell. Where your hosting’s plainphpis older than PHP 8.3, write the full path of your site’s PHP version in its place (on Hostinger,/opt/alt/php83/usr/bin/phpfor PHP 8.3). The success page shows each task’s schedule and command, with your installation’s own folder filled in, each in its own field with a Copy button — among themcommunication work, which sends the e-mails and text messages every minute,commerce reconcile, which checks online payments again, and, in the licensed edition,license renew, which confirms the license every night. They are shown again any time under Overview → Get started and System → Before you go live. Check the command-line PHP first. Details, and what each task does: Scheduled tasks (cron). - Back up the configuration and the pictures with the database. The backup set is the database together with
config/app_local.php,config/installed.php, thestorage/folder and thewebroot/media/folder:config/app_local.phpholds this installation’s secrets, including the application salt, and cannot be regenerated;storage/holdsstorage/keys/integration.keyand the originals of uploaded pictures;webroot/media/holds the website’s published pictures, which no database restore brings back.
Changing the application salt invalidates every pending one-time code and booking grant: see The application salt.
- Sign in as the owner at
/loginand open Get started (see First admin and configuration). Check the salon name and the currency under System → Website settings, and the time zone, the country, the address and the phone on Salon → Location. - Set up the site’s e-mail under System → E-mail (SMTP) before you add your team, take bookings online or open the shop (see Messages, reminders, text messages and push).
- In the licensed edition, open System → Software license and check that its status reads Active.
Installing an update #
An update’s database changes run only after you confirm that a backup exists. Nothing is applied by itself.
- Back up the database together with
config/app_local.php,config/installed.php, thestorage/folder and thewebroot/media/folder, as after the installation. - Replace the program folders with the new version’s. Keep exactly these four:
config/app_local.php,config/installed.php, thestorage/folder and thewebroot/media/folder. Delete everything else in the site’s folder, then upload the new version’s files. Do not upload the new files over the old ones: files that a new version removed would stay behind, and an old database change left in a folder could run again. - Check from the site’s folder:
php bin/cake.php upgrade check. It names the installed version and the version of the files, lists the waiting database changes, and says whether a backup confirmation is already on record. - Apply the update, in one of two ways:
- In the administration area: System → Updates (the owner only) lists the waiting changes. Tick “I have a backup of the database and the files listed above, taken after the last change”, add a note if you like (for example where the backup is), and choose Run the updates. Without the tick nothing is run.
- On the command line:
php bin/migrate.php --backup-confirmed(or--backup-confirmed="backup of 6 October in the hosting panel"). Without--backup-confirmedit prints the backup reminder and runs nothing.
The site switches to maintenance by itself while the changes run, and back when they all succeed. Each confirmation is recorded, with the note, in the installation log and the audit log, and is used for that one run only.
- If a run does not complete, the site stays in maintenance and the page or the command says which part failed. Restore the backup you confirmed — the database and the four kept items — then delete
storage/maintenance.flagif it is still there, and contact support with the message shown.
On the command line, bin/migrate.php ends with exit code 0 (done, or nothing was waiting), 1 (refused before anything ran — for example another run is going, or a record cannot be written; the message names the file), 2 (the run did not complete; the database may have changed) or 3 (no backup confirmed).
Moving to another address #
The site answers at the address in config/app_local.php (the line 'App' => ['fullBaseUrl' => …]). To move it to another domain or subdomain:
- Back up the full set (see Installing an update, step 1).
- In your hosting panel, point the new address at the same
webrootfolder (see Where the web root goes). - From the site’s folder run
php bin/cake.php installer site-address --url=https://booking.newname.com. It writes the new address intoconfig/app_local.phpand keeps the old one as an alias, so old links and bookmarks are sent on to the new address. Without a terminal, change the address in thefullBaseUrlline yourself, in the same form, and change nothing else in the file; then redirect the old address in your hosting panel (a permanent 301 redirect). Where OPcache does not check file times, restart PHP after either change (see Behind a proxy or a TLS terminator). - If you also moved the site’s folder, update the scheduled tasks: their lines contain the folder (Overview → Get started shows the new lines).
- Check the website’s picture folder at the new address:
php bin/cake.php media check-public --url=https://booking.newname.com. - If clients continue with Google, add the new address’s return address to your Google web client: System → Google sign-in shows it.