LimeSurvey on AWS User Guide
Overview
LimeSurvey is the leading open source online survey and questionnaire platform. It gives you dozens of question types, conditional branching, quotas, multilingual surveys, participant management with invitations and reminders, response statistics, and export to CSV, Excel, PDF, SPSS and R, together with a clean respondent-facing front end that works in any browser.
The cloudimg image delivers LimeSurvey 7 Community Edition on a LAMP stack: NGINX 1.24 in front of PHP 8.3 (php-fpm), backed by MariaDB 10.11, all from the Ubuntu 24.04 main and universe repositories with no third-party APT repositories. The LimeSurvey schema is installed at build time through LimeSurvey's own console installer, so you land on a working administration console rather than a web installer, and the web installer itself is blocked. Backed by 24/7 cloudimg support.
What is included:
- LimeSurvey 7.0.6+260722 Community Edition (GPL-2.0-or-later) at
/var/www/limesurvey, downloaded from the official LimeSurvey download server and verified against a pinned SHA-256 digest at build time - NGINX 1.24 serving the LimeSurvey front controller on port 80, with the internal application directories and the web installer denied
- PHP 8.3 with OPcache and every LimeSurvey required and recommended extension:
pdo_mysql,mysqli,mbstring,gd,imap,ldap,zip,intl,dom,simplexml,xmlreader,xmlwriter,curl,bcmath,gmpandsodium - MariaDB 10.11 bound to
127.0.0.1only, on its own dedicated EBS volume - Two dedicated EBS data volumes: the MariaDB datadir at
/var/lib/mysqland the LimeSurvey writable application data at/var/lib/limesurvey, each independently resizable and mounted by filesystem UUID - A per-instance administrator password, a per-instance MariaDB maintenance credential and per-instance LimeSurvey response-encryption keys, all minted on first boot — no shared or default credential ships in the image
- 24/7 cloudimg support
This image ships only the free Community Edition. LimeSurvey Cloud and the paid LimeSurvey subscription tiers are separate products from LimeSurvey GmbH and are not included. cloudimg is not affiliated with or endorsed by LimeSurvey GmbH.
Launching the instance
Launch the AMI from AWS Marketplace, or with the EC2 console or CLI. Recommended instance type is m5.large or larger. Your security group needs:
| Port | Protocol | Purpose | Suggested source |
|---|---|---|---|
| 22 | TCP | SSH administration | Your management CIDR only |
| 80 | TCP | LimeSurvey administration and the public survey front end | Your respondents' networks, or 0.0.0.0/0 for a public survey |
| 443 | TCP | HTTPS once you attach a certificate | Same as port 80 |
Port 3306 is never required and should never be opened: MariaDB listens on the loopback interface only.
First boot takes roughly two minutes. It generates this instance's credentials and encryption keys, so wait for it to finish before signing in.
Connecting to your instance
| OS variant | SSH login user | Example |
|---|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i your-key.pem ubuntu@<public-ip> |
Replace <public-ip> with the public IPv4 address shown for your instance in the EC2 console, and your-key.pem with the private key of the key pair you selected at launch.
Confirming the stack is up
Every service LimeSurvey needs is enabled and starts automatically:
systemctl is-active nginx.service php8.3-fpm.service mariadb.service limesurvey-firstboot.service
active
active
active
active
NGINX serves an unauthenticated static health endpoint at /healthz, which is what you point an Application Load Balancer or an EC2 health check at:
curl -s -o /dev/null -w 'health endpoint: HTTP %{http_code}\n' http://127.0.0.1/healthz
health endpoint: HTTP 200
Confirm the shipped versions:
grep -E "versionnumber|buildnumber" /var/www/limesurvey/application/config/version.php
php -r 'echo "PHP ", PHP_VERSION, "\n";'
mariadb --version
nginx -v
$config['versionnumber'] = '7.0.6';
$config['buildnumber'] = 260722;
PHP 8.3.6
mariadb Ver 15.1 Distrib 10.11.14-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper
nginx version: nginx/1.24.0 (Ubuntu)
Retrieving your administrator credentials
First boot writes this instance's credentials to a root-only file at /root/limesurvey-credentials.txt, mode 0600. The file holds three keys:
sudo grep -oE '^LIMESURVEY_[A-Z_]+=' /root/limesurvey-credentials.txt
LIMESURVEY_ADMIN_URL=
LIMESURVEY_ADMIN_USER=
LIMESURVEY_ADMIN_PASSWORD=
To read the values, run the command in the table below over SSH. Keep the output to yourself: it is the only administrator account on the instance.
| What you need | Command |
|---|---|
| The whole credentials file | sudo cat /root/limesurvey-credentials.txt |
| Just the administrator password | sudo grep '^LIMESURVEY_ADMIN_PASSWORD=' /root/limesurvey-credentials.txt \| cut -d= -f2- |
| Just the sign-in URL | sudo grep '^LIMESURVEY_ADMIN_URL=' /root/limesurvey-credentials.txt \| cut -d= -f2- |
The password is generated from openssl rand on this instance and on no other. Two instances launched from this AMI never share it.
Signing in
Browse to http://<public-ip>/index.php/admin and sign in with user admin and the password from the credentials file.

