Applications AWS

InstantCMS 2.18.2 on AWS User Guide

| Product: InstantCMS 2.18.2 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the InstantCMS 2.18.2 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg BookStack, CMS, Blogs and Wikis listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

InstantCMS is a free and open source content management system written in PHP, built for community sites: user profiles and friends, groups, content types you define (pages, articles, news, blogs and more), photo albums, comments, ratings, an activity feed, private messages and a full control panel at /admin.

The cloudimg image adds:

  • No reachable installer, no shared database. InstantCMS's browser installer creates the site and the first administrator for whoever opens it first. This image ships no database at all (the MariaDB data directory is empty), no configuration file and no installer in the web root. Your instance's first boot initialises its own database and runs InstantCMS's own installer before the web server starts: over a temporary server on a random local port that answers only requests carrying a token generated for that boot. First boot then stops that server, removes the installer and deletes the "remember me" token the installer creates for the administrator.
  • Secrets of your instance's own, never on a command line. The database password, the administrator password and the TLS key are generated on your instance; nothing from the image build is reused. The installer's forms, which carry the passwords, are handed over in files only root can read, never as command line arguments, and its replies are never logged.
  • A patched editor. InstantCMS 2.18.2 bundles TinyMCE 7.6.0, which has three published cross-site scripting flaws (CVE-2026-47759, CVE-2026-47761, CVE-2026-47762). On this image every TinyMCE file InstantCMS uses is the official TinyMCE 7.9.3 build (checked against the npm registry's checksum; InstantCMS's own editor plugins and skin are kept). TinyMCE's media plugin is not shipped: a newer flaw in it (GHSA-mf2p-h6hf-fcwm) affects 7.9.3, and its fix is only in a commercial TinyMCE release. The media button is removed from both editor presets; you can still insert images, links, tables, code samples and spoilers.
  • No proprietary components. InstantCMS ships an old copy of the Imperavi Redactor editor, which is commercial software. It is removed; private messages use InstantCMS's TinyMCE "Comments & Wall" editor instead.
  • Closed by default. Public registration is off (Step 7 shows how to open it), and InstantCMS makes no calls home: the update check is off, and the dashboard news and sponsorship feeds, the add-ons catalogue and the online updater, which contact instantcms.ru, are not available (Step 7).
  • HTTPS from the first boot. nginx serves InstantCMS on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS.
  • Fail closed. nginx does not start until first boot has finished; if first boot cannot complete, the site stays offline rather than open.
  • Only InstantCMS's front controller runs PHP. Every page goes through index.php; every other PHP file is never run, and the system, install and update folders are never served. The folder PHP can write uploads to, upload, is static only: every file gets nosniff and a sandboxing content security policy, and only passive types (images, PDF, fonts, audio and video) open in the browser; anything else, SVG and HTML included, is sent as a download. From cache only the merged stylesheets and scripts and the sitemaps are served.
  • A rate-limited sign in. InstantCMS has no lockout of its own, so nginx allows 10 sign-in, password-recovery and registration attempts a minute from one address (after a burst of 10), using the address of the connection, never a header a client sends.
  • Links from other sites cannot act for you. Control panel pages under /admin/ and the links that change something on the site (joining or leaving a group, accepting requests, setting an album cover and the like) only work when they come from your site itself (Step 9).
  • The real host and client address. nginx hands InstantCMS the host name you configure and nothing a request claims, and the configuration pins the site and upload addresses to it, so every link, password recovery e-mails included, uses your host name. nginx removes X-Forwarded-For, Client-IP and the other forwarding headers, and InstantCMS records the address of the connection.
  • Hardened defaults. The InstantCMS code belongs to root and is read only to PHP, the configuration file is read only to PHP (and the cloudimg tools read it as data, never as code), and only upload and cache are writable. PHP cannot run shell commands and is confined to the site folder. MariaDB has no network listener at all (InstantCMS talks to it over a local socket) and its root account signs in only through the socket as the operating system's root. nginx, PHP, MariaDB, the scheduler and the first boot service are blocked from the instance metadata service, the AMI requires IMDSv2, and requests for a host name the instance does not serve are dropped.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: InstantCMS 2.18.2 (the upstream release, checksum verified) with TinyMCE 7.9.3, MariaDB 10.11, PHP 8.3 FPM, nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.

Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
  • A security group that allows TCP 22 (SSH), TCP 443 (InstantCMS) and TCP 80 (redirects to HTTPS) from the networks that should reach them. Keep 22 to your own networks. Open 443 to your visitors for a public site, or only to your team while you build it.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick InstantCMS 2.18.2 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair and a security group as above.

