diff --git a/README.md b/README.md index b05dfe4..23f3b8d 100644 --- a/README.md +++ b/README.md @@ -447,9 +447,11 @@ script can be overriden by running the script with ## Nushell scripts -By default, the script contents are executed as either `bash` script, or `nu` script based on the extension. +By default, the script contents are executed as either `bash` script, or `nu` +script based on the extension. -You can overwrite the interpreter used to execute the script by adding an extra `#!` line to the script, for example: +You can overwrite the interpreter used to execute the script by adding an extra +`#!` line to the script, for example: ```bash #! /usr/bin/env -S haze script @@ -459,7 +461,8 @@ You can overwrite the interpreter used to execute the script by adding an extra print("Hello"); ``` -Note that the interpreter used needs to already be available inside the haze container. +Note that the interpreter used needs to already be available inside the haze +container. ## Configuration diff --git a/book/.gitignore b/book/.gitignore new file mode 100644 index 0000000..e9c0728 --- /dev/null +++ b/book/.gitignore @@ -0,0 +1 @@ +book \ No newline at end of file diff --git a/book/book.toml b/book/book.toml new file mode 100644 index 0000000..c2ab188 --- /dev/null +++ b/book/book.toml @@ -0,0 +1,4 @@ +[book] +title = "Haze" +authors = ["Robin Appelman"] +language = "en" diff --git a/book/src/README.md b/book/src/README.md new file mode 100644 index 0000000..8d340b0 --- /dev/null +++ b/book/src/README.md @@ -0,0 +1,7 @@ +# Haze + +Hazy with a chance of clouds. + +`haze` is a tool that provides provides an easy way to set up Nextcloud test +instances with a choice of php version, database server, optional s3 or ldap +setup and much more. diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md new file mode 100644 index 0000000..565c8e4 --- /dev/null +++ b/book/src/SUMMARY.md @@ -0,0 +1,11 @@ +# Summary + +[Introduction](README.md) + +- [Setup](setup.md) +- [Configuration](configuration.md) +- [Proxy](proxy/README.md) + - [DNS](proxy/dns.md) + - [HTTPS](proxy/https.md) +- [Xdebug](xdebug.md) +- [FrankenPHP (experimental)](frankenphp.md) diff --git a/book/src/configuration.md b/book/src/configuration.md new file mode 100644 index 0000000..ab42b18 --- /dev/null +++ b/book/src/configuration.md @@ -0,0 +1,272 @@ +# Configuration + +Configuration is loaded from `~/.config/haze/haze.toml`. + +The minimum required configuration needed to get started is just the +`sources_root` options. + +The full list of supported options is: + +### sources_root + +The local path of the nextcloud sources. This options is **required**. + +Type: string + +### app_directories + +A list of additional app directory paths to look for apps into + +Default `[]` + +Type: list of strings + +### work_dir + +The location where haze keeps it's temporary files and caches + +Default: `/tmp/haze` + +Type: string + +### worktree_dir + +The location to to store git worktrees when using instances with detached +sources. + +Default: `/worktrees` + +Type: string + +## auto_setup + +Options for automatically setting up the newly created Nextcloud instance. + +Examples: + +```toml +[auto_setup] +username = "foo" +password = "bar" +enable_apps = ["files_external"] +disable_apps = ["contacts"] +post_setup = [ + "occ group:add test", +] +config = { "enforce_theme" = "dark" } +``` + +```toml +[auto_setup] +enabled = false +``` + +### auto_setup.enabled + +Whether to automatically setup Nextcloud inside a created instance. + +Default: `true` + +Type: boolean + +### auto_setup.username + +The username to use for the admin account during auto setup. + +Default: `admin` + +Type: string + +### auto_setup.password + +The password to use for the admin account during auto setup. + +Default: `admin` + +Type: string + +### auto_setup.enabled_apps + +Extra apps to enable after auto setup + +Default: `[]` + +Type: list of strings + +### auto_setup.disabled_apps + +Apps to disabled after auto setup + +Default: `[]` + +Type: list of strings + +### auto_setup.post_setup + +Commands to execute after auto setup + +Default: `[]` + +Type: list of strings + +### auto_setup.config + +System configuration options to set before auto setup + +Default: `{}` + +Type: Object + +## volume + +Additional files or directories to bind-mount into instances. + +Any number of volume options can be configured + +Examples: + +```toml +[[volume]] +source = "/tmp/haze-shared" +target = "/shared" +create = true +``` + +```toml +[[volume]] +source = "/home/me/Downloads" +target = "/Downloads" +read_only = true +``` + +### volume.source + +The source path on the host + +Type: string + +### volume.target + +The target path inside the container + +Type: string + +### volume.create + +Create the source directory on the host if it doesn't exist already. + +Default: `false` + +Type: boolean + +### volume.read_only + +Whether to mount the file or directory as read read_only + +Default: `false` + +Type: boolean + +### preset + +Configured presets that can be used when creating instances. + +Any number of presets can be configured. + +Example: + +```toml +[[preset]] +name = "groupfolders" +apps = ["groupfolders"] +commands = [ + "occ groupfolders:create gf", + "occ groupfolders:group 1 admin read write share delete" +] +``` + +### preset.name + +The name of the preset, this is used when creating instances to select the +preset. + +Type: string without whitespace + +### preset.apps + +A list of apps to enable when the preset is used. + +Default: `[]` + +Type: list of strings + +### preset.commands + +A list of commands to run post-setup when the preset is used. + +Default: `[]` + +Type: list of strings + +## proxy + +Configuration for the haze proxy. Only required when using the proxy. + +```toml +[proxy] +address = "haze.example.com" +listen = "/run/haze/haze.sock" +https = true +cert = "/path/to/haze.test.crt" +key = "/path/to/haze.test.key" +``` + +### proxy.listen + +The ip and port or unix socket for the proxy to listen on. + +**Required** when the proxy is enabled. + +Type: string + +Examples: + +```toml +listen = "/run/haze/haze.sock" +``` + +```toml +listen = "127.0.0.1:8080" +``` + +### proxy.address + +The base domain the proxy is accessible on. + +**Required** if the proxy is enabled. + +Type: string + +### proxy.https + +Whether to enable built-in https support for the proxy. + +Default: `false` + +Type: boolean + +### proxy.cert + +The path of the PEM encoded certificate chain to use for https. + +**Required** if https is enabled for the proxy. + +Type: string. + +### proxy.cert + +The path of the PEM encoded private key to use for https. + +**Required** if https is enabled for the proxy. + +Type: string. diff --git a/book/src/frankenphp.md b/book/src/frankenphp.md new file mode 100644 index 0000000..ad8871f --- /dev/null +++ b/book/src/frankenphp.md @@ -0,0 +1 @@ +# FrankenPHP (experimental) diff --git a/book/src/proxy/README.md b/book/src/proxy/README.md new file mode 100644 index 0000000..5be009b --- /dev/null +++ b/book/src/proxy/README.md @@ -0,0 +1,91 @@ +# Proxy + +By default, instances can be accessed by their IP. In order to get more +memorable URLs and allow supporting https. haze comes with a builtin reverse +proxy to allow using a wildcard domain. + +## Setup + +- [Setup a DNS record](./dns.html) for `*.haze.example.com` and + `haze.example.com` pointing to your development machine. +- Set the `proxy` configuration with your domain and desired listen endpoint. +- Set up a service to run `haze proxy` in the background as your own user. A + systemd user service is recommended (see + [haze.service](<[./haze.service](https://codeberg.org/icewind/haze/src/branch/main/haze.service)>) + for an example). +- If you're already running a reverse proxy, configure your reverse proxy of + choice to proxy `*.haze.example.com` and `haze.example.com` to the proxy's + listen endpoint. +- (Optionally) [setup https](./https.html) for the proxy. + +### Configuration + +Add the following configuration to the `haze.toml` config file: + +```toml +[proxy] +address = "haze.example.com" # the base domain for the proxy to use +listen = "127.0.0.1:8080" # the port+ip to listen on +# listen = "/var/run/haze/haze.sock" # or a unix socket path +``` + +### Without a reverse proxy + +If you have no other http(s) servers on your development machine, you can setup +things without a reverse proxy. + +Simply configure the proxy to listen on port `80` (or `443` when using http). + +Binding to port 80 or443 as a regular user requires either giving the haze +binary the `net_bind_service` capability with +`sudo setcap cap_net_bind_service=+ep $(which haze)` (this will have to be done +every time your upgrade haze) or configure your system to allow unpriviled users +to bind on the low port numbers. Using +`sysctl net.ipv4.ip_unprivileged_port_start=80` and writing + +``` +net.ipv4.ip_unprivileged_port_start=80 +``` + +to `/etc/sysctl.d/bind.conf` to make it persistent across reboot. + +### With a reverse proxy + +If you're already have other http(s) services listening on your machine, you'll +probably want to setup a reverse proxy to allow them to all be served on your +machine. + +The setup for this will depend on your reverse proxy of the choice, the +following example config is for `nginx`. + +```nginx +upstream haze-handler { + server unix:/var/run/haze/haze.sock; +} + +server { + listen 80; + server_name *.haze.example.com; + + location / { + proxy_pass http://haze-handler; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +## Usage + +When the proxy is configured, generated URLs for the instances will use a +subdomain of the configured domain, e.g. the `rolling-bees` instance will be +available at `rolling-bees.haze.example.com`. Additionally, `haze.example.com` +will automatically point to the last created instance. + +Additionally, the proxy allows access to the service containers trough either +`-.haze.example.com` for a specific instance, or +`.haze.example.com` for the last created instance. For example +`rolling-bees-mail.haze.example.com` will give access to the smtp4dev web +interface of the `rolling-bees` instance. diff --git a/book/src/proxy/dns.md b/book/src/proxy/dns.md new file mode 100644 index 0000000..c0dc85d --- /dev/null +++ b/book/src/proxy/dns.md @@ -0,0 +1,27 @@ +# DNS + +Since the domain name used for the instance is dynamic, a wildcard dns record is +required. + +## With your domain's DNS provider + +If you own a domain you would like to use, you can create a wildcard domain +withing the DNS settings of your DNS provider. For example creating a record an +`A` record for `*.haze.example.com` with a value of `127.0.0.1` and a similar +one for `haze.example.com`. + +## With a local dnsmasq + +If you do not own a "real" domain for using with haze, you can setup `dnsmasq` +locally to achieve the same goal instead. + +How to install and enable `dnsmasq` will depend on your distro of choice and +should be documented by it's documentation. + +Once setup, a configuration line like + +``` +address=/haze.local/172.0.0.1 +``` + +should be enough to point `haze.local` and `*.haze.local` to your local host. diff --git a/book/src/proxy/https.md b/book/src/proxy/https.md new file mode 100644 index 0000000..0acd6c1 --- /dev/null +++ b/book/src/proxy/https.md @@ -0,0 +1,78 @@ +# HTTPS + +The proxy can be setup to enable using https to access the running instances. +Besides the warm and fuzy feeling of knowing that nobody can snoop on the trafic +that is happening completely local inside your machine. Accessing the page over +https is required for some javascript features (such as service workers), as +they are only available in "secure contexts". + +## Getting a wildcard certificate + +Since the domain name used for the instance is dynamic, a wildcard certificate +is required. + +## Let's encrypt + +Let's encrypt allows getting trusted wildcard certificates for free if you can +use DNS validation. + +How to setup DNS validation will depend on the specifics of the DNS provider and +ACME client. +[This](https://community.letsencrypt.org/t/dns-providers-who-easily-integrate-with-lets-encrypt-dns-validation/86438) +lists some DNS providers and supported ACME clients. + +## Self signed + +You can also create a self-signed wildcard certificate using a tool like +`mkcert`. This certificate will not be trusted by your browser and tools like +curl, but you can add manually add it to the trusted certificates on your +system, or bypass the certficate warning in the browser/curl every time. + +```bash +# Generate local wildcard certificate +mkcert -cert-file haze.example.com.crt -key-file haze.example.com.key '*.haze.example.com' +``` + +## Using the certificate + +### Without reverse proxy + +The haze proxy can serve over https directly, to enable that add the following +to the `[proxy]` section of your `haze.toml`. + +```toml +https = true +cert = "/path/to/haze.example.com.crt" +key = "/path/to/haze.example.com.key" +``` + +You might also want to change the port it's listening on to `443`. + +### With a reverse proxy + +This depends on what reverse proxy you have setup. The following example is for +`nginx`. + +```nginx +upstream haze-handler { + server unix:/run/haze/haze.sock; +} + +server { + listen 80; + listen 443 ssl; + http2 on; + server_name *.haze.example.com; + + ssl_certificate /haze.example.com.crt; + ssl_certificate_key /haze.example.com.key; + + location / { + proxy_pass http://haze-handler; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` diff --git a/book/src/setup.md b/book/src/setup.md new file mode 100644 index 0000000..f191167 --- /dev/null +++ b/book/src/setup.md @@ -0,0 +1,33 @@ +# Setup + +## Requirements + +- Docker + +## Installation + +- Grab a binary from the + [Codeberg releases](https://codeberg.org/icewind/haze/releases) and place it + in your `$PATH` + +## Config + +Create a file `~/.config/haze/haze.toml` with the following options: + +```toml +sources_root = "/path/to/nextcloud/sources" +``` + +See the [configuration section](./configuration.html) for more options. + +## Test the Setup + +### Quick examples + +- Start a basic Nextcloud instance: + + ```bash + haze start + ``` + +- Navigate to the address that is provided in the output. diff --git a/book/src/xdebug.md b/book/src/xdebug.md new file mode 100644 index 0000000..e0cf5e1 --- /dev/null +++ b/book/src/xdebug.md @@ -0,0 +1 @@ +# Xdebug diff --git a/flake.nix b/flake.nix index 99f9772..bde0f45 100644 --- a/flake.nix +++ b/flake.nix @@ -63,6 +63,7 @@ bacon skopeo dive + mdbook ]; homeModules = {