-
-
Notifications
You must be signed in to change notification settings - Fork 0
Add a first draft of user documentation #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| hosts: | ||
| - host: local | ||
| dozzle: https://logs.localhost/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| #!/usr/bin/env sh | ||
|
|
||
| # Download the database dump from the latest GitHub workflow | ||
| # Usage: ./backup_download.sh [workflow_id] | ||
|
|
||
| set -eux | ||
|
|
||
| workflow_id="${1:-$(gh api "repos/{owner}/{repo}/actions/runs" | jq -r '.workflow_runs[] | select(.name == "Backup" and .conclusion == "success") | .id' | sed 's/"//g' | head -n 1)}" | ||
|
|
||
| gh run download "$workflow_id" -n backup.dump |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #!/usr/bin/env sh | ||
|
|
||
| # Restore the PostgreSQL database from a dump file | ||
| # Usage: ./backup_restore.sh [dump_file] [database_name] [num_jobs] | ||
|
|
||
| set -eux | ||
|
|
||
| dump_file="${1:-backup.dump}" | ||
| database_name="${2:-postgres}" | ||
| num_jobs="${3:-$(getconf _NPROCESSORS_ONLN)}" | ||
|
|
||
| pg_restore "$dump_file" -d "$database_name" --no-acl --no-owner --no-privileges -j "$num_jobs" --disable-triggers |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| services: | ||
| web: | ||
| memswap_limit: 1g # Limit total memory usage (RAM + swap) to 1GB | ||
| deploy: | ||
| mode: replicated | ||
| replicas: 2 | ||
| resources: | ||
| limits: | ||
| cpus: '0.25' # Limit to 25% of a CPU | ||
| memory: 512M # Limit to 512MB of RAM | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,21 @@ | ||||||
| # freePaaS | ||||||
|
|
||||||
| freePaaS is an open-source platform-as-a-service (PaaS) solution that enables developers to easily deploy, manage, and scale applications in a cloud environment. It provides a user-friendly interface and a variety of tools to streamline the application lifecycle, from development to production. | ||||||
|
|
||||||
| ## Features | ||||||
|
|
||||||
| - [Easy Deployment](deployment.md): Deploy applications with just a few clicks. | ||||||
| - [Scalability](scaling.md): Automatically scale applications based on demand. | ||||||
| - [Monitoring](monitoring.md): Keep track of application performance and health. | ||||||
| - [Environment Management](enviroment.md): Manage configuration and environment variables effectively. | ||||||
|
||||||
| - [Environment Management](enviroment.md): Manage configuration and environment variables effectively. | |
| - [Environment Management](environment.md): Manage configuration and environment variables effectively. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Backups | ||
|
|
||
| ## Database backups | ||
|
|
||
| PostgreSQL backups are captured daily using [pg_dump](https://www.postgresql.org/docs/current/app-pgdump.html) and stored as repository artifacts in GitHub Actions. | ||
|
|
||
| ### Durability | ||
|
|
||
| By default, GitHub retains workflow artifacts for 90 days. You can [adjust the retention period](https://docs.github.com/en/organizations/managing-organization-settings/configuring-the-retention-period-for-github-actions-artifacts-and-logs-in-your-organization) up to a maximum of 400 days. | ||
|
|
||
| Importantly, artifacts are stored independently of your application server, ensuring that backups remain safe even if your server fails. | ||
|
|
||
| The backup frequency may be altered in the [`.github/workflows/backup.yml`](../.github/workflows/backup.yml) file. Here you may also configure additional backup targets, such as cloud storage providers. | ||
|
|
||
| ### Restoration | ||
|
|
||
| To restore a backup, download the desired artifact from the GitHub Actions workflow run history. The artifact will be a compressed file containing the SQL dump. | ||
|
|
||
| You can restore the database using the built-in database scripts: | ||
|
|
||
| ```bash | ||
| bin/backup_download.sh | ||
| bin/backup_restore.sh | ||
| ``` | ||
|
|
||
| > [!NOTE] | ||
| > Backups are stored in PostgreSQL's [custom format](https://www.postgresql.org/docs/current/app-pgdump.html) which is compressed and allows for more flexible restoration options. | ||
|
|
||
| ### Privacy | ||
|
|
||
| With backups being stored on GitHub, it's crucial to consider the sensitivity of your data. Ensure that your repository is private to prevent unauthorized access to your backups. Additionally, consider encrypting your database dumps before uploading them as artifacts for an added layer of security. | ||
|
|
||
| > [!IMPORTANT] | ||
| > If you are serving customers in the EU, ensure that you add GitHub as a data processor in your privacy policy to comply with GDPR regulations. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Deployment | ||
|
|
||
| Deploying your application with freePaaS is a streamlined process that involves running an installation script and leveraging GitHub Actions for continuous deployment. | ||
|
|
||
| ## Initial Setup | ||
|
|
||
| The primary setup is handled by an interactive script. To start the installation wizard, run the following command from the root of the repository: | ||
|
|
||
| ```bash | ||
| ./bin/install.sh | ||
| ``` | ||
|
|
||
| This script will guide you through the following steps: | ||
|
|
||
| 1. **Domain Configuration**: You will be prompted to enter your domain name. | ||
| 1. **Server Access**: The script will verify SSH access to your server. | ||
| 1. **GitHub Integration**: It will help you create a GitHub OAuth App for secure authentication. | ||
| 1. **Repository Configuration**: The script will set up the necessary GitHub repository secrets and variables to enable automated deployments. These include: | ||
| - `SSH_HOSTNAME`: Your server's hostname or IP address. | ||
| - `SSH_PRIVATE_KEY`: A private SSH key for accessing the server. | ||
| - `SSH_KNOWN_HOSTS`: Your server's SSH host key. | ||
|
|
||
| ## Continuous Deployment | ||
|
|
||
| Once the initial setup is complete, your application will be automatically deployed whenever you push changes to the `main` branch. This is handled by the [`.github/workflows/deploy.yml`](../.github/workflows/deploy.yml) GitHub Actions workflow. | ||
|
|
||
| The deployment workflow performs the following steps: | ||
|
|
||
| 1. **Trigger**: The workflow is triggered by a push to the `main` branch (after the `ci` workflow succeeds) or can be triggered manually. | ||
| 1. **Environment Setup**: It sets up an SSH connection to your production server using the configured secrets. | ||
| 1. **Remote Deployment**: It establishes a remote Docker context to your server. | ||
| 1. **Application Start**: It uses `docker compose` to pull the latest images and start the application containers. | ||
|
|
||
| Your application will be served via a Caddy reverse proxy, which also handles automatic SSL certificate provisioning. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # Environment | ||
|
||
|
|
||
| [12-factor] apps are designed to be portable and resilient by strictly separating configuration from code. This approach allows applications to adapt seamlessly across different environments, such as development, staging, and production. | ||
|
|
||
| Your environment variables are stored on GitHub in your repository. | ||
|
|
||
| ## Default runtime variables | ||
|
|
||
| The default variables are set: | ||
|
|
||
| - `HOSTNAME`: The hostname of your application. | ||
| - `DATABASE_URL`: The URL for your database connection. | ||
| - `REDIS_URL`: The URL for your Redis instance. | ||
| - `EMAIL_URL`: The URL to your SMTP relay instance. | ||
|
|
||
| ## Managing variables | ||
|
|
||
| GitHub can store multiple environments for a single repository. Each environment can have its own set of variables and secrets. You can create environments such as `development`, `staging`, and `production` to manage different configurations for each stage of your application lifecycle. | ||
|
|
||
| If your workflow targets a specific environment, GitHub Actions will automatically load the corresponding variables and secrets for that environment during the workflow run. | ||
|
|
||
| > [!IMPORTANT] | ||
| > GitHub will inherit secrets from the repository level to the environment level, but not the other way around. Be cautious when naming secrets at both levels to avoid unintentional overrides. Environment-level secrets will take precedence over repository-level secrets with the same name. | ||
|
|
||
| ### Variables | ||
|
|
||
| Variables are stored in plain text and retrievable. | ||
|
|
||
| ```bash | ||
| # With body | ||
| gh variable set VARIABLE_NAME --env production --body "variable_value" | ||
| # from file | ||
| gh variable set VARIABLE_NAME --env production <path/to/file | ||
| ``` | ||
|
|
||
| ### Secrets | ||
|
|
||
| Secrets are securely stored and non-retrievable. | ||
|
|
||
| ```bash | ||
| # With body | ||
| gh secret set SECRET_NAME --env production --body "variable_value" | ||
| # from file | ||
| gh secret set SECRET_NAME --env production <path/to/file | ||
| # create a random secret | ||
| python -c "import secrets; print(secrets.token_urlsafe())" | gh secret set SECRET_NAME --env production | ||
| ``` | ||
|
|
||
| [12-factor]: https://12factor.net/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # Monitoring | ||
|
|
||
| Monitoring is a crucial aspect of managing applications deployed on freePaaS. It allows developers and administrators to keep track of application performance, resource usage, and overall health. freePaaS provides built-in monitoring tools that offer insights into various metrics, enabling proactive management and troubleshooting. | ||
|
|
||
| ## Built-in Monitoring Tools | ||
|
|
||
| freePaaS integrates [Dozzle] and [dtop] to provide real-time monitoring and logging capabilities. | ||
|
|
||
| To access the monitoring tools, navigate to the following URLs in your web browser: | ||
|
|
||
| - Dozzle: `http://logs.<your-domain>` | ||
|
|
||
| To access via shell, use the following commands: | ||
|
|
||
| ```bash | ||
| dtop | ||
| ``` | ||
|
|
||
| The bootstrap script creates a `.dtop.yml` configuration file for your project with production and development contexts. | ||
|
|
||
| ## Application Monitoring | ||
|
|
||
| freePaaS provides only basic monitoring tools out of the box to help you assess your container health. For more advanced monitoring, logging, and alerting capabilities, consider integrating third-party services such as [Sentry]. | ||
|
||
|
|
||
| [dozzle]: https://dozzle.dev/ | ||
| [dtop]: https://dtop.dev/ | ||
| [sentry]: https://sentry.io/welcome/ | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,60 @@ | ||||||
| # Scaling | ||||||
|
|
||||||
| freePaaS allows you to start small and scale your applications as they grow in popularity. There are multiple ways to progressively scale your applications depending on your needs without breaking the bank. | ||||||
|
|
||||||
| ## Scaling services | ||||||
|
|
||||||
| freePaaS defaults to a highly available web server setup with a minimum of two web servers behind a load balancer. This allows your application to handle more traffic and provides redundancy in case one of the web servers goes down. | ||||||
|
|
||||||
| You can easily add more web servers to your application by simply adding more containers to the `web` service in your `compose.yml` file. | ||||||
|
|
||||||
| ```yaml | ||||||
| services: | ||||||
| web: | ||||||
| deploy: | ||||||
| replicas: 3 # Increase the number of replicas | ||||||
| ``` | ||||||
|
|
||||||
| You may also scale ad-hoc using the Docker CLI: | ||||||
|
|
||||||
| ```bash | ||||||
| docker service scale web=5 # Scale to 5 replicas | ||||||
| ``` | ||||||
|
|
||||||
| ### Resource management | ||||||
|
|
||||||
| You can also limit the resources used by each service in your [`containers/web/compose.yml`](../containers/web/compose.yml) file. This allows you to control the amount of CPU and memory used by each service. | ||||||
|
|
||||||
| ```yaml | ||||||
| services: | ||||||
| web: | ||||||
| memswap_limit: 1g # Limit total memory + swap to 1GB | ||||||
| deploy: | ||||||
| resources: | ||||||
| limits: | ||||||
| cpus: '0.50' # Limit to 50% of a CPU | ||||||
| memory: 512M # Limit to 512MB of RAM | ||||||
| reservations: | ||||||
| cpus: '0.25' # Reserve 25% of a CPU | ||||||
| memory: 256M # Reserve 256MB of RAM | ||||||
| ``` | ||||||
|
|
||||||
| > [!IMPORTANT] | ||||||
| > Setting resource limits is important to prevent a single service from consuming all available resources on the server, which could lead to performance degradation or crashes. You MUST always set `memswap_limit` to prevent services from using swap space. Swapping will prevent OOM (out of memory) restarts. | ||||||
|
|
||||||
| ## Long term growth strategies | ||||||
|
|
||||||
| ### Scaling Vertically | ||||||
|
|
||||||
| Most datacenters will offer VPS or dedicated servers in a variety of sizes and the ability to upgrade an existing server to a larger size. This is known as vertical scaling or scaling up. | ||||||
|
|
||||||
| This will probably be the easiest way to scale your application, especially if you are just starting out. Simply upgrade your server to a larger size and freePaaS will automatically take advantage of the additional resources. | ||||||
|
|
||||||
| ### Scaling Horizontally | ||||||
|
|
||||||
| When your application outgrows the resources of a single server, you can just add a second one. Docker [Swarm mode](https://docs.docker.com/engine/swarm/) is low effort way to just add more servers to your PaaS. Setup takes minutes and freePaaS will automatically distribute your applications across the available servers. | ||||||
|
||||||
| When your application outgrows the resources of a single server, you can just add a second one. Docker [Swarm mode](https://docs.docker.com/engine/swarm/) is low effort way to just add more servers to your PaaS. Setup takes minutes and freePaaS will automatically distribute your applications across the available servers. | |
| When your application outgrows the resources of a single server, you can just add a second one. Docker [Swarm mode](https://docs.docker.com/engine/swarm/) is a low-effort way to just add more servers to your PaaS. Setup takes minutes and freePaaS will automatically distribute your applications across the available servers. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # File Storage | ||
|
|
||
| freePaaS doesn't offer built-in file storage solutions by default. | ||
|
|
||
| Secure storage is a complex topic with many considerations. We recommend using specialized third-party services that are designed to handle file storage securely and efficiently. All major cloud providers offer object storage solutions (compatible with AWS S3) that can be easily integrated into your application. | ||
|
|
||
| > [!IMPORTANT] | ||
| > Web containers in freePaaS are designed to be stateless, meaning that any files stored locally within the container will be lost if the container is restarted or redeployed. Therefore, it's crucial to use external storage solutions for any files that need to persist beyond the lifecycle of a single container instance. | ||
|
|
||
| ## Local storage (not recommended) | ||
|
|
||
| If you still want to use local storage for development or testing purposes, you can mount a volume to your web container by modifying the `volumes` section in the [`containers/web/compose.yml`](../containers/web/compose.yml) file. | ||
|
|
||
| ```yaml | ||
| services: | ||
| web: | ||
| volumes: | ||
| - /path/on/host:/path/in/container:z | ||
| ``` | ||
|
|
||
| This will mount the specified host directory to the container, allowing files to persist across container restarts. However, be aware that this approach may lead to data loss and performance issues in a production environment. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment states "Limit to 50% of a CPU" but the actual value is '0.25' which limits to 25% of a CPU. The comment should say "Limit to 25% of a CPU" to match the configured value.