Applications AWS

REDAXO on AWS User Guide

| Product: REDAXO

Overview

REDAXO is an open source PHP content management system that has been developed continuously since 2004 by Yakamara Media. It is deliberately unopinionated. Instead of imposing a fixed page model, REDAXO gives you templates and modules that you define yourself, so the editing interface ends up matching the site you are actually building rather than the other way round. Editors get a clean backend with a structured page tree, a media pool and reusable content blocks; developers get plain PHP templates, a documented API, a command line console and an addon system.

This image runs REDAXO 5.21.2 on a LAMP stack assembled entirely from the distribution archives, with no third party package repositories: Apache 2.4 with mod_php, PHP 8.3 with OPcache, and MariaDB 10.11 bound to the loopback interface only. The database directory and the application tree each sit on their own EBS volume, separate from the operating system disk.

The important difference from a do-it-yourself install is that there is no installer waiting on your public IP address. The published image contains no configuration file, no database and no user account. On first boot a one shot service generates a fresh database password and a fresh administrator password, creates the database and a least privilege database user, runs the REDAXO console setup, seeds a starter page and then closes the setup routine permanently. Until that has finished, the web server answers every request with HTTP 503 rather than an installation wizard.

Backed by 24/7 cloudimg support.


Connecting to your instance

Image variant SSH login user Example
Ubuntu 24.04 ubuntu ssh -i your-key.pem ubuntu@<public-ip>

The instance opens three inbound ports: 22 for SSH, 80 for the site and 443 for TLS once you configure it. The database listens on 127.0.0.1:3306 only and is never reachable from the network.


Launching the instance

From AWS Marketplace

  1. Open the product page and choose Continue to Subscribe, then Continue to Configuration.
  2. Pick your region and the software version, then Continue to Launch.
  3. Choose Launch through EC2. Select an instance type (m5.large is the recommended size), your key pair, and a security group that allows inbound 22 from your own address and 80 and 443 from wherever your visitors are.
  4. Launch, then wait for the instance to reach 2/2 checks passed.

From the EC2 CLI

Substitute your own AMI id, key pair, subnet and security group.

aws ec2 run-instances \
  --region us-east-1 \
  --image-id ami-0123456789abcdef0 \
  --instance-type m5.large \
  --key-name your-key \
  --security-group-ids sg-0123456789abcdef0 \
  --subnet-id subnet-0123456789abcdef0 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=redaxo}]'

First boot takes roughly a minute after the instance reports healthy. Until it completes, the site answers 503 by design.


Verifying the deployment

SSH in as the login user for your variant, then run the checks below.

Services

Both application services should be active, and the one shot first boot unit reports active because it is a RemainAfterExit oneshot that has already completed.

systemctl is-active mariadb apache2 redaxo-firstboot
active
active
active

Software versions

sudo -u www-data php /var/www/redaxo/redaxo/bin/console -V
php -v | head -1
apache2 -v | head -1
mariadb -N -B -e 'SELECT VERSION()'
REDAXO 5.21.2
PHP 8.3.6 (cli) (built: Jul 16 2026 18:30:41) (NTS)
Server version: Apache/2.4.58 (Ubuntu)
10.11.14-MariaDB-0ubuntu0.24.04.1

Dedicated data volumes

The content database and the application tree are on their own EBS volumes, so each can be resized and snapshotted independently of the operating system disk.

df -h /var/www /var/lib/mysql
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme1n1     20G   25M   19G   1% /var/www
/dev/nvme2n1     20G  191M   19G   2% /var/lib/mysql

Retrieving your credentials

Every instance generates its own administrator and database passwords on first boot and writes them to a root only file. Nothing is shared between deployments and nothing is recoverable from the published image.

sudo cat /root/redaxo-credentials.txt
# REDAXO - generated on first boot by redaxo-firstboot.service.
# These credentials are unique to this instance. Store them somewhere safe.

