aboutsummaryrefslogtreecommitdiff
path: root/doc/book
diff options
context:
space:
mode:
Diffstat (limited to 'doc/book')
-rw-r--r--doc/book/src/SUMMARY.md17
-rw-r--r--doc/book/src/cookbook/clients.md13
-rw-r--r--doc/book/src/cookbook/from_source.md51
-rw-r--r--doc/book/src/cookbook/index.md20
-rw-r--r--doc/book/src/cookbook/real_world.md272
-rw-r--r--doc/book/src/cookbook/systemd.md39
-rw-r--r--doc/book/src/cookbook/website.md2
-rw-r--r--doc/book/src/getting_started/01_binary.md44
-rw-r--r--doc/book/src/getting_started/02_test_deployment.md107
-rw-r--r--doc/book/src/getting_started/03_real_world_deployment.md154
-rw-r--r--doc/book/src/getting_started/04_control.md75
-rw-r--r--doc/book/src/getting_started/05_cluster.md82
-rw-r--r--doc/book/src/getting_started/06_bucket.md74
-rw-r--r--doc/book/src/getting_started/07_files.md45
-rw-r--r--doc/book/src/getting_started/index.md5
-rw-r--r--doc/book/src/quick_start/index.md266
16 files changed, 669 insertions, 597 deletions
diff --git a/doc/book/src/SUMMARY.md b/doc/book/src/SUMMARY.md
index b88ebb4c..659f880e 100644
--- a/doc/book/src/SUMMARY.md
+++ b/doc/book/src/SUMMARY.md
@@ -2,20 +2,17 @@
[The Garage Data Store](./intro.md)
-- [Getting Started](./getting_started/index.md)
- - [Get a binary](./getting_started/01_binary.md)
- - [Configuring a test deployment](./getting_started/02_test_deployment.md)
- - [Configure a real-world deployment](./getting_started/03_real_world_deployment.md)
- - [Control the daemon](./getting_started/04_control.md)
- - [Configure a cluster](./getting_started/05_cluster.md)
- - [Create buckets and keys](./getting_started/06_bucket.md)
- - [Handle files](./getting_started/07_files.md)
+- [Quick start](./quick_start/index.md)
- [Cookbook](./cookbook/index.md)
- - [Host a website](./cookbook/website.md)
+ - [Deploying Garage](./cookbook/real_world.md)
+ - [Configuring S3 clients](./cookbook/clients.md)
+ - [Hosting a website](./cookbook/website.md)
+ - [Recovering from failures](./cookbook/recovering.md)
+ - [Building from source](./cookbook/from_source.md)
+ - [Starting with Systemd](./cookbook/systemd.md)
- [Integrate as a media backend]()
- [Operate a cluster]()
- - [Recovering from failures](./cookbook/recovering.md)
- [Reference Manual](./reference_manual/index.md)
- [Garage configuration file](./reference_manual/configuration.md)
diff --git a/doc/book/src/cookbook/clients.md b/doc/book/src/cookbook/clients.md
new file mode 100644
index 00000000..006f604a
--- /dev/null
+++ b/doc/book/src/cookbook/clients.md
@@ -0,0 +1,13 @@
+# Configuring S3 clients to interact with Garage
+
+## AWS CLI
+
+## Minio client
+
+## `rclone`
+
+## Cyberduck
+
+## `s3cmd`
+
+
diff --git a/doc/book/src/cookbook/from_source.md b/doc/book/src/cookbook/from_source.md
new file mode 100644
index 00000000..167f01db
--- /dev/null
+++ b/doc/book/src/cookbook/from_source.md
@@ -0,0 +1,51 @@
+# Compiling Garage from source
+
+
+Garage is a standard Rust project.
+First, you need `rust` and `cargo`.
+For instance on Debian:
+
+```bash
+sudo apt-get update
+sudo apt-get install -y rustc cargo
+```
+
+You can also use [Rustup](https://rustup.rs/) to setup a Rust toolchain easily.
+
+## Using source from `crates.io`
+
+Garage's source code is published on `crates.io`, Rust's official package repository.
+This means you can simply ask `cargo` to download and build this source code for you:
+
+```bash
+cargo install garage
+```
+
+That's all, `garage` should be in `$HOME/.cargo/bin`.
+
+You can add this folder to your `$PATH` or copy the binary somewhere else on your system.
+For instance:
+
+```bash
+sudo cp $HOME/.cargo/bin/garage /usr/local/bin/garage
+```
+
+
+## Using source from the Gitea repository
+
+The primary location for Garage's source code is the
+[Gitea repository](https://git.deuxfleurs.fr/Deuxfleurs/garage).
+
+Clone the repository and build Garage with the following commands:
+
+```bash
+git clone https://git.deuxfleurs.fr/Deuxfleurs/garage.git
+cd garage
+cargo build
+```
+
+Be careful, as this will make a debug build of Garage, which will be extremely slow!
+To make a release build, invoke `cargo build --release` (this takes much longer).
+
+The binaries built this way are found in `target/{debug,release}/garage`.
+
diff --git a/doc/book/src/cookbook/index.md b/doc/book/src/cookbook/index.md
index 26ec68bb..a838b549 100644
--- a/doc/book/src/cookbook/index.md
+++ b/doc/book/src/cookbook/index.md
@@ -3,3 +3,23 @@
A cookbook, when you cook, is a collection of recipes.
Similarly, Garage's cookbook contains a collection of recipes that are known to works well!
This chapter could also be referred as "Tutorials" or "Best practices".
+
+- **[Deploying Garage](real_world.md):** This page will walk you through all of the necessary
+ steps to deploy Garaage in a real-world setting.
+
+- **[Configuring S3 clients](clients.md):** This page will explain how to configure
+ popular S3 clients to interact with a Garage server.
+
+- **[Hosting a website](website.md):** This page explains how to use Garage
+ to host a static website.
+
+- **[Recovering from failures](recovering.md):** Garage's first selling point is resilience
+ to hardware failures. This section explains how to recover from such a failure in the
+ best possible way.
+
+- **[Building from source](from_source.md):** This page explains how to build Garage from
+ source in case a binary is not provided for your architecture, or if you want to
+ hack with us!
+
+- **[Starting with Systemd](from_source.md):** This page explains how to run Garage
+ as a Systemd service (instead of as a Docker container).
diff --git a/doc/book/src/cookbook/real_world.md b/doc/book/src/cookbook/real_world.md
new file mode 100644
index 00000000..abef8912
--- /dev/null
+++ b/doc/book/src/cookbook/real_world.md
@@ -0,0 +1,272 @@
+# Deploying Garage on a real-world cluster
+
+To run Garage in cluster mode, we recommend having at least 3 nodes.
+This will allow you to setup Garage for three-way replication of your data,
+the safest and most available mode avaialble.
+
+We recommend first following the [quick start guide](../quick_start/index.md) in order
+to get familiar with Garage's command line and usage patterns.
+
+## Get a Docker image
+
+Our docker image is currently named `lxpz/garage_amd64` and is stored on the [Docker Hub](https://hub.docker.com/r/lxpz/garage_amd64/tags?page=1&ordering=last_updated).
+We encourage you to use a fixed tag (eg. `v0.3.0`) and not the `latest` tag.
+For this example, we will use the latest published version at the time of the writing which is `v0.3.0` but it's up to you
+to check [the most recent versions on the Docker Hub](https://hub.docker.com/r/lxpz/garage_amd64/tags?page=1&ordering=last_updated).
+
+For example:
+
+```
+sudo docker pull lxpz/garage_amd64:v0.3.0
+```
+
+
+## Generating TLS certificates
+
+You first need to generate TLS certificates to encrypt traffic between Garage nodes
+(reffered to as RPC traffic).
+
+To generate your TLS certificates, run on your machine:
+
+```
+wget https://git.deuxfleurs.fr/Deuxfleurs/garage/raw/branch/main/genkeys.sh
+chmod +x genkeys.sh
+./genkeys.sh
+```
+
+It will creates a folder named `pki/` containing the keys that you will used for the cluster.
+
+
+## Deploying and configuring Garage
+
+To run a real-world deployment, make sure you the following conditions are met:
+
+- You have at least three machines with sufficient storage space available
+
+- Each machine has a public IP address which is reachable by other machines.
+ Running behind a NAT is possible, but having several Garage nodes behind a single NAT
+ is slightly more involved as each will have to have a different RPC port number
+ (the local port number of a node must be the same as the port number exposed publicly
+ by the NAT).
+
+- Ideally, each machine should have a SSD available in addition to the HDD you are dedicating
+ to Garage. This will allow for faster access to metadata and has the potential
+ to drastically reduce Garage's response times.
+
+Before deploying garage on your infrastructure, you must inventory your machines.
+For our example, we will suppose the following infrastructure with IPv6 connectivity:
+
+| Location | Name | IP Address | Disk Space |
+|----------|---------|------------|------------|
+| Paris | Mercury | fc00:1::1 | 1 To |
+| Paris | Venus | fc00:1::2 | 2 To |
+| London | Earth | fc00:B::1 | 2 To |
+| Brussels | Mars | fc00:F::1 | 1.5 To |
+
+
+On each machine, we will have a similar setup,
+especially you must consider the following folders/files:
+
+ - `/etc/garage/garage.toml`: Garage daemon's configuration (see below)
+ - `/etc/garage/pki/`: Folder containing Garage certificates, must be generated on your computer and copied on the servers
+ - `/var/lib/garage/meta/`: Folder containing Garage's metadata, put this folder on a SSD if possible
+ - `/var/lib/garage/data/`: Folder containing Garage's data, this folder will grows and must be on a large storage, possibly big HDDs.
+ - `/etc/systemd/system/garage.service`: Service file to start garage at boot automatically (defined below, not required if you use docker)
+
+A valid `/etc/garage/garage.toml` for our cluster would be:
+
+```toml
+metadata_dir = "/var/lib/garage/meta"
+data_dir = "/var/lib/garage/data"
+
+replication_mode = "3"
+
+rpc_bind_addr = "[::]:3901"
+
+bootstrap_peers = [
+ "[fc00:1::1]:3901",
+ "[fc00:1::2]:3901",
+ "[fc00:B::1]:3901",
+ "[fc00:F::1]:3901",
+]
+
+[rpc_tls]
+ca_cert = "/etc/garage/pki/garage-ca.crt"
+node_cert = "/etc/garage/pki/garage.crt"
+node_key = "/etc/garage/pki/garage.key"
+
+[s3_api]
+s3_region = "garage"
+api_bind_addr = "[::]:3900"
+
+[s3_web]
+bind_addr = "[::]:3902"
+root_domain = ".web.garage"
+index = "index.html"
+```
+
+Please make sure to change `bootstrap_peers` to **your** IP addresses!
+
+Check the [configuration file reference documentation](../reference_manual/configuration.md)
+to learn more about all available configuration options.
+
+
+## Starting Garage using Docker
+
+On each machine, you can run the daemon with:
+
+```bash
+docker run \
+ -d \
+ --name garaged \
+ --restart always \
+ --network host \
+ -v /etc/garage/pki:/etc/garage/pki \
+ -v /etc/garage/garage.toml:/garage/garage.toml \
+ -v /var/lib/garage/meta:/var/lib/garage/meta \
+ -v /var/lib/garage/data:/var/lib/garage/data \
+ lxpz/garage_amd64:v0.3.0
+```
+
+It should be restart automatically at each reboot.
+Please note that we use host networking as otherwise Docker containers
+can not communicate with IPv6.
+
+Upgrading between Garage versions should be supported transparently,
+but please check the relase notes before doing so!
+To upgrade, simply stop and remove this container and
+start again the command with a new version of garage.
+
+
+## Controling the daemon
+
+The `garage` binary has two purposes:
+ - it acts as a daemon when launched with `garage server ...`
+ - it acts as a control tool for the daemon when launched with any other command
+
+In this section, we will see how to use the `garage` binary as a control tool for the daemon we just started.
+You first need to get a shell having access to this binary. For instance, enter the Docker container with:
+
+```bash
+sudo docker exec -ti garaged bash
+```
+
+You will now have a shell where the Garage binary is available as `/garage/garage`
+
+*You can also install the binary on your machine to remotely control the cluster.*
+
+## Talk to the daemon and create an alias
+
+`garage` requires 4 options to talk with the daemon:
+
+```
+--ca-cert <ca-cert>
+--client-cert <client-cert>
+--client-key <client-key>
+-h, --rpc-host <rpc-host>
+```
+
+The 3 first ones are certificates and keys needed by TLS, the last one is simply the address of garage's RPC endpoint.
+
+If you are invoking `garage` from a server node directly, you do not need to set `--rpc-host`
+as the default value `127.0.0.1:3901` will allow it to contact Garage correctly.
+
+To avoid typing the 3 first options each time we want to run a command,
+you can use the following alias:
+
+```bash
+alias garagectl='/garage/garage \
+ --ca-cert /etc/garage/pki/garage-ca.crt \
+ --client-cert /etc/garage/pki/garage.crt \
+ --client-key /etc/garage/pki/garage.key'
+```
+
+You can now use all of the commands presented in the [quick start guide](../quick_start/index.md),
+simply replace occurences of `garage` by `garagectl`.
+
+#### Test the alias
+
+You can test your alias by running a simple command such as:
+
+```
+garagectl status
+```
+
+You should get something like that as result:
+
+```
+Healthy nodes:
+2a638ed6c775b69a… 37f0ba978d27 [::ffff:172.20.0.101]:3901 UNCONFIGURED/REMOVED
+68143d720f20c89d… 9795a2f7abb5 [::ffff:172.20.0.103]:3901 UNCONFIGURED/REMOVED
+8781c50c410a41b3… 758338dde686 [::ffff:172.20.0.102]:3901 UNCONFIGURED/REMOVED
+```
+
+
+## Configuring a cluster
+
+We will now inform garage of the disk space available on each node of the cluster
+as well as the zone (e.g. datacenter) in which each machine is located.
+
+For our example, we will suppose we have the following infrastructure (Capacity, Identifier and Datacenter are specific values to garage described in the following):
+
+| Location | Name | Disk Space | `Capacity` | `Identifier` | `Zone` |
+|----------|---------|------------|------------|--------------|--------------|
+| Paris | Mercury | 1 To | `2` | `8781c5` | `par1` |
+| Paris | Venus | 2 To | `4` | `2a638e` | `par1` |
+| London | Earth | 2 To | `4` | `68143d` | `lon1` |
+| Brussels | Mars | 1.5 To | `3` | `212f75` | `bru1` |
+
+#### Node identifiers
+
+After its first launch, garage generates a random and unique identifier for each nodes, such as:
+
+```
+8781c50c410a41b363167e9d49cc468b6b9e4449b6577b64f15a249a149bdcbc
+```
+
+Often a shorter form can be used, containing only the beginning of the identifier, like `8781c5`,
+which identifies the server "Mercury" located in "Paris" according to our previous table.
+
+The most simple way to match an identifier to a node is to run:
+
+```
+garagectl status
+```
+
+It will display the IP address associated with each node; from the IP address you will be able to recognize the node.
+
+#### Zones
+
+Zones are simply a user-chosen identifier that identify a group of server that are grouped together logically.
+It is up to the system administrator deploying garage to identify what does "grouped together" means.
+
+In most cases, a zone will correspond to a geographical location (i.e. a datacenter).
+Behind the scene, Garage will use zone definition to try to store the same data on different zones,
+in order to provide high availability despite failure of a zone.
+
+#### Capacity
+
+Garage reasons on an arbitrary metric about disk storage that is named the *capacity* of a node.
+The capacity configured in Garage must be proportional to the disk space dedicated to the node.
+Additionaly, the capacity values used in Garage should be as small as possible, with
+1 ideally representing the size of your smallest server.
+
+Here we chose that 1 unit of capacity = 0.5 To, so that we can express servers of size
+1 To and 2 To, as wel as the intermediate size 1.5 To.
+
+Note that the amount of data stored by Garage on each server may not be strictly proportional to
+its capacity value, as Garage will priorize having 3 copies of data in different zones,
+even if this means that capacities will not be strictly respected. For example in our above examples,
+nodes Earth and Mars will always store a copy of everything each, and the third copy will
+have 66% chance of being stored by Venus and 33% chance of being stored by Mercury.
+
+#### Injecting the topology
+
+Given the information above, we will configure our cluster as follow:
+
+```
+garagectl node configure -z par1 -c 2 -t mercury 8781c5
+garagectl node configure -z par1 -c 4 -t venus 2a638e
+garagectl node configure -z lon1 -c 4 -t earth 68143d
+garagectl node configure -z bru1 -c 3 -t mars 212f75
+```
diff --git a/doc/book/src/cookbook/systemd.md b/doc/book/src/cookbook/systemd.md
new file mode 100644
index 00000000..aded09ad
--- /dev/null
+++ b/doc/book/src/cookbook/systemd.md
@@ -0,0 +1,39 @@
+# Starting Garage with systemd instead of Docker
+
+NOTE: This guide is incomplete. Typicall you would also want to create a separate
+Unix user to run Garage.
+
+Make sure you have the Garage binary installed on your system (see [quick start](../quick_start/index.md)), e.g. at `/usr/local/bin/garage`.
+
+Create a file named `/etc/systemd/system/garage.service`:
+
+```toml
+[Unit]
+Description=Garage Data Store
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Environment='RUST_LOG=garage=info' 'RUST_BACKTRACE=1'
+ExecStart=/usr/local/bin/garage server -c /etc/garage/garage.toml
+
+[Install]
+WantedBy=multi-user.target
+```
+
+To start the service then automatically enable it at boot:
+
+```bash
+sudo systemctl start garage
+sudo systemctl enable garage
+```
+
+To see if the service is running and to browse its logs:
+
+```bash
+sudo systemctl status garage
+sudo journalctl -u garage
+```
+
+If you want to modify the service file, do not forget to run `systemctl daemon-reload`
+to inform `systemd` of your modifications.
diff --git a/doc/book/src/cookbook/website.md b/doc/book/src/cookbook/website.md
index b3dd1b51..53488ac4 100644
--- a/doc/book/src/cookbook/website.md
+++ b/doc/book/src/cookbook/website.md
@@ -1,3 +1,3 @@
-# Host a website
+# Hosting a website
TODO
diff --git a/doc/book/src/getting_started/01_binary.md b/doc/book/src/getting_started/01_binary.md
deleted file mode 100644
index 2719d959..00000000
--- a/doc/book/src/getting_started/01_binary.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Get a binary
-
-Currently, only two installations procedures are supported for Garage: from Docker (x86\_64 for Linux) and from source.
-In the future, we plan to add a third one, by publishing a compiled binary (x86\_64 for Linux).
-We did not test other architecture/operating system but, as long as your architecture/operating system is supported by Rust, you should be able to run Garage (feel free to report your tests!).
-
-## From Docker
-
-Our docker image is currently named `lxpz/garage_amd64` and is stored on the [Docker Hub](https://hub.docker.com/r/lxpz/garage_amd64/tags?page=1&ordering=last_updated).
-We encourage you to use a fixed tag (eg. `v0.3.0`) and not the `latest` tag.
-For this example, we will use the latest published version at the time of the writing which is `v0.3.0` but it's up to you
-to check [the most recent versions on the Docker Hub](https://hub.docker.com/r/lxpz/garage_amd64/tags?page=1&ordering=last_updated).
-
-For example:
-
-```
-sudo docker pull lxpz/garage_amd64:v0.3.0
-```
-
-## From source
-
-Garage is a standard Rust project.
-First, you need `rust` and `cargo`.
-On Debian:
-
-```bash
-sudo apt-get update
-sudo apt-get install -y rustc cargo
-```
-
-Then, you can ask cargo to install the binary for you:
-
-```bash
-cargo install garage
-```
-
-That's all, `garage` should be in `$HOME/.cargo/bin`.
-You can add this folder to your `$PATH` or copy the binary somewhere else on your system.
-For the following, we will assume you copied it in `/usr/local/bin/garage`:
-
-```bash
-sudo cp $HOME/.cargo/bin/garage /usr/local/bin/garage
-```
-
diff --git a/doc/book/src/getting_started/02_test_deployment.md b/doc/book/src/getting_started/02_test_deployment.md
deleted file mode 100644
index c8296fcc..00000000
--- a/doc/book/src/getting_started/02_test_deployment.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Configuring a test deployment
-
-This section describes how to run a simple test Garage deployment with a single node.
-Note that this kind of deployment should not be used in production, as it provides
-no redundancy for your data!
-We will also skip intra-cluster TLS configuration, meaning that if you add nodes
-to your cluster, communication between them will not be secure.
-
-First, make sure that you have Garage installed in your command line environment.
-We will explain how to launch Garage in a Docker container, however we still
-recommend that you install the `garage` CLI on your host system in order to control
-the daemon.
-
-## Writing a first configuration file
-
-This first configuration file should allow you to get started easily with the simplest
-possible Garage deployment:
-
-```toml
-metadata_dir = "/tmp/meta"
-data_dir = "/tmp/data"
-
-replication_mode = "none"
-
-rpc_bind_addr = "[::]:3901"
-
-bootstrap_peers = []
-
-[s3_api]
-s3_region = "garage"
-api_bind_addr = "[::]:3900"
-
-[s3_web]
-bind_addr = "[::]:3902"
-root_domain = ".web.garage"
-index = "index.html"
-```
-
-Save your configuration file as `garage.toml`.
-
-As you can see in the `metadata_dir` and `data_dir` parameters, we are saving Garage's data
-in `/tmp` which gets erased when your system reboots. This means that data stored on this
-Garage server will not be persistent. Change these to locations on your HDD if you want
-your data to be persisted properly.
-
-## Launching the Garage server
-
-#### Option 1: directly (without Docker)
-
-Use the following command to launch the Garage server with our configuration file:
-
-```
-garage server -c garage.toml
-```
-
-By default, Garage displays almost no output. You can tune Garage's verbosity as follows
-(from less verbose to more verbose):
-
-```
-RUST_LOG=garage=info garage server -c garage.toml
-RUST_LOG=garage=debug garage server -c garage.toml
-RUST_LOG=garage=trace garage server -c garage.toml
-```
-
-Log level `info` is recommended for most use cases.
-Log level `debug` can help you check why your S3 API calls are not working.
-
-#### Option 2: in a Docker container
-
-Use the following command to start Garage in a docker container:
-
-```
-docker run -d \
- -p 3901:3901 -p 3902:3902 -p 3900:3900 \
- -v $PWD/garage.toml:/garage/garage.toml \
- lxpz/garage_amd64:v0.3.0
-```
-
-To tune Garage's verbosity level, set the `RUST_LOG` environment variable in the configuration
-at launch time. For instance:
-
-```
-docker run -d \
- -p 3901:3901 -p 3902:3902 -p 3900:3900 \
- -v $PWD/garage.toml:/garage/garage.toml \
- -e RUST_LOG=garage=info \
- lxpz/garage_amd64:v0.3.0
-```
-
-## Checking that Garage runs correctly
-
-The `garage` utility is also used as a CLI tool to configure your Garage deployment.
-It tries to connect to a Garage server through the RPC protocol, by default looking
-for a Garage server at `localhost:3901`.
-
-Since our deployment already binds to port 3901, the following command should be sufficient
-to show Garage's status, provided that you installed the `garage` binary on your host system:
-
-```
-garage status
-```
-
-Move on to [controlling the Garage daemon](04_control.md) to learn more about how to
-use the Garage CLI to control your cluster.
-
-Move on to [configuring your cluster](05_cluster.md) in order to configure
-your single-node deployment for actual use!
diff --git a/doc/book/src/getting_started/03_real_world_deployment.md b/doc/book/src/getting_started/03_real_world_deployment.md
deleted file mode 100644
index 9fd97303..00000000
--- a/doc/book/src/getting_started/03_real_world_deployment.md
+++ /dev/null
@@ -1,154 +0,0 @@
-# Configuring a real-world Garage deployment
-
-To run Garage in cluster mode, we recommend having at least 3 nodes.
-This will allow you to setup Garage for three-way replication of your data,
-the safest and most available mode avaialble.
-
-## Generating a TLS Certificate
-
-You first need to generate TLS certificates to encrypt traffic between Garage nodes
-(reffered to as RPC traffic).
-
-To generate your TLS certificates, run on your machine:
-
-```
-wget https://git.deuxfleurs.fr/Deuxfleurs/garage/raw/branch/main/genkeys.sh
-chmod +x genkeys.sh
-./genkeys.sh
-```
-
-It will creates a folder named `pki/` containing the keys that you will used for the cluster.
-
-## Real-world deployment
-
-To run a real-world deployment, make sure you the following conditions are met:
-
-- You have at least three machines with sufficient storage space available
-
-- Each machine has a public IP address which is reachable by other machines.
- Running behind a NAT is possible, but having several Garage nodes behind a single NAT
- is slightly more involved as each will have to have a different RPC port number
- (the local port number of a node must be the same as the port number exposed publicly
- by the NAT).
-
-- Ideally, each machine should have a SSD available in addition to the HDD you are dedicating
- to Garage. This will allow for faster access to metadata and has the potential
- to drastically reduce Garage's response times.
-
-Before deploying garage on your infrastructure, you must inventory your machines.
-For our example, we will suppose the following infrastructure with IPv6 connectivity:
-
-| Location | Name | IP Address | Disk Space |
-|----------|---------|------------|------------|
-| Paris | Mercury | fc00:1::1 | 1 To |
-| Paris | Venus | fc00:1::2 | 2 To |
-| London | Earth | fc00:B::1 | 2 To |
-| Brussels | Mars | fc00:F::1 | 1.5 To |
-
-
-On each machine, we will have a similar setup,
-especially you must consider the following folders/files:
-
- - `/etc/garage/garage.toml`: Garage daemon's configuration (see below)
- - `/etc/garage/pki/`: Folder containing Garage certificates, must be generated on your computer and copied on the servers
- - `/var/lib/garage/meta/`: Folder containing Garage's metadata, put this folder on a SSD if possible
- - `/var/lib/garage/data/`: Folder containing Garage's data, this folder will grows and must be on a large storage, possibly big HDDs.
- - `/etc/systemd/system/garage.service`: Service file to start garage at boot automatically (defined below, not required if you use docker)
-
-A valid `/etc/garage/garage.toml` for our cluster would be:
-
-```toml
-metadata_dir = "/var/lib/garage/meta"
-data_dir = "/var/lib/garage/data"
-
-replication_mode = "3"
-
-rpc_bind_addr = "[::]:3901"
-
-bootstrap_peers = [
- "[fc00:1::1]:3901",
- "[fc00:1::2]:3901",
- "[fc00:B::1]:3901",
- "[fc00:F::1]:3901",
-]
-
-[rpc_tls]
-ca_cert = "/etc/garage/pki/garage-ca.crt"
-node_cert = "/etc/garage/pki/garage.crt"
-node_key = "/etc/garage/pki/garage.key"
-
-[s3_api]
-s3_region = "garage"
-api_bind_addr = "[::]:3900"
-
-[s3_web]
-bind_addr = "[::]:3902"
-root_domain = ".web.garage"
-index = "index.html"
-```
-
-Please make sure to change `bootstrap_peers` to **your** IP addresses!
-
-Check the [configuration file reference documentation](../reference_manual/configuration.md)
-to learn more about all available configuration options.
-
-### For docker users
-
-On each machine, you can run the daemon with:
-
-```bash
-docker run \
- -d \
- --name garaged \
- --restart always \
- --network host \
- -v /etc/garage/pki:/etc/garage/pki \
- -v /etc/garage/garage.toml:/garage/garage.toml \
- -v /var/lib/garage/meta:/var/lib/garage/meta \
- -v /var/lib/garage/data:/var/lib/garage/data \
- lxpz/garage_amd64:v0.3.0
-```
-
-It should be restart automatically at each reboot.
-Please note that we use host networking as otherwise Docker containers
-can not communicate with IPv6.
-
-Upgrading between Garage versions should be supported transparently,
-but please check the relase notes before doing so!
-To upgrade, simply stop and remove this container and
-start again the command with a new version of garage.
-
-### For systemd/raw binary users
-
-Create a file named `/etc/systemd/system/garage.service`:
-
-```toml
-[Unit]
-Description=Garage Data Store
-After=network-online.target
-Wants=network-online.target
-
-[Service]
-Environment='RUST_LOG=garage=info' 'RUST_BACKTRACE=1'
-ExecStart=/usr/local/bin/garage server -c /etc/garage/garage.toml
-
-[Install]
-WantedBy=multi-user.target
-```
-
-To start the service then automatically enable it at boot:
-
-```bash
-sudo systemctl start garage
-sudo systemctl enable garage
-```
-
-To see if the service is running and to browse its logs:
-
-```bash
-sudo systemctl status garage
-sudo journalctl -u garage
-```
-
-If you want to modify the service file, do not forget to run `systemctl daemon-reload`
-to inform `systemd` of your modifications.
diff --git a/doc/book/src/getting_started/04_control.md b/doc/book/src/getting_started/04_control.md
deleted file mode 100644
index 018d3268..00000000
--- a/doc/book/src/getting_started/04_control.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Control the daemon
-
-The `garage` binary has two purposes:
- - it acts as a daemon when launched with `garage server ...`
- - it acts as a control tool for the daemon when launched with any other command
-
-In this section, we will see how to use the `garage` binary as a control tool for the daemon we just started.
-You first need to get a shell having access to this binary, which depends of your configuration:
-
- - with `docker`, run `sudo docker exec -ti garaged bash`, you will now have a shell
- where the Garage binary is available as `/garage/garage`
- - with `systemd`, simply run `/usr/local/bin/garage` if you followed previous instructions
-
-*You can also install the binary on your machine to remotely control the cluster.*
-
-## Talk to the daemon and create an alias
-
-`garage` requires 4 options to talk with the daemon:
-
-```
---ca-cert <ca-cert>
---client-cert <client-cert>
---client-key <client-key>
--h, --rpc-host <rpc-host>
-```
-
-The 3 first ones are certificates and keys needed by TLS, the last one is simply the address of garage's RPC endpoint.
-Because we configure garage directly from the server, we do not need to set `--rpc-host`.
-To avoid typing the 3 first options each time we want to run a command, we will create an alias.
-
-### test deployment
-
-If you have simply deployed Garage on your local machine, without TLS, you can invoke
-`garage` directly without any of these parameters and without making a `garagectl` alias
-(replace mentions of `garagectl` in the next sections by `garage`).
-
-
-### `docker` alias
-
-```bash
-alias garagectl='/garage/garage \
- --ca-cert /etc/garage/pki/garage-ca.crt \
- --client-cert /etc/garage/pki/garage.crt \
- --client-key /etc/garage/pki/garage.key'
-```
-
-### raw binary alias
-
-```bash
-alias garagectl='/usr/local/bin/garage \
- --ca-cert /etc/garage/pki/garage-ca.crt \
- --client-cert /etc/garage/pki/garage.crt \
- --client-key /etc/garage/pki/garage.key'
-```
-
-Of course, if your deployment does not match exactly one of this alias, feel free to adapt it to your needs!
-
-## Test the alias
-
-You can test your alias by running a simple command such as:
-
-```
-garagectl status
-```
-
-You should get something like that as result:
-
-```
-Healthy nodes:
-2a638ed6c775b69a… 37f0ba978d27 [::ffff:172.20.0.101]:3901 UNCONFIGURED/REMOVED
-68143d720f20c89d… 9795a2f7abb5 [::ffff:172.20.0.103]:3901 UNCONFIGURED/REMOVED
-8781c50c410a41b3… 758338dde686 [::ffff:172.20.0.102]:3901 UNCONFIGURED/REMOVED
-```
-
-...which means that you are ready to [configure your cluster](05_cluster.md)!
diff --git a/doc/book/src/getting_started/05_cluster.md b/doc/book/src/getting_started/05_cluster.md
deleted file mode 100644
index ac6fc9fd..00000000
--- a/doc/book/src/getting_started/05_cluster.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# Configure a cluster
-
-*We use a command named `garagectl` which is in fact an alias you must define as explained in the [Control the daemon](./daemon.md) section.*
-
-In this section, we will inform garage of the disk space available on each node of the cluster
-as well as the site (think datacenter) of each machine.
-
-## Test cluster
-
-As this part is not relevant for a test cluster, you can use this three-liner to create a basic topology:
-
-```bash
-garagectl status | grep UNCONFIGURED | grep -Po '^[0-9a-f]+' | while read id; do
- garagectl node configure -z dc1 -c 1 $id
-done
-```
-
-## Real-world cluster
-
-For our example, we will suppose we have the following infrastructure (Capacity, Identifier and Datacenter are specific values to garage described in the following):
-
-| Location | Name | Disk Space | `Capacity` | `Identifier` | `Zone` |
-|----------|---------|------------|------------|--------------|--------------|
-| Paris | Mercury | 1 To | `2` | `8781c5` | `par1` |
-| Paris | Venus | 2 To | `4` | `2a638e` | `par1` |
-| London | Earth | 2 To | `4` | `68143d` | `lon1` |
-| Brussels | Mars | 1.5 To | `3` | `212f75` | `bru1` |
-
-### Identifier
-
-After its first launch, garage generates a random and unique identifier for each nodes, such as:
-
-```
-8781c50c410a41b363167e9d49cc468b6b9e4449b6577b64f15a249a149bdcbc
-```
-
-Often a shorter form can be used, containing only the beginning of the identifier, like `8781c5`,
-which identifies the server "Mercury" located in "Paris" according to our previous table.
-
-The most simple way to match an identifier to a node is to run:
-
-```
-garagectl status
-```
-
-It will display the IP address associated with each node; from the IP address you will be able to recognize the node.
-
-### Zones
-
-Zones are simply a user-chosen identifier that identify a group of server that are grouped together logically.
-It is up to the system administrator deploying garage to identify what does "grouped together" means.
-
-In most cases, a zone will correspond to a geographical location (i.e. a datacenter).
-Behind the scene, Garage will use zone definition to try to store the same data on different zones,
-in order to provide high availability despite failure of a zone.
-
-### Capacity
-
-Garage reasons on an arbitrary metric about disk storage that is named the *capacity* of a node.
-The capacity configured in Garage must be proportional to the disk space dedicated to the node.
-Additionaly, the capacity values used in Garage should be as small as possible, with
-1 ideally representing the size of your smallest server.
-
-Here we chose that 1 unit of capacity = 0.5 To, so that we can express servers of size
-1 To and 2 To, as wel as the intermediate size 1.5 To.
-
-Note that the amount of data stored by Garage on each server may not be strictly proportional to
-its capacity value, as Garage will priorize having 3 copies of data in different zones,
-even if this means that capacities will not be strictly respected. For example in our above examples,
-nodes Earth and Mars will always store a copy of everything each, and the third copy will
-have 66% chance of being stored by Venus and 33% chance of being stored by Mercury.
-
-### Inject the topology
-
-Given the information above, we will configure our cluster as follow:
-
-```
-garagectl node configure -z par1 -c 2 -t mercury 8781c5
-garagectl node configure -z par1 -c 4 -t venus 2a638e
-garagectl node configure -z lon1 -c 4 -t earth 68143d
-garagectl node configure -z bru1 -c 3 -t mars 212f75
-```
diff --git a/doc/book/src/getting_started/06_bucket.md b/doc/book/src/getting_started/06_bucket.md
deleted file mode 100644
index b4a2d81d..00000000
--- a/doc/book/src/getting_started/06_bucket.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# Create buckets and keys
-
-*We use a command named `garagectl` which is in fact an alias you must define as explained in the [Control the daemon](./daemon.md) section.*
-
-In this section, we will suppose that we want to create a bucket named `nextcloud-bucket`
-that will be accessed through a key named `nextcloud-app-key`.
-
-Don't forget that `help` command and `--help` subcommands can help you anywhere, the CLI tool is self-documented! Two examples:
-
-```
-garagectl help
-garagectl bucket allow --help
-```
-
-## Create a bucket
-
-Fine, now let's create a bucket (we imagine that you want to deploy nextcloud):
-
-```
-garagectl bucket create nextcloud-bucket
-```
-
-Check that everything went well:
-
-```
-garagectl bucket list
-garagectl bucket info nextcloud-bucket
-```
-
-## Create an API key
-
-Now we will generate an API key to access this bucket.
-Note that API keys are independent of buckets: one key can access multiple buckets, multiple keys can access one bucket.
-
-Now, let's start by creating a key only for our PHP application:
-
-```
-garagectl key new --name nextcloud-app-key
-```
-
-You will have the following output (this one is fake, `key_id` and `secret_key` were generated with the openssl CLI tool):
-
-```
-Key name: nextcloud-app-key
-Key ID: GK3515373e4c851ebaad366558
-Secret key: 7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34
-Authorized buckets:
-```
-
-Check that everything works as intended:
-
-```
-garagectl key list
-garagectl key info nextcloud-app-key
-```
-
-## Allow a key to access a bucket
-
-Now that we have a bucket and a key, we need to give permissions to the key on the bucket!
-
-```
-garagectl bucket allow \
- --read \
- --write
- nextcloud-bucket \
- --key nextcloud-app-key
-```
-
-You can check at any times allowed keys on your bucket with:
-
-```
-garagectl bucket info nextcloud-bucket
-```
-
diff --git a/doc/book/src/getting_started/07_files.md b/doc/book/src/getting_started/07_files.md
deleted file mode 100644
index cdd5d945..00000000
--- a/doc/book/src/getting_started/07_files.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Handle files
-
-We recommend the use of MinIO Client to interact with Garage files (`mc`).
-Instructions to install it and use it are provided on the [MinIO website](https://docs.min.io/docs/minio-client-quickstart-guide.html).
-Before reading the following, you need a working `mc` command on your path.
-
-Note that on certain Linux distributions such as Arch Linux, the Minio client binary
-is called `mcli` instead of `mc` (to avoid name clashes with the Midnight Commander).
-
-## Configure `mc`
-
-You need your access key and secret key created in the [previous section](bucket.md).
-You also need to set the endpoint: it must match the IP address of one of the node of the cluster and the API port (3900 by default).
-For this whole configuration, you must set an alias name: we chose `my-garage`, that you will used for all commands.
-
-Adapt the following command accordingly and run it:
-
-```bash
-mc alias set \
- my-garage \
- http://172.20.0.101:3900 \
- <access key> \
- <secret key> \
- --api S3v4
-```
-
-You must also add an environment variable to your configuration to inform MinIO of our region (`garage` by default).
-The best way is to add the following snippet to your `$HOME/.bash_profile` or `$HOME/.bashrc` file:
-
-```bash
-export MC_REGION=garage
-```
-
-## Use `mc`
-
-You can not list buckets from `mc` currently.
-
-But the following commands and many more should work:
-
-```bash
-mc cp image.png my-garage/nextcloud-bucket
-mc cp my-garage/nextcloud-bucket/image.png .
-mc ls my-garage/nextcloud-bucket
-mc mirror localdir/ my-garage/another-bucket
-```
diff --git a/doc/book/src/getting_started/index.md b/doc/book/src/getting_started/index.md
deleted file mode 100644
index 282f5034..00000000
--- a/doc/book/src/getting_started/index.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Getting Started
-
-Let's start your Garage journey!
-In this chapter, we explain how to deploy a simple garage cluster and start interacting with it.
-Our goal is to introduce you to Garage's workflows.
diff --git a/doc/book/src/quick_start/index.md b/doc/book/src/quick_start/index.md
new file mode 100644
index 00000000..d564f760
--- /dev/null
+++ b/doc/book/src/quick_start/index.md
@@ -0,0 +1,266 @@
+# Quick Start
+
+Let's start your Garage journey!
+In this chapter, we explain how to deploy Garage as a single-node server
+and how to interact with it.
+
+Our goal is to introduce you to Garage's workflows.
+Following this guide is recommended before moving on to
+[configuring a real-world deployment](../cookbook/real_world.md).
+
+Note that this kind of deployment should not be used in production, as it provides
+no redundancy for your data!
+We will also skip intra-cluster TLS configuration, meaning that if you add nodes
+to your cluster, communication between them will not be secure.
+
+## Get a binary
+
+Download the latest Garage binary from the release pages on our repository:
+
+<https://git.deuxfleurs.fr/Deuxfleurs/garage/releases>
+
+Place this binary somewhere in your `$PATH` so that you can invoke the `garage`
+command directly (for instance you can copy the binary in `/usr/local/bin`
+or in `~/.local/bin`).
+
+If a binary of the last version is not available for your architecture,
+you can [build Garage from source](../cookbook/from_source.md).
+
+
+## Writing a first configuration file
+
+This first configuration file should allow you to get started easily with the simplest
+possible Garage deployment:
+
+```toml
+metadata_dir = "/tmp/meta"
+data_dir = "/tmp/data"
+
+replication_mode = "none"
+
+rpc_bind_addr = "[::]:3901"
+
+bootstrap_peers = []
+
+[s3_api]
+s3_region = "garage"
+api_bind_addr = "[::]:3900"
+
+[s3_web]
+bind_addr = "[::]:3902"
+root_domain = ".web.garage"
+index = "index.html"
+```
+
+Save your configuration file as `garage.toml`.
+
+As you can see in the `metadata_dir` and `data_dir` parameters, we are saving Garage's data
+in `/tmp` which gets erased when your system reboots. This means that data stored on this
+Garage server will not be persistent. Change these to locations on your local disk if you want
+your data to be persisted properly.
+
+
+## Launching the Garage server
+
+Use the following command to launch the Garage server with our configuration file:
+
+```
+garage server -c garage.toml
+```
+
+By default, Garage displays almost no output. You can tune Garage's verbosity as follows
+(from less verbose to more verbose):
+
+```
+RUST_LOG=garage=info garage server -c garage.toml
+RUST_LOG=garage=debug garage server -c garage.toml
+RUST_LOG=garage=trace garage server -c garage.toml
+```
+
+Log level `info` is recommended for most use cases.
+Log level `debug` can help you check why your S3 API calls are not working.
+
+
+## Checking that Garage runs correctly
+
+The `garage` utility is also used as a CLI tool to configure your Garage deployment.
+It tries to connect to a Garage server through the RPC protocol, by default looking
+for a Garage server at `localhost:3901`.
+
+Since our deployment already binds to port 3901, the following command should be sufficient
+to show Garage's status:
+
+```
+garage status
+```
+
+This should show something like this:
+
+```
+Healthy nodes:
+2a638ed6c775b69a… linuxbox 127.0.0.1:3901 UNCONFIGURED/REMOVED
+```
+
+## Configuring your Garage node
+
+Configuring the nodes in a Garage deployment means informing Garage
+of the disk space available on each node of the cluster
+as well as the zone (e.g. datacenter) each machine is located in.
+
+For our test deployment, we are using only one node. The way in which we configure
+it does not matter, you can simply write:
+
+```bash
+garage node configure -z dc1 -c 1 <node_id>
+```
+
+where `<node_id>` corresponds to the identifier of the node shown by `garage status` (first column).
+You can enter simply a prefix of that identifier.
+For instance here you could write just `garage node configure -z dc1 -c 1 2a63`.
+
+
+
+
+## Creating buckets and keys
+
+In this section, we will suppose that we want to create a bucket named `nextcloud-bucket`
+that will be accessed through a key named `nextcloud-app-key`.
+
+Don't forget that `help` command and `--help` subcommands can help you anywhere,
+the CLI tool is self-documented! Two examples:
+
+```
+garage help
+garage bucket allow --help
+```
+
+#### Create a bucket
+
+Let's take an example where we want to deploy NextCloud using Garage as the
+main data storage.
+
+First, create a bucket with the following command:
+
+```
+garage bucket create nextcloud-bucket
+```
+
+Check that everything went well:
+
+```
+garage bucket list
+garage bucket info nextcloud-bucket
+```
+
+#### Create an API key
+
+The `nextcloud-bucket` bucket now exists on the Garage server,
+however it cannot be accessed until we add an API key with the proper access rights.
+
+Note that API keys are independent of buckets:
+one key can access multiple buckets, multiple keys can access one bucket.
+
+Create an API key using the following command:
+
+```
+garage key new --name nextcloud-app-key
+```
+
+The output should look as follows:
+
+```
+Key name: nextcloud-app-key
+Key ID: GK3515373e4c851ebaad366558
+Secret key: 7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34
+Authorized buckets:
+```
+
+Check that everything works as intended:
+
+```
+garage key list
+garage key info nextcloud-app-key
+```
+
+#### Allow a key to access a bucket
+
+Now that we have a bucket and a key, we need to give permissions to the key on the bucket:
+
+```
+garage bucket allow \
+ --read \
+ --write
+ nextcloud-bucket \
+ --key nextcloud-app-key
+```
+
+You can check at any time the allowed keys on your bucket with:
+
+```
+garage bucket info nextcloud-bucket
+```
+
+
+## Uploading and downlading from Garage
+
+We recommend the use of MinIO Client to interact with Garage files (`mc`).
+Instructions to install it and use it are provided on the
+[MinIO website](https://docs.min.io/docs/minio-client-quickstart-guide.html).
+Before reading the following, you need a working `mc` command on your path.
+
+Note that on certain Linux distributions such as Arch Linux, the Minio client binary
+is called `mcli` instead of `mc` (to avoid name clashes with the Midnight Commander).
+
+#### Configure `mc`
+
+You need your access key and secret key created above.
+We will assume you are invoking `mc` on the same machine as the Garage server,
+your S3 API endpoint is therefore `http://127.0.0.1:3900`.
+For this whole configuration, you must set an alias name: we chose `my-garage`, that you will used for all commands.
+
+Adapt the following command accordingly and run it:
+
+```bash
+mc alias set \
+ my-garage \
+ http://127.0.0.1:3900 \
+ <access key> \
+ <secret key> \
+ --api S3v4
+```
+
+You must also add an environment variable to your configuration to
+inform MinIO of our region (`garage` by default, corresponding to the `s3_region` parameter
+in the configuration file).
+The best way is to add the following snippet to your `$HOME/.bash_profile`
+or `$HOME/.bashrc` file:
+
+```bash
+export MC_REGION=garage
+```
+
+#### Use `mc`
+
+You can not list buckets from `mc` currently.
+
+But the following commands and many more should work:
+
+```bash
+mc cp image.png my-garage/nextcloud-bucket
+mc cp my-garage/nextcloud-bucket/image.png .
+mc ls my-garage/nextcloud-bucket
+mc mirror localdir/ my-garage/another-bucket
+```
+
+
+#### Other tools for interacting with Garage
+
+The following tools can also be used to send and recieve files from/to Garage:
+
+- the [AWS CLI](https://aws.amazon.com/cli/)
+- [`rclone`](https://rclone.org/)
+- [Cyberduck](https://cyberduck.io/)
+- [`s3cmd`](https://s3tools.org/s3cmd)
+
+Refer to the ["configuring clients"](../cookbook/clients.md) to learn how to configure
+these clients to interact with a Garage server.