Saaster is a CFML-based framework designed to simplify the development of SaaS applications. It is built on a modern stack, using Lucee 6, NGINX, and MySQL 8.1, and is fully containerized with Docker Compose. The architecture provides a solid foundation for building scalable SaaS platforms while keeping configuration flexible. Saaster includes core features such as user authentication, API integration, and a modular approach to extend functionality. This framework allows developers to focus on building their application's unique components without reinventing common SaaS patterns.
🌐 Website
📚 Documentation
📃 License
Saaster is organized into three primary branches to support different stages of development and deployment:
- Development: This is the default branch where new features, bug fixes, and improvements are implemented. Developers work primarily in this branch. It may contain unstable code, and its purpose is for active development and experimentation. Use this branch for contributing and testing new functionality.
- Staging: The staging branch is used to test features that have been merged from development. It mimics the production environment as closely as possible to ensure stability before release. The staging branch uses a copy of the production database for testing with live data, making it suitable for integration and acceptance testing.
- Production: The production branch contains the stable version of Saaster that is deployed to the live environment. Code is only merged into production after thorough testing in staging. This branch should always reflect the current state of the live environment and should be free from experimental or incomplete features.
To set up Saaster for local development, follow these steps. This will allow you to work on the project, make modifications, and test it in a development environment. Make sure Docker is installed and running before you begin.
1. Open a terminal and navigate to the desired folder
Choose the directory where you want to clone the project.
cd /path/to/your/folder
2. Clone the Saaster repository
git clone https://github.com/PAWECOGmbH/saaster
3. Navigate to the project folder
cd saaster
4. Configure environment variables
Copy the example environment file and modify the settings to match your local setup:
mv config/example.env .env
Update the .env file with your configuration. You can also adopt the suggestions for the local environment.
5. Copy the NGINX base settings
mv config/example.base.conf config/nginx/conf.d/base.conf
6. Set up the application configuration
Copy the example configuration file and make any necessary changes:
mv config/example.config_dev.cfm www/config.cfm
Edit www/config.cfm to suit your development environment.
Note: If you change the config.cfm file after the first start of the application, you need to reload the application scope:
http://localhost:8080?reinit=1
7. Start the containers
Use Docker Compose to start the development environment:
docker compose -f compose-dev.yml up
8. Configure Lucee
Access the Lucee admin interface:
- URL:
http://localhost:8080/lucee/admin/server.cfm - Steps:
- Set up the database connection (important: Make sure to enable 'Allow Multiple Queries.')
- Configure SMTP (you can use Inbucket for local email handling).
- Adjust any additional settings required for your development setup.
9. Set up Saaster
Run the setup script to initialize Saaster:
- URL:
http://localhost:8080/setup/index.cfm - Work your way through the wizard.
- Complete the registration; the first registration creates the Sysadmin account.
- Access Inbucket (local email client) at
http://localhost:9000to view any emails.
If you want to load test data into your database:
- In the folder
config/db/dev/, you'll find SQL files with demo data. They contain data only - the tables come from the migrations - and can be imported again at any time (they replace their own records). Import them in this order:
| File | Content |
|---|---|
create-plans.sql |
One plan group with four plans (Free, Standard, Advanced, Enterprise), features and prices in USD, EUR and CHF (CHF with 8.1% VAT) |
create-modules.sql |
Three modules: a free Todo app, Easy ERP (monthly/yearly, 30 test days), MailChimp API (one-time, 10 test days) |
create-widgets.sql |
Five dashboard widgets: shown to everybody, only with a module, only with certain plans, deactivated (replaces widgets 1-5) |
create-customers.sql |
Eleven demo companies with users, active, test, free, canceled, expired and waiting bookings, invoices in every status, payments, payment methods and tenants |
create-notifications.sql |
Notifications for the first account (customer 1, user 1) |
for f in create-plans create-modules create-widgets create-customers create-notifications; do
cat ./config/db/dev/$f.sql | docker exec -i {MYSQL_CONTAINER_NAME} mysql -u {MYSQL_USER} -p{MYSQL_PASSWORD} {MYSQL_DATABASE}
done
All demo users log in with the password Saaster-Demo-2026!, e.g. anna.meier@alpine-bakery.example (German, Standard plan) or oliver.smith@brightpixel.example (English, overdue invoice). The list of companies and what each of them shows is at the top of create-customers.sql.
Replace the following placeholders:
{MYSQL_CONTAINER_NAME}: The name of your MySQL container.{MYSQL_USER}: Your MySQL user.{MYSQL_PASSWORD}: Your MySQL password (ensure no space after -p).{MYSQL_DATABASE}: Your MySQL database name.
- You can also import mock customers and invoices:
- URL:
http://localhost:8080/setup/mockdata/index.cfm
After configuring Lucee and Saaster, you may want to create a custom Docker image to preserve your settings:
-
Stop the Lucee container:
docker stop <lucee_container_name> -
Commit the container to create an image:
docker commit <lucee_container_name> <your_image_name>:version
Example:docker commit lucee_container saaster:20241002 -
Remove the old container:
docker container rm <lucee_container_name> -
Update your
.envfile with the new image name:
LUCEE_IMAGE=saaster:20241002 -
Restart the container with your saved image:
docker compose -f compose-dev.yml up -d
Saaster comes with a TestBox test workspace in www/tests. The specs run inside your local Lucee container against a dedicated test database (saaster_test_db), never against your development database. With the dev stack running, set it up once from the repository root:
bash www/tests/bin/install_test_dependencies.sh
bash www/tests/bin/prepare_test_db.sh
Then run the specs in the browser at http://localhost:8080/tests/runner.cfm or from the shell:
bash www/tests/bin/run_tests.sh "reporter=mintext"
The test application only starts when config.cfm is set to variables.environment = "dev". Details and how to write your own specs: www/tests/README.md
For production deployment, Saaster can be run on an Ubuntu server using Docker. This setup ensures a stable and scalable environment. A detailed guide on how to configure the server, set up Docker, and deploy Saaster in a live environment can be found in the official documentation:
- Production Setup Guide: coming soon
Production and staging use the same compose.yml. Optional services have a Compose profile and only start when the profile is listed in COMPOSE_PROFILES of the server's .env:
| Server | .env |
Started by docker compose up -d |
|---|---|---|
| Production | COMPOSE_PROFILES=filebrowser |
Lucee, MySQL, File Browser |
| Staging | nothing (or COMPOSE_PROFILES= empty) |
Lucee, MySQL |
To check what a server would start: docker compose config --services
The File Browser variables (FILEBROWSER_PORT, FILEBROWSER_CONTAINER_NAME) are only needed where the File Browser runs - Compose validates every service, so compose.yml has defaults for them.
When you remove a profile from a server where its service is already running (e.g. the File Browser on staging), stop and remove that container once - Compose leaves it running otherwise:
docker compose stop filebrowser
docker compose rm filebrowser
We welcome contributions from developers to help improve Saaster. Whether it's fixing bugs, adding new features, or improving documentation, contributions are highly appreciated. Follow the steps below to get started:
-
Fork the repository
First, fork the Saaster repository to your GitHub account. -
Clone your fork
Clone your forked repository to your local machine:
git clone https://github.com/{your-username}/saaster
cd saaster -
Create a new branch
Always create a new branch for your changes to keep things organized:
git checkout -b feature/your-feature-name -
Make your changes
Implement your changes and commit them with a clear and concise commit message:
git add .
git commit -m "Add feature description" -
Push your branch
Push your branch to your forked repository:
git push origin feature/your-feature-name -
Create a pull request
Go to the Saaster repository on GitHub and create a pull request from your forked repository. Ensure your pull request clearly describes the changes and why they are necessary.
- Code style: Follow the existing code style of the project.
- Testing: Ensure that your changes do not break any existing functionality. Run the test suite (see Testing) and add specs where applicable.
- Documentation: If your changes affect functionality, please update the relevant documentation.
For more information or if you're unsure about something, feel free to open an issue or ask for guidance on an existing one.
- Tabler
- Dropify
- Hugerte
- Bootstrap
- MockDataCFC
- Fontawesome
- jquery
- taffy
- Bouncy Castle (Argon2 password hashing,
www/assets/java)