REDAXO_URL=http://<public-ip>/
REDAXO_BACKEND_URL=http://<public-ip>/redaxo/
REDAXO_ADMIN_USERNAME=cloudimg
REDAXO_ADMIN_PASSWORD=<REDAXO_ADMIN_PASSWORD>
REDAXO_DB_NAME=redaxo
REDAXO_DB_USER=redaxo
REDAXO_DB_PASSWORD=<REDAXO_DB_PASSWORD>

The file is 0600 root:root, so it is readable only through sudo.


Signing in to the backend

Browse to http://<public-ip>/redaxo/ and sign in with REDAXO_ADMIN_USERNAME and REDAXO_ADMIN_PASSWORD from that file.

REDAXO backend sign-in page

The first thing you should do after signing in is change the password from your profile page.

You can confirm the sign in works from the command line as well. The check below signs in with the per instance password, then proves a wrong password is refused, and reports only its verdict.

sudo /usr/local/sbin/redaxo-login-check.sh
OK REDAXO backend accepted the per-instance password and refused a wrong one

What you land on

After signing in you arrive at Structure management, REDAXO's page tree. The image seeds one online article called Home on a template called cloudimg Starter, so the front end serves a real page immediately rather than a "not found" error.

Structure management showing the seeded Home article

The front end is already live on port 80:

CODE=$(curl -s -o /dev/null -w '%{http_code}' -m 20 http://127.0.0.1/)
BODY=$(curl -s -m 20 http://127.0.0.1/)
echo "front end HTTP ${CODE}"
[ "${CODE}" = "200" ] || { echo "FATAL: front end returned ${CODE}, expected 200"; exit 1; }
printf '%s' "${BODY}" | grep -q 'REDAXO is running' \
  || { echo "FATAL: the seeded starter article was not served"; exit 1; }
echo "starter article served"
front end HTTP 200
starter article served

The seeded starter page on the front end

The starter page is an ordinary article. Edit it, or delete it once you have templates of your own.


Creating your first page

REDAXO separates what a page looks like (a template) from what an editor may put on it (modules assembled into content slices).

  1. Open Templates and either edit cloudimg Starter or add your own. A template is plain PHP and HTML; REX_ARTICLE[] marks where article content is rendered.

Template list

  1. Open Modules and define the content blocks your editors will use, for example a heading, a rich text block, or an image with a caption. Each module has an input form and an output template.

  2. Open Structure, add a category or an article, choose its template, and set it online.

  3. Open the article and use Add slice to place your modules on the page.

Editing an article

Uploaded assets live in the Media Pool, and the Media Manager addon generates resized and cropped variants on demand.

Media pool


Addons

The image ships REDAXO's complete core addon set, all of it MIT licensed. The Installer addon fetches further addons from the REDAXO repository.

Addon management

sudo -u www-data php /var/www/redaxo/redaxo/bin/console list | sed -n '15,40p'
Available commands:
  completion                 Dump the shell completion script
  help                       Display help for a command
  list                       List commands
 assets
  assets:sync                Sync assets within the assets-dir with the sources-dir
 be_style
  be_style:compile           [styles:compile] Converts Backend SCSS files to CSS
 cache
  cache:clear                Clears the redaxo core cache
 config
  config:get                 Get config variables
  config:set                 Set config variables
 db
  db:connection-options      Dumps the db connection options for the mysql cli tool
  db:dump-schema             Dumps the schema of db tables as php code
  db:set-connection          Sets database connection credentials.
 install
  install:download           Download an AddOn from redaxo.org
  install:list               List available packages on redaxo.org
  install:update             Updates an AddOn from redaxo.org
 package
  package:activate           Activates the selected package
  package:deactivate         Deactivates the selected package
  package:delete             Deletes the selected package
  package:install            Installs the selected package

Managing users

Open User to add editors and administrators and to assign roles. Give day to day editors a non administrator account with only the permissions they need.

User administration


Verifying the security posture

These four checks are worth running once on any new deployment. They are the same properties the image asserts for itself before it is published.

The setup wizard is closed

The console setup wrote setup: false into the configuration when it completed, so REDAXO will never serve an installation wizard again.

CFG=/var/www/redaxo/redaxo/data/core/config.yml
grep -E '^setup:' "${CFG}" \
  || { echo "FATAL: no setup key in ${CFG}"; exit 1; }
grep -qE '^setup:[[:space:]]*false[[:space:]]*$' "${CFG}" \
  || { echo "FATAL: the REDAXO setup wizard is still open"; exit 1; }
echo "setup wizard closed"
setup: false
setup wizard closed

The database is not reachable from the network

MariaDB binds to loopback only. The listener list below should show the database on 127.0.0.1 and only SSH and Apache on a public address. (127.0.0.53 and 127.0.0.54 are the systemd DNS stub resolvers, also loopback.)

ss -tlnH | awk '{print $4}' | sort
BAD=""
while read -r addr; do
    [ -n "${addr}" ] || continue
    host="${addr%:*}"; host="${host%%%*}"; port="${addr##*:}"
    case "${host}" in 127.*|"[::1]"|::1) continue ;; esac
    case "${port}" in 22|80|443) continue ;; esac
    BAD="${BAD} ${addr}"
done < <(ss -tlnH | awk '{print $4}')
[ -z "${BAD}" ] || { echo "FATAL: unexpected public listeners:${BAD}"; exit 1; }
ss -tlnH | awk '{print $4}' | grep -qx '127.0.0.1:3306' \
  || { echo "FATAL: the database is not bound to loopback"; exit 1; }
echo "only SSH and the web server are reachable; the database is loopback only"
*:80
0.0.0.0:22
127.0.0.1:3306
127.0.0.53%lo:53
127.0.0.54:53
[::]:22
only SSH and the web server are reachable; the database is loopback only

REDAXO's internal trees are not web readable

The source, data, cache and console directories are denied by both REDAXO's own .htaccess files and a vhost rule, so a request for any of them is refused.

for p in redaxo/src/core/boot.php redaxo/data/core/config.yml redaxo/cache/ redaxo/bin/console; do
  C=$(curl -s -o /dev/null -w '%{http_code}' -m 10 "http://127.0.0.1/${p}")
  echo "/${p} -> HTTP ${C}"
  case "${C}" in 403|404) : ;; *) echo "FATAL: /${p} is readable over HTTP"; exit 1 ;; esac
done
echo "internal trees refused as expected"
/redaxo/src/core/boot.php -> HTTP 403
/redaxo/data/core/config.yml -> HTTP 403
/redaxo/cache/ -> HTTP 403
/redaxo/bin/console -> HTTP 403
internal trees refused as expected

The application database user is least privilege

The account REDAXO connects with is scoped to its own database and has no global privileges.

GRANTS=$(sudo mariadb -N -B -e "SHOW GRANTS FOR 'redaxo'@'127.0.0.1'")
echo "${GRANTS}" | sed -E "s/IDENTIFIED BY PASSWORD .*/IDENTIFIED BY PASSWORD <redacted>/"
printf '%s' "${GRANTS}" | grep -qi 'ALL PRIVILEGES ON \*\.\*' \
  && { echo "FATAL: the application user has global privileges"; exit 1; }
printf '%s' "${GRANTS}" | grep -q '`redaxo`' \
  || { echo "FATAL: no grant scoped to the redaxo database"; exit 1; }
echo "application database user is scoped to the redaxo database only"
GRANT USAGE ON *.* TO `redaxo`@`127.0.0.1` IDENTIFIED BY PASSWORD <redacted>
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, REFERENCES ON `redaxo`.* TO `redaxo`@`127.0.0.1`
application database user is scoped to the redaxo database only

Reaching the database

Because MariaDB is loopback only, connect through an SSH tunnel from your own workstation rather than opening port 3306. Run this on your machine, not on the instance:

ssh -i your-key.pem -L 3306:127.0.0.1:3306 ubuntu@<public-ip>

Then point your client at 127.0.0.1:3306 with REDAXO_DB_USER and REDAXO_DB_PASSWORD from the credentials file.


Setting your real site URL

REDAXO records a site URL and an error e-mail address. The image sets the URL to the instance's public address at first boot and the error address to a placeholder, so change both once you have a domain. Either edit them in the backend under System, or from the command line:

sudo -u www-data php /var/www/redaxo/redaxo/bin/console config:set server https://<your-domain>/
sudo -u www-data php /var/www/redaxo/redaxo/bin/console config:set error_email you@<your-domain>
sudo -u www-data php /var/www/redaxo/redaxo/bin/console cache:clear

The backend and front end both work from the request host, so the site keeps answering on the instance IP, a private address or a custom domain without any further reconfiguration. The recorded URL is used for absolute links and outgoing mail.


Enabling HTTPS

The image is TLS ready but ships no certificate, because a certificate is specific to your domain. Two options:

AWS Certificate Manager behind a load balancer. Put an Application Load Balancer in front of the instance, attach an ACM certificate to the listener, and forward to port 80. This is the usual choice for production and needs no change on the instance.

Let's Encrypt directly on the instance. Point your domain at the instance's public address first, then:

sudo apt-get update
sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d <your-domain> --agree-tos -m you@<your-domain> --redirect

Afterwards, tell REDAXO to use HTTPS so it generates https:// links:

sudo -u www-data php /var/www/redaxo/redaxo/bin/console config:set use_https true
sudo -u www-data php /var/www/redaxo/redaxo/bin/console cache:clear

Backups

Two things need backing up: the database and the application tree (which holds your templates, modules, the media pool and any addons you install).

Database, from the instance:

sudo mariadb-dump --single-transaction --default-character-set=utf8mb4 redaxo \
  | gzip > /var/backups/redaxo-$(date +%F).sql.gz

Application tree:

sudo tar -czf /var/backups/redaxo-files-$(date +%F).tar.gz -C /var/www redaxo

Copy both off the instance, for example to Amazon S3. The backend's Backup addon can also export and import the database from the browser.

Because each tier is on its own EBS volume, an EBS snapshot of the /var/lib/mysql volume and the /var/www volume is an equally valid backup and is usually the simplest to schedule with Amazon Data Lifecycle Manager.


Keeping the system patched

The image ships fully patched, and unattended upgrades are left in their stock configuration so security updates continue to arrive. To apply everything immediately:

sudo apt-get update
sudo apt-get -y upgrade

REDAXO itself is upgraded from the backend: the Installer addon offers core and addon updates, and the Backup addon lets you export the database first.


Troubleshooting

The site returns 503. First boot has not finished, or it failed. Check it:

systemctl is-active redaxo-firstboot >/dev/null \
  || { echo "FATAL: first boot did not complete - run: journalctl -u redaxo-firstboot"; exit 1; }
test -f /var/lib/cloudimg/redaxo-firstboot.done \
  || { echo "FATAL: the first-boot sentinel is missing"; exit 1; }
echo "first boot completed"
first boot completed

If first boot did fail, journalctl -u redaxo-firstboot carries the reason. Apache deliberately refuses to start until it succeeds, so the setup wizard can never be exposed.

Signing in is rejected. Confirm you are using REDAXO_ADMIN_USERNAME from the credentials file, not a name of your own. After several wrong attempts REDAXO applies a short delay before the next try.

A page shows no content. A new article has no content slices until you add them, and it needs a template that is active and permitted for its category.

Something is slow. Check systemctl status apache2 mariadb and the Apache error log at /var/log/apache2/redaxo-error.log. For a busy site, move to a larger instance type or migrate the database to Amazon RDS.


Support

Every subscription includes 24/7 technical support from cloudimg engineers.

  • Email: support@cloudimg.co.uk
  • Live chat: available 24/7

We help with deployment, credential retrieval, upgrades, addon installation, template and module development, performance tuning, TLS configuration and database administration.

REDAXO is open source software published under the MIT licence by Yakamara Media GmbH & Co. KG. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.