Change the password from admin menu → My account once you are in, and add a real email address so password resets work.
The trusted host list, on your first sign-in
LimeSurvey 7 protects against HTTP Host header injection with a trusted host allowlist. The file that holds it, application/config/allowed_hosts.php, does not ship in this image, so a fresh instance answers on any hostname. On your first successful administrator sign-in LimeSurvey creates that file and pins the hostname you used at that moment; every later request arriving with a different Host header is then rejected with HTTP 400 The requested hostname is invalid.
Two practical consequences:
- Sign in first on the name you intend to use in production. If you plan to put
surveys.example.comin front of the instance, point the DNS record at it and sign in on that name, not on the raw public IP. - To serve more than one hostname (for example an IP for administration and a domain for respondents), edit the file after that first sign-in:
| Task | Command |
|---|---|
| Show the current trusted hosts | sudo cat /var/www/limesurvey/application/config/allowed_hosts.php |
| Edit the list | sudo -u www-data nano /var/www/limesurvey/application/config/allowed_hosts.php |
| Start over (re-pin on the next sign-in) | sudo rm /var/www/limesurvey/application/config/allowed_hosts.php |
Building your first survey
From Surveys → Create survey, give the survey a title and a base language. LimeSurvey creates a first question group and an example question for you.

Each survey has its own settings for text elements, privacy policy, presentation, participant handling, notifications, quotas and permissions:

Add your questions, then use Preview survey to see exactly what a respondent will see:

When the survey is ready, activate it from the survey toolbar. Activation creates the survey's own response table, after which the survey list shows its status and a live response count:

Share the participation link — http://<public-ip>/index.php/<survey-id> — with your respondents, or use Survey participants to send tokenised invitations and reminders. Responses are visible under Responses, and can be exported to CSV, Excel, PDF, SPSS or R from Responses → Export.
Storage layout
The database tier and the application data tier each sit on their own EBS volume, so you can grow the response store and the uploaded-file store independently of the operating system disk, and snapshot them separately.
findmnt -no SOURCE,TARGET,FSTYPE,SIZE /var/lib/mysql
findmnt -no SOURCE,TARGET,FSTYPE,SIZE /var/lib/limesurvey
df -h --output=target,size,used,avail / /var/lib/mysql /var/lib/limesurvey
/dev/nvme2n1 /var/lib/mysql ext4 29.4G
/dev/nvme1n1 /var/lib/limesurvey ext4 29.4G
Mounted on Size Used Avail
/ 38G 3.7G 35G
/var/lib/mysql 30G 126M 28G
/var/lib/limesurvey 30G 176M 28G
/var/lib/mysqlis the MariaDB data directory. It holds thelimesurveyschema, every survey definition and every survey response./var/lib/limesurveyholds LimeSurvey's writable state:upload/for survey resources and respondent file uploads, andtmp/for exports, imports, the runtime cache, published assets and the session cache. LimeSurvey reaches them through symlinks from its own tree:
ls -l /var/www/limesurvey/upload /var/www/limesurvey/tmp
lrwxrwxrwx 1 root root 23 /var/www/limesurvey/tmp -> /var/lib/limesurvey/tmp
lrwxrwxrwx 1 root root 26 /var/www/limesurvey/upload -> /var/lib/limesurvey/upload
Both volumes are recorded in /etc/fstab by filesystem UUID, not by device name, so the layout survives reboots and re-launches even though NVMe device names are not stable. To grow either tier, resize the EBS volume in the EC2 console, then run sudo growpart on the device and sudo resize2fs on the filesystem.
Security posture
The web installer is blocked
A LimeSurvey installation whose web installer is still reachable can be claimed by the first visitor. On this image the installer is blocked twice over, independently.
First, NGINX denies every installer path outright:
for p in /installer /index.php/installer/welcome; do
printf '%s -> HTTP %s\n' "$p" "$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1$p)"
done
/installer -> HTTP 403
/index.php/installer/welcome -> HTTP 403
Second, LimeSurvey refuses on its own account: InstallerController::checkInstallation() aborts with "Installation has been done already. Installer disabled." whenever application/config/config.php exists, which it does on every instance of this image. Removing the NGINX rule would not re-open the installer.
No default or shared credential
The administrator account is created at build time by LimeSurvey's console installer with a random password that is then discarded, and re-minted per instance at first boot. There is no admin/password pairing to find. The image also ships no usable system password hash at all:
sudo awk -F: 'BEGIN{n=0} $2!="" && $2!="*" && $2 !~ /^!/ {n++} END{print "accounts with a usable password hash: " n}' /etc/shadow
accounts with a usable password hash: 0
SSH accepts your EC2 key pair only; password authentication is off.
The database is not on the network
MariaDB is pinned to the loopback interface, so the application database is unreachable from outside the instance whatever your security group says:
sudo ss -tlnp | awk '$4 ~ /:3306$/ {print $1, $4, $6}'
LISTEN 127.0.0.1:3306 users:(("mariadbd",pid=17574,fd=22))
For on-box maintenance, sudo mariadb authenticates over the unix socket as root@localhost; no database password is needed or stored for that path.
Per-instance response-encryption keys
LimeSurvey can encrypt participant and response fields at rest. The keys that do it live in application/config/security.php, and first boot mints a fresh libsodium nonce and secret-box key for this instance before LimeSurvey has a chance to generate one, so no two instances launched from this AMI share an encryption key. Once you have collected encrypted responses, back that file up with the database: losing it loses the ability to read those responses.
Enable HTTPS before you collect responses
The image is TLS-ready but ships no certificate, so out of the box the administration console and the survey front end are served over plain HTTP. Survey responses are frequently personal data, so put HTTPS in front of the instance before you publish a survey. Either terminate TLS on an Application Load Balancer with a certificate from AWS Certificate Manager, or install Certbot on the instance and issue a certificate for your own domain. LimeSurvey itself will then warn you no further: enable Force HTTPS under Configuration → Global settings → Security once the certificate is live.
Maintenance
| Task | Command |
|---|---|
| Back up the database | sudo mariadb-dump --single-transaction --routines limesurvey \| gzip > ~/limesurvey-$(date +%F).sql.gz |
| Back up uploaded survey files | sudo tar czf ~/limesurvey-uploads-$(date +%F).tar.gz -C /var/lib/limesurvey upload |
| Back up the encryption keys | sudo cp /var/www/limesurvey/application/config/security.php ~/limesurvey-security-$(date +%F).php |
| Apply operating system updates | sudo apt-get update && sudo apt-get -y dist-upgrade |
| Restart the web tier | sudo systemctl restart php8.3-fpm.service nginx.service |
| Read the first-boot log | sudo cat /var/log/limesurvey-firstboot.log |
| Read the NGINX error log | sudo tail -n 50 /var/log/nginx/error.log |
Store backups off the instance — for example aws s3 cp into a bucket in your own account — and take EBS snapshots of both data volumes on a schedule.
To upgrade LimeSurvey itself, follow the official upgrade instructions. Take a database dump and an EBS snapshot first.
Support
cloudimg provides 24/7 support via email and live chat for this image, covering deployment, configuration and day-to-day operation. We aim to respond within one business day. Contact support@cloudimg.co.uk.
LimeSurvey itself is developed by the LimeSurvey project and community; questions about survey design and LimeSurvey features are answered in the LimeSurvey manual and the community forums.