With the AWS CLI (replace the values in angle brackets):

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=instantcms}]'

Step 2: Connect to your instance

Version SSH user
InstantCMS 2.18.2 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: Check the services

First boot takes under a minute (it creates the database and runs InstantCMS's installer). Then nginx, PHP, MariaDB, the first boot unit and InstantCMS's scheduler are active:

systemctl is-active nginx php8.3-fpm mariadb instantcms-firstboot instantcms-cron.timer
active
active
active
active
active

nginx serves ports 80 and 443; PHP and MariaDB listen on local sockets only, and the installer's temporary server is gone, so the only open ports are 22, 80 and 443:

sudo ss -tlnp | awk 'NR==1 || /nginx|sshd|php|maria/' | awk '{print $1, $4, $6}' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g'
State Local Peer
LISTEN 0.0.0.0:22 users:(("sshd"),("systemd"))
LISTEN 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx"))
LISTEN 0.0.0.0:443 users:(("nginx"),("nginx"),("nginx"))
LISTEN [::]:22 users:(("sshd"),("systemd"))
LISTEN [::]:80 users:(("nginx"),("nginx"),("nginx"))
LISTEN [::]:443 users:(("nginx"),("nginx"),("nginx"))

The InstantCMS release, the editor and the PHP and MariaDB versions:

sudo grep -E '^(major|minor|build) ' /var/www/instantcms/system/config/version.ini
sed -n 2p /var/www/instantcms/wysiwyg/tinymce/files/tinymce.min.js
php -v | head -1
mariadb --version
major = 2
minor = 18
build = 2
 * TinyMCE version 7.9.3 (2026-05-19)
PHP 8.3.6 (cli) (built: Oct 19 2026 15:16:58) (NTS)
mariadb  Ver 15.1 Distrib 10.11.14-MariaDB, for debian-linux-gnu (x86_64) using  EditLine wrapper

How the download was verified, and that every TinyMCE file is the 7.9.3 build:

cat /usr/share/doc/instantcms/RELEASE
cd /var/www/instantcms/wysiwyg/tinymce/files && sha256sum -c --quiet /usr/share/doc/instantcms/TINYMCE-7.9.3.sha256 && echo "48 files match TinyMCE 7.9.3"
InstantCMS 2.18.2
source https://codeload.github.com/instantsoft/icms2/tar.gz/refs/tags/2.18.2
commit 4a13609c480cccfcbd27dbab424d6bf00ad67375
sha256 b873ac1c123e367299304bd06a1c215490164199c97e6662127b8a1a59b83b7f
tinymce 7.9.3 https://registry.npmjs.org/tinymce/-/tinymce-7.9.3.tgz sha512-Mtm54U5YJ6Pyo/GaAx+JSHXTGEuxrg2AowVWCD9zy1eBolp5Ub7S1rTtsyQdxhPegfhLuR3VLiTKGw1tacv09g== (media plugin not shipped: GHSA-mf2p-h6hf-fcwm)
redactor removed (Imperavi proprietary licence)
48 files match TinyMCE 7.9.3

Step 4: Get your sign-in details

The credentials file holds the address InstantCMS is served as (your instance's public DNS name by default), the sign-in and control panel addresses, the administrator's e-mail and password, and the database credentials, all generated on this instance. Show it with:

sudo cat /root/instantcms-credentials.txt
INSTANTCMS_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/
INSTANTCMS_LOGIN_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/auth/login
INSTANTCMS_ADMIN_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/admin
INSTANTCMS_ADMIN_EMAIL=admin@example.com
INSTANTCMS_ADMIN_PASSWORD=<24 letters and digits>
INSTANTCMS_DB_NAME=instantcms
INSTANTCMS_DB_USER=instantcms
INSTANTCMS_DB_PASSWORD=<48 hexadecimal characters>

InstantCMS signs in with an e-mail address. The administrator starts as admin@example.com; change it to your own address in your profile (admin > Edit profile) before you rely on password recovery e-mails.

Step 5: Visit the site and sign in

Open INSTANTCMS_URL in your browser. The certificate is self signed (generated on your instance), so your browser warns once: compare the certificate's SHA-256 fingerprint with the one on the instance (sudo openssl x509 -in /etc/nginx/ssl/instantcms.crt -noout -fingerprint -sha256) and continue, or install a certificate from your own certificate authority (Step 11). A fresh site shows InstantCMS's modern theme:

The InstantCMS home page of a fresh site in the modern theme

Open INSTANTCMS_LOGIN_URL and sign in with INSTANTCMS_ADMIN_EMAIL and INSTANTCMS_ADMIN_PASSWORD:

The InstantCMS sign in page with the E-mail and Password fields

Then open INSTANTCMS_ADMIN_URL. The control panel opens on its dashboard, with the menu on the left:

The InstantCMS control panel dashboard with site statistics and the sidebar menu

The administrator can do everything. For editors and moderators, create accounts under Users and give them a group with only the permissions they need.

Step 6: Content and the editor

Content lives in content types (Content Types in the menu): the image starts with Pages and Photo albums; add articles, blogs, news or anything else your community needs, each with its own fields and permissions. Add a page from the site (/pages/add) or from Content in the control panel. The text field uses TinyMCE 7.9.3:

The TinyMCE 7.9.3 editor in the InstantCMS page form with a heading, bold and italic text and a list

Saving publishes the page at /pages/<url>.html:

A page published from the editor, showing its heading, formatting and list

Content in the control panel lists everything published, by content type:

The InstantCMS control panel content list

InstantCMS filters the HTML of every saved text on the server: scripts, event handler attributes and javascript: links are removed whatever the editor sends. The editor presets (toolbar buttons per field) are under Components > Editors; the media button cannot be added back, because the media plugin is not on the image.

Step 7: The closed-by-default settings

Setting Image default Where to change it
Public registration off ("We do not accept new users at the moment"), and the guest menu's Sign up link is hidden Components > Authorization & Registration (tick Registration enabled), and Menu > Header to show Sign up again
Update check (is_check_updates) off config.php (see Step 12)
Dashboard news and sponsorship feeds, add-ons catalogue, online updater not available (they fetch from instantcms.ru) install add-ons and updates from the shell (Step 12)
Client address (detect_ip_key) REMOTE_ADDR, the connection's address keep it (Step 10)
Site and upload address (host, upload_host) https://<your host> sudo instantcms-set-hostname (Step 11)
sudo php /usr/local/lib/cloudimg/instantcms/write-config.php dump | grep -E '^(host|upload_host|detect_ip_key|is_check_updates|debug)=' | sed -E 's#https://[^/'"'"']+#https://<your host>#'
sudo mysql -N -B --raw instantcms -e "SELECT options FROM cms_controllers WHERE name='auth'" | grep '^is_reg_enabled'
host='https://<your host>'
upload_host='https://<your host>/upload'
debug=0
is_check_updates=0
detect_ip_key='REMOTE_ADDR'
is_reg_enabled: null

The control panel also sends a content security policy that lets its pages connect only to your own server:

H=$(sed -n 's/^set \$icms_host "\(.*\)";$/\1/p' /etc/nginx/instantcms-host.conf)
curl -sk -D - -o /dev/null --resolve "$H:443:127.0.0.1" "https://$H/admin" | tr -d '\r' | grep -i '^content-security-policy'
content-security-policy: connect-src 'self'; frame-ancestors 'self'

Step 8: Your data

Everything that makes your site lives in the instantcms database in MariaDB and the uploads under /var/www/instantcms/upload. The caches in /var/www/instantcms/cache are rebuilt automatically. Keep system/config/config.php with your backup: it holds this site's database password.

Back up the database to a file only root can read (MariaDB's root signs in over the local socket without a password, so no password appears on the command line):

sudo sh -c 'umask 077; mysqldump --single-transaction instantcms > /root/instantcms-$(date +%F).sql'
sudo tar -C /var/www/instantcms -czf /root/instantcms-files-$(date +%F).tgz system/config upload

For a whole-instance copy, snapshot the EBS volume.

Step 9: Security checks

Port 80 sends browsers to HTTPS, the health endpoint answers for load balancer checks, and the installer, the configuration, the scheduler script, the updater, stray PHP files in the writable folders and the removed media plugin are not reachable:

H=$(sed -n 's/^set \$icms_host "\(.*\)";$/\1/p' /etc/nginx/instantcms-host.conf)
curl -s -o /dev/null -w 'port 80: %{http_code} -> %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/auth/login" | sed -E 's#https://[^/]+#https://<your host>#'
curl -sk --resolve "$H:443:127.0.0.1" "https://$H/healthz"
for p in /install/ /system/config/config.php /cron.php /update/current/install.php /upload/x.php /cache/x.php /wysiwyg/tinymce/files/plugins/media/plugin.min.js; do
  curl -sk -o /dev/null -w "$p: %{http_code}\n" --resolve "$H:443:127.0.0.1" "https://$H$p"
done
curl -s -o /dev/null -w 'unknown host name: %{http_code}\n' -H 'Host: example.com' http://127.0.0.1/ || true
port 80: 301 -> https://<your host>/auth/login
ok
/install/: 404
/system/config/config.php: 404
/cron.php: 404
/update/current/install.php: 404
/upload/x.php: 404
/cache/x.php: 404
/wysiwyg/tinymce/files/plugins/media/plugin.min.js: 404
unknown host name: 000

(000 means nginx closed the connection without an answer.) The credentials file is readable by root only, the configuration file by root and the web server, the upload and cache folders belong to the web server, and the code belongs to root:

sudo stat -c '%a %U:%G %n' /root/instantcms-credentials.txt /var/www/instantcms/system/config/config.php /var/www/instantcms/system/config /var/www/instantcms/upload /var/www/instantcms/cache /var/www/instantcms/index.php
600 root:root /root/instantcms-credentials.txt
640 root:www-data /var/www/instantcms/system/config/config.php
750 root:www-data /var/www/instantcms/system/config
750 www-data:www-data /var/www/instantcms/upload
750 www-data:www-data /var/www/instantcms/cache
755 root:root /var/www/instantcms/index.php

An uploaded HTML file is sent as a download with nosniff and the sandboxing policy, never rendered as a page of your site:

H=$(sed -n 's/^set \$icms_host "\(.*\)";$/\1/p' /etc/nginx/instantcms-host.conf)
echo '<b>demo</b>' | sudo -u www-data tee /var/www/instantcms/upload/guide-demo.html >/dev/null
curl -sk -D - -o /dev/null --resolve "$H:443:127.0.0.1" "https://$H/upload/guide-demo.html" | tr -d '\r' | grep -iE '^(HTTP|content-disposition|content-security-policy|x-content-type)'
sudo rm -f /var/www/instantcms/upload/guide-demo.html
HTTP/2 200
x-content-type-options: nosniff
content-security-policy: default-src 'none'; img-src 'self' data:; style-src 'unsafe-inline'; sandbox
content-disposition: attachment

The certificate was generated on this instance, names its own addresses and can only vouch for itself (it is not a certificate authority):

H=$(sed -n 's/^set \$icms_host "\(.*\)";$/\1/p' /etc/nginx/instantcms-host.conf)
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -ext basicConstraints,extendedKeyUsage
X509v3 Basic Constraints: critical
    CA:FALSE
X509v3 Extended Key Usage:
    TLS Web Server Authentication

nginx, PHP, MariaDB, the first boot service (and the installer's temporary server, which ran inside it) and the scheduler cannot reach the instance metadata service; PHP cannot run shell commands and is confined to the site folder; nginx hands PHP the configured host name, removes forwarding headers and any Authorization header a client sends, and rate-limits requests:

for u in nginx php8.3-fpm mariadb instantcms-firstboot instantcms-cron; do systemctl show $u -p IPAddressDeny; done
php-fpm8.3 -i 2>/dev/null | grep -E '^(open_basedir|disable_functions|expose_php) ' | cut -d' ' -f1-3
grep -E 'fastcgi_param (HTTP_HOST|SERVER_NAME|HTTP_X_FORWARDED_FOR|HTTP_CLIENT_IP|HTTP_X_FORWARDED_HOST|HTTP_AUTHORIZATION) ' /etc/nginx/snippets/cloudimg-instantcms-fastcgi.conf
grep -h 'limit_req_zone\|limit_req_status' /etc/nginx/conf.d/cloudimg-instantcms-guard.conf
IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32
IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32
IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32
IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32
IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32
disable_functions => exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec
expose_php => Off
open_basedir => /var/www/instantcms/:/var/lib/php/sessions/:/tmp/
fastcgi_param HTTP_HOST $icms_host;
fastcgi_param SERVER_NAME $icms_host;
fastcgi_param HTTP_X_FORWARDED_HOST "";
fastcgi_param HTTP_X_FORWARDED_FOR "";
fastcgi_param HTTP_CLIENT_IP "";
fastcgi_param HTTP_AUTHORIZATION "";
limit_req_zone $icms_login_key zone=icms_login:10m rate=10r/m;
limit_req_zone $icms_post_key zone=icms_post:10m rate=60r/m;
limit_req_zone $binary_remote_addr zone=icms_php:10m rate=600r/m;
limit_req_status 429;

icms_login counts sign-in, password recovery, reset and registration attempts from one address (10 a minute after a burst of 10), icms_post every request that sends data (60 a minute after a burst of 60) and icms_php every page (600 a minute). Raise them in /usr/local/lib/cloudimg/instantcms/login-guard.conf.tmpl and /etc/nginx/snippets/cloudimg-instantcms-fastcgi.conf if your community needs more, then run sudo instantcms-set-hostname <your host> (Step 11) to apply the template.

sudo instantcms-cred-roundtrip checks the whole sign in path on the instance: the redirect to HTTPS, that no installer is offered and the configuration is refused, a sign in through the real sign-in form with the password from the credentials file, and that a wrong and a common password are refused:

sudo instantcms-cred-roundtrip
OK https 301 + no installer + config.php 404 + administrator sign-in + wrong and default passwords refused

Links opened from another site. A control panel page under /admin/, or a site link that changes something (joining, entering or leaving a group, accepting or declining requests, changing a group's owner, setting an album cover, unbinding content, starting a message), only works when the request comes from your site itself. nginx decides this from the browser's Sec-Fetch-Site, Origin and Referer headers (a request with none of them is refused too), so another site cannot make you act through a link. The dashboard at /admin and every ordinary page stay linkable. Scripts that call those routes must send Sec-Fetch-Site: same-origin:

H=$(sed -n 's/^set \$icms_host "\(.*\)";$/\1/p' /etc/nginx/instantcms-host.conf)
curl -sk -o /dev/null -w 'settings link from another site: %{http_code}\n' -H 'Sec-Fetch-Site: cross-site' --resolve "$H:443:127.0.0.1" "https://$H/admin/settings"
curl -sk -o /dev/null -w 'group leave link from another site: %{http_code}\n' -H 'Sec-Fetch-Site: cross-site' --resolve "$H:443:127.0.0.1" "https://$H/groups/example/leave"
curl -sk -o /dev/null -w 'sign in page from another site: %{http_code}\n' -H 'Sec-Fetch-Site: cross-site' --resolve "$H:443:127.0.0.1" "https://$H/auth/login"
settings link from another site: 403
group leave link from another site: 403
sign in page from another site: 200

The rules cover these routes under the components' own names, any URL alias you give a component (Components, the component's settings) and a language prefix. They are written by instantcms-set-hostname into /etc/nginx/conf.d/cloudimg-xsite-guard.conf and /etc/nginx/conf.d/cloudimg-instantcms-guard.conf: run sudo instantcms-set-hostname <your host> again after you change a component's URL alias.

Step 10: Behind a proxy or load balancer

nginx removes X-Forwarded-For, X-Real-IP, Client-IP and Forwarded from every request, and InstantCMS reads the client address from the connection (detect_ip_key is REMOTE_ADDR), so the users list, sessions and logs use the address of the connection. Behind an AWS load balancer that is the load balancer's address; nginx's own access log (/var/log/nginx/access.log) records it the same way. To record visitors' addresses, use nginx's real_ip module with set_real_ip_from set to your load balancer's subnet only.

Step 11: Your own DNS name and certificate

Point a DNS record at the instance, then set the name InstantCMS is served as. This mints a new self signed certificate for the name, updates nginx (which hands the name to InstantCMS), the request rules and the site and upload addresses in config.php, clears InstantCMS's caches, updates the addresses in /root/instantcms-credentials.txt and keeps the name across reboots:

sudo instantcms-set-hostname <your-domain>

To use a certificate from your own certificate authority instead, copy it over the generated pair and reload nginx (running instantcms-set-hostname again replaces it with a self signed one):

sudo install -m 0644 <your-domain>.crt /etc/nginx/ssl/instantcms.crt
sudo install -m 0600 <your-domain>.key /etc/nginx/ssl/instantcms.key
sudo nginx -t && sudo systemctl reload nginx

Once browsers trust the certificate you can also add an HSTS header (add_header Strict-Transport-Security "max-age=31536000" always;) to /etc/nginx/snippets/cloudimg-instantcms-headers.conf. The image does not send one: browsers ignore HSTS from a site whose certificate they do not trust.

Step 12: Passwords, settings, e-mail, add-ons and upgrades

instantcms-set-password gives the administrator a new random password with InstantCMS's own password hashing, removes its "remember me" tokens, signs out every session and records the password in /root/instantcms-credentials.txt. Run it without arguments, or pass your own password (24 to 72 letters and digits) on stdin. Users change their own password in their profile.

sudo instantcms-set-password
printf '%s\n' '<your-new-password>' | sudo instantcms-set-password --stdin

The configuration file is read only to PHP. config.php is executed on every request, so the image does not let the web server rewrite it (a compromised PHP process could otherwise change the site permanently), and the cloudimg tools never execute it: they read it as data and refuse it unless it belongs to root, is mode 0640 and holds plain values only. InstantCMS keeps most settings in its database and saves them normally; the site settings under Settings and the theme options live in files, and saving them reports that the file is not writable. For that change only, let PHP write the file, save the setting, and restore the mode straight after:

sudo chmod 0660 /var/www/instantcms/system/config/config.php
sudo chmod 0640 /var/www/instantcms/system/config/config.php

(instantcms-set-hostname refuses to run while the file is writable.) Theme options are in system/config/theme_modern.yml, and the theme's compiled stylesheet in templates/modern/css: make those writable the same way for a theme change, then restore them.

E-mail. InstantCMS sends password recovery mail and notifications with PHP's mail function by default; the image has no mail server, so set an SMTP server under Settings > Mail before you rely on e-mail.

Add-ons and templates. The code folders belong to root, so the control panel cannot install packages, and its add-ons catalogue and online updater (which download from instantcms.ru) are not available. Install an add-on from the shell: unpack its package, copy its files into /var/www/instantcms as root, then run its installation under Components. If the add-on has a database script, the control panel's Components page runs it.

Upgrades. InstantCMS releases are published at https://github.com/instantsoft/icms2/releases. After a snapshot, copy the new release's files over /var/www/instantcms (keep system/config, upload and cache), run its update from Settings in the control panel if the release includes one, then check that the code belongs to root again and that config.php is 0640 root:www-data. Keep the TinyMCE 7.9.3 files: a new InstantCMS release may bring its own TinyMCE, so check its version with the command in Step 3.

Step 13: Server components

Component Path
InstantCMS code (root owned) /var/www/instantcms
Configuration (this instance's database password) /var/www/instantcms/system/config/config.php
Uploads /var/www/instantcms/upload
Caches (rebuilt automatically) /var/www/instantcms/cache
Editor (TinyMCE 7.9.3) and its checksum list /var/www/instantcms/wysiwyg/tinymce/files, /usr/share/doc/instantcms/TINYMCE-7.9.3.sha256
Database (MariaDB datadir) /var/lib/mysql
Scheduler (InstantCMS's cron.php every minute as www-data) instantcms-cron.timer, instantcms-cron.service
nginx site, request limits and cross-site link rules /etc/nginx/sites-available/cloudimg-instantcms, /etc/nginx/conf.d/cloudimg-instantcms-guard.conf, /etc/nginx/conf.d/cloudimg-xsite-guard.conf, /etc/nginx/snippets/cloudimg-instantcms-*.conf
PHP settings /etc/php/8.3/fpm/conf.d/99-cloudimg-instantcms.ini
MariaDB settings /etc/mysql/mariadb.conf.d/99-cloudimg-instantcms.cnf
Certificate and key /etc/nginx/ssl/
First boot script, installer copy and helpers /usr/local/sbin/instantcms-firstboot.sh, /usr/local/lib/cloudimg/instantcms/
Helpers /usr/local/sbin/instantcms-set-hostname, instantcms-set-password, instantcms-cred-roundtrip
Licences, release and image notes /usr/share/doc/instantcms/
Credentials /root/instantcms-credentials.txt (mode 0600)

Step 14: Security recommendations

  • Allow port 22 in the security group from your own networks only.
  • Change the administrator e-mail to your own (Step 4), keep its password secret and rotate it if it may have been shared (Step 12).
  • Open registration only when you are ready to moderate a community, and consider a captcha for it (Components > Authorization & Registration).
  • Keep config.php and your database backups secret (Step 8).
  • Use your own DNS name and a certificate your browsers trust (Step 11).
  • Keep InstantCMS on the newest release (Step 12) and install only add-ons you trust.
  • Keep the operating system patched; unattended security upgrades are on, and sudo apt-get update && sudo apt-get upgrade applies everything else. MariaDB, PHP-FPM and PHP's zip extension come from Ubuntu's universe repository; sudo pro security-status --esm-apps shows whether Ubuntu Pro (ESM Apps) has security updates for them (none were pending when the image was built).

Support and licensing

InstantCMS is free software under the GNU General Public License, version 2 (a copy is at /usr/share/doc/instantcms/LICENSE); TinyMCE is under the GNU General Public License, version 2 or later (/usr/share/doc/instantcms/TINYMCE-LICENSE.md), and the other bundled libraries carry their own open source licences. There is no per user or per CPU licence fee and no licence key. This image installs the upstream release with its bundled TinyMCE replaced by TinyMCE 7.9.3 (without the media plugin) and without the proprietary Redactor editor, plus the cloudimg first boot, settings and helpers described above. The AMI price covers cloudimg's hardening, first boot setup and support.

  • Email: support@cloudimg.co.uk
  • Website: https://www.cloudimg.co.uk
  • Support: 24/7, with a 24 hour response SLA