Stud.IP
Overview
Stud.IP is a mature open-source platform for learning management and campus management, published at studip.de and run in production by hundreds of universities and colleges across Germany and Europe. It brings the whole life of a course online. Lecturers create courses and seminars, students enroll and build a personal timetable, and each course gets its own space for documents, a forum, a wiki, a participant list, a schedule and announcements.
This SecureAnyCloud image installs Stud.IP 6.1.2 on Ubuntu 24.04 on Azure and wires it together with nginx and PHP 8.3 FPM to serve it and MariaDB 10.11 to hold every piece of platform data. Unattended security upgrades keep the server patched on your running VM.
What you get:
- Stud.IP 6.1.2 served by nginx and PHP 8.3 FPM, with the
public/directory as the only web root - MariaDB 10.11 (
mariadb.service) holding all platform data, bound to loopback - A background cronjob worker that runs every minute as a systemd timer, so notifications and scheduled tasks work out of the box
- Courses and seminars with open or application-based enrollment; per-course documents, forums, wikis, participant lists, schedules and news; a personal desktop, calendar, messaging and activity stream; Courseware for online lessons; evaluations; room booking; a full role and permission system; and LDAP/Shibboleth single sign-on
- A per-instance database password and a rotated administrator password, generated on the first boot and documented in
/root/studip-credentials.txt(0600)
One appliance, three services. nginx and php8.3-fpm serve the platform on port 80. mariadb holds every user, course, enrollment, document record, forum post and calendar entry. MariaDB is bound to 127.0.0.1:3306 and PHP FPM listens on a Unix socket, so neither is ever exposed to the network. Port 80 is the only reachable surface.
A clean web root. The document root is the application's public/ directory and nothing above it. The application source, the command-line tools, the database dumps and, above all, config/config_local.inc.php (which holds this VM's database password) live outside any URL the web server can address. Only Stud.IP's own front controllers may execute PHP, so a file placed anywhere else in the web root is refused rather than run. The browser setup wizard is removed from the image entirely.
The well-known root@studip/testing default is closed. Stud.IP normally ships a super administrator with the username root@studip and the password testing. This image ships with no schema, no administrator account and no database password at all.
On the very first boot of every VM, a one-shot service imports the schema, generates a unique database password, and rotates the seeded administrator to a unique per-instance password. The service proves through the real login form that the new password signs in and that testing, a blank password and other common guesses do not. It then writes /root/studip-credentials.txt (mode 0600, root only).
The platform cannot serve an unprovisioned instance. nginx and php8.3-fpm are each gated on a bootstrap marker that the first boot writes only after the schema is imported and the administrator is rotated. Until that marker exists, systemd skips those units entirely. There is therefore no window in which the transient root@studip/testing default is reachable on any network. The units are still enabled, so the platform comes straight back after a reboot.
Prerequisites
- An Azure subscription with permission to create resources
- An SSH key pair (run
ssh-keygen -t rsa -b 4096if you need one) - Basic familiarity with the Azure Portal or the Azure CLI
Deploy from the Azure Portal
Search the Azure Marketplace for Stud.IP Learning Management on Ubuntu 24.04 LTS by SecureAnyCloud and select Create.
Choose your subscription, resource group and region. Select the recommended size Standard_B2s (2 vCPU, 4 GB).
Set the administrator username to azureuser and provide your SSH public key.
On the Networking tab, allow inbound port 80 (HTTP) and port 22 (SSH).
Select Review + create, then Create. When the VM is running, note its public IP address.
Deploy from the Azure CLI
Accept the Marketplace terms, create a resource group and the VM, then open ports 80 and 22:
RG="studip-prod"; LOCATION="eastus"; VM_NAME="studip" IMAGE_URN="sac1647283583153:studip-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:studip-ubuntu-24-04:default:latest
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$IMAGE_URN" \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values "$SSH_KEY" \
--public-ip-sku Standard
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 80 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1002First boot and your credentials
On the first boot, the image runs these steps:
- Imports the Stud.IP schema and generates this VM's database password.
- Rotates the
root@studipadministrator to a unique password. - Opens the bootstrap gate and starts the web server.
- Verifies that the new credentials work and that
root@studip/testingis rejected. - Writes
/root/studip-credentials.txt.
This completes within a minute or two. SSH in as azureuser and read the details:
sudo cat /root/studip-credentials.txtThe file is mode 0600 and owned by root, so only a privileged user can read it. It contains the platform URL, the administrator username (root@studip) and password, and the database name, user and password.
Confirm the appliance is running
Run the commands below. All three services should report active. The ss output confirms that the platform is on port 80 while MariaDB is bound to loopback only. The response headers carry no server version banner.
systemctl is-active mariadb.service php8.3-fpm.service nginx.service php -r 'echo "PHP ".PHP_VERSION."\n";'
sudo mysql -N -e "SELECT CONCAT('MariaDB ', VERSION())" nginx -v ss -tlnp | grep -E ':(80|3306) ' | sed 's/users:.*//' | sort curl -sI http://127.0.0.1/dispatch.php/login | head -3Sign in to your platform
Browse to http://<your-server-ip>/ and sign in with the username root@studip and the password from your credentials file.
Accept the terms and reach your desktop
On your first sign-in, Stud.IP asks you to accept its terms of use. It then opens your personal desktop, the hub with your courses, your schedule, messages, announcements and quick links to every tool.
The desktop confirms that the whole stack works end to end: the web server, PHP and the database are all answering.
Change the administrator password
Open the avatar menu (top right) and go to Settings > Password to set your own password. The administrator account is the one Stud.IP calls a root user, and it can reach the whole Admin area.
You can also change any user's password from the command line:
cd /usr/local/studip printf '<new-password>\n<new-password>\n' | sudo -u www-data php cli/studip user:password root@studipAdminister the platform
Open the Admin area (the cog in the top navigation). This is where you configure your institution. From here you build out your campus:
- Create and manage user accounts and roles.
- Create institutes and course categories.
- Manage the semesters and the course catalog.
- Configure the available tools and global settings.
- Moderate content.
Create your first course
Go to Admin > Courses > New course. As a lecturer, you can use the + in the top bar instead. Give the course a name, pick a semester and a course type, and create it.
Each course opens with its own tools, which you enable per course: participants, documents and folders, a forum, a wiki, a schedule and news. Enroll participants directly, or open the course for self-enrollment with an optional access code.
The background cronjob worker
Stud.IP runs scheduled work, such as notification digests and cleanup tasks, through a cronjob worker. The image ships the worker as a systemd timer that fires every minute, so there is nothing to configure. Confirm that the timer is active:
systemctl is-active studip-cron.timer
systemctl list-timers studip-cron.timer --all --no-pagerConfigure mail so notifications and password reset work
A fresh appliance relies on the local mail transport. To send mail through your own SMTP server, set the mail options in config/config_local.inc.php.
The relevant keys are $MAIL_TRANSPORT, $MAIL_HOST, $MAIL_PORT, $MAIL_USER and $MAIL_PASSWORD. Add them for your provider at <your-domain> and clear the cache. The Stud.IP administration documentation has the full mail configuration reference.
Use your own domain and add TLS
Point an A record at your VM's public IP. Stud.IP builds absolute URLs from the request Host header, so the new hostname needs no configuration change. Then install a certificate with Certbot:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d studip.<your-domain> --redirect --agree-tos -m you@<your-domain>Certbot edits the nginx site in place and reloads it. The packaged timer renews the certificate automatically.
How the security model works
nginx and php8.3-fpm are each gated on the bootstrap marker /var/lib/sac/data/studip-bootstrap-ready, which the first boot creates only after the schema is imported, the per-instance database password is written and the root@studip account is rotated. Until then, systemd skips those units, so the transient root@studip/testing default is never reachable. Both units are still enabled, so the platform returns after a reboot. Verify the gate and the unit state:
grep -H ConditionPathExists /etc/systemd/system/{nginx,php8.3-fpm}.service.d/sac-bootstrap-gate.conf systemctl is-enabled mariadb.service php8.3-fpm.service nginx.service studip-firstboot.service studip-cron.timerThe web root is the Stud.IP public/ directory and nothing above it. config/config_local.inc.php (this VM's database password) lives above the web root. The secret configuration and the command-line tools are never reachable over HTTP. Only the named front controllers execute PHP, so the removed setup wizard and any other .php file are refused. Check the web root and probe the protected paths:
grep -E '^\s+root ' /etc/nginx/sites-available/studip for p in /config/config_local.inc.php /config/config.inc.php /install.php /cli/studip; do printf '%-32s HTTP %s\n' "$p" "$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1$p)" doneThe per-instance database password is unique to this VM, and the real login form rejects root@studip/testing and every other common guess. Exactly one administrator account exists on a fresh instance. Run the credential round trip:
sudo bash /usr/local/sbin/studip-cred-roundtrip.shBack up your platform
Stud.IP stores users, courses, enrollments, documents, forums and settings in the studip MariaDB database. Take a consistent dump at any time:
sudo mysqldump --single-transaction studip > <backup-dir>/studip-$(date +%F).sqlRestore into an empty database with mysql studip < your-dump.sql.
Keep the dump somewhere off the VM, for example in Azure Blob Storage. If you store uploaded documents on the VM, keep the contents of /usr/local/studip/data there too.
Keeping Stud.IP up to date
The OS receives unattended security updates automatically. To move to a newer Stud.IP release, follow these steps:
- Back up the database and the
data/tree. - Deploy the new release tree.
- Run
sudo -u www-data php cli/studip migrateto apply the database migrations. - Clear the cache.
Always test on a copy first. See the Stud.IP UPDATE.md for the release-specific steps.
Troubleshooting
The platform returns nothing right after boot. The first boot takes a minute or two to import the schema and rotate the credentials. Run systemctl status studip-firstboot.service to see its progress. nginx and php8.3-fpm start only once it finishes.
root@studip/testing does not work. This is by design, because the default is closed on the first boot. Use the per-instance password from sudo cat /root/studip-credentials.txt.
A page shows a database error. Confirm that MariaDB is running (systemctl status mariadb). Confirm that config/config_local.inc.php holds the per-instance password, which is written on the first boot.
Notifications or scheduled tasks are not running. Check the cronjob worker timer with systemctl list-timers studip-cron.timer --all and journalctl -u studip-cron.service.
Mail is not delivered. Configure your SMTP server in config/config_local.inc.php (Step 11) and clear the cache.
Support
SecureAnyCloud provides 24/7 technical support for this Stud.IP image by email (sales@secureanycloud.com) and live chat, with a one-hour average response time for critical issues.
We help with domain and TLS setup, user and course management, enrollment and roles, LDAP and Shibboleth single sign-on, Courseware, plugins and the API, mail delivery, the background cronjob worker, MariaDB backup and restore, performance tuning and version upgrades.
Stud.IP is free software licensed under the GNU General Public License version 2. All product and company names are trademarks or registered trademarks of their respective holders. Their use does not imply any affiliation with or endorsement by them.
Deploy on Azure
Launch Stud.IP 6.1.2 Learning Management on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com