# Bootstrap Config

> Octelium documentation. Canonical page: <https://octelium.com/docs/octelium/latest/install/cluster/bootstrap>.

A Bootstrap configuration file is a `yaml` file that acts as the sole source of truth for all the configs (e.g. information related to the primary store used by the *Cluster*) needed to properly install and initialize a new Octelium *Cluster* via the `octops init` command (read in detail about *Cluster* installation via `octops init` [here](https://octelium.com/docs/octelium/latest/install/cluster/installing-cluster.md)) as follows:

```bash
octops init example.com --bootstrap /PATH/TO/BOOTSTRAP_CONFIG.yaml
```

> **Note:**
>
> You do not really need to know about the Bootstrap configuration if you intend to install a *Cluster* via the quick installation guide as shown [here](https://octelium.com/docs/octelium/latest/overview/quick-install.md).

A practical, yet minimal, Bootstrap configuration file can look as follows:

```yaml
spec:
  primaryStorage:
    postgresql:
      username: postgres
      password: password
      host: pg.provider.example.com
      port: 5432
      database: octelium
      isTLS: true
  secondaryStorage:
    redis:
      username: redis-user
      password: password
      host: 1.2.3.4
      port: 6379
      database: 0
      isTLS: true
```

A more comprehensive Bootstrap configuration can look as follows (see the details below for more info about each configuration section):

```yaml
spec:
  primaryStorage:
    postgresql:
      username: octelium
      # Use either password or passwordFromSecret.
      # password: replace-with-postgres-password
      passwordFromSecret:
        name: octelium-postgres
        namespace: octelium-dbs
        key: password
      host: octelium-rw.octelium-dbs.svc
      port: 5432
      database: octelium
      isTLS: false
  secondaryStorage:
    redis:
      username: default
      # Use either password or passwordFromSecret.
      # password: replace-with-redis-password
      passwordFromSecret:
        name: octelium-redis
        namespace: octelium-dbs
        key: password
      host: valkey-primary.octelium-dbs.svc
      port: 6379
      database: 0
      isTLS: false
  network:
    # DEFAULT also resolves to DUAL_STACK.
    # Other supported values are V4_ONLY and V6_ONLY.
    mode: DUAL_STACK
    v4:
      clusterNetwork: 100.64.0.0/10
    wireguard:
      gatewayPort: 53820
      mtu: 1280
    quicv0:
      enable: true
      gatewayPort: 8443
      mtu: 1190
```

## Storage

### Primary Storage

Octelium currently uses PostgreSQL as the primary store for all of its resources. Here is an example:

```yaml
spec:
  primaryStorage:
    postgresql:
      username: postgres
      password: password
      host: 1.2.3.4
      port: 5432
      database: octelium
      isTLS: true
```

You can also use a password value by reference from a Kubernetes secret (read more [here](https://kubernetes.io/docs/concepts/configuration/secret/)). Here is an example:

```yaml
spec:
  primaryStorage:
    postgresql:
      username: octelium
      # !mark(1:4)
      passwordFromSecret:
        name: octelium-pg
        namespace: default
        key: password
      host: octelium-pg-postgresql.default.svc
      database: octelium
      port: 5432
```

### Secondary Storage

Octelium currently uses Redis as the secondary store which is used for being a cache store as well as pub/sub infrastructure to send events and resource changes between the different *Cluster* components. Here is an example:

```yaml
spec:
  secondaryStorage:
    redis:
      username: redis-user
      password: password
      host: 1.2.3.4
      port: 6379
      database: 0
      isTLS: true
```

As with primary storage, you can also use a password value by reference from a Kubernetes secret. Here is an example:

```yaml
spec:
  secondaryStorage:
    redis:
      # !mark(1:4)
      passwordFromSecret:
        name: octelium-redis
        namespace: default
        key: password
      host: octelium-redis-master.default.svc
      port: 6379
```

## Network

The *Cluster's* network range is the private network range that encompasses all ranges used by the *Cluster*'s *Services* as well as private IP addresses assigned to *Users* whenever connected via the `octelium` CLI tool. By default, this range is dual-stack but you can override the mode to become IPv4-only or IPv6-only. The following *Bootstrap* configuration example sets the networking mode to IPv6-only:

```yaml
spec:
  network:
    mode: V6_ONLY
```

> **Note:**
>
> Note that `V6_ONLY` does **not** mean that the upstreams (i.e. the actual protected resource setting behind the *Service* and served through it) has to listen on IPv6. It means that the *Services* will be listening to only IPv6 and the WireGuard-based clients can only be assigned to IPv6 addresses when to connecting to the *Cluster*. The *Service* itself is implemented by an identity-aware proxy, [*Vigil*](https://octelium.com/docs/octelium/latest/reference/components.md#vigil), that can connect to the upstream at both IPv4 and IPv6 regardless of which IP version the downstreams/clients are using.

For IPv6 ranges, the *Cluster* currently automatically generates a random range within the `fd00::/8` range.

For IPv4, the range `100.64.0.0/10` is currently used by default since it is rarely used by private networks. You can override that range to any other private range as long as it is large enough. Some examples are:

- `10.128.0.0/9`
- `172.16.0.0/12`
- `100.64.0.0/10` (the current default range)

Here is a *Bootstrap* configuration example where `10.128.0.0/9` is used as the IPv4 *Cluster* network range. Please note that such IPv4 private ranges are generally **not** recommended for any production environment since they might easily collide with ranges used both at clients or at the *Cluster* itself.

```yaml
spec:
  network:
    v4:
      clusterNetwork: 10.128.0.0/9
```

> **Note:**
>
> The `octelium` CLI tool always prefers IPv6-only when connecting to the *Cluster* as long as the *Cluster* supports IPv6, which is enabled by default, in order to not have any conflicts with the *User*'s host routing tables as IPv4 ranges are scarce and may lead to conflicts with other applications. As mentioned above, even if the `octelium` client is using IPv6-only, it can still reach IPv4-only upstreams since it's the *Service* that talks to the upstream and not the downstream directly. In fact, we encourage you to try the IPv6-only mode in the *Cluster* configuration unless you're sure that you will have to deal with IPv4-only clients.

### WireGuard

By default, the *Cluster* uses WireGuard for tunneling. By default the UDP port number `53820` is used by *Gateways*. You can override that number as follows:

```yaml
spec:
  network:
    wireguard:
      # !mark
      gatewayPort: 34567
```

Also, currently an MTU value of `1280` is used by all *Gateways*. You can override that value as follows:

```yaml
spec:
  network:
    wireguard:
      # !mark
      mtu: 1200
```

### QUIC

By default, the *Cluster* uses WireGuard for tunneling. Moreover, Octelium currently supports a QUIC-based tunneling mode. QUIC-based tunneling can be enabled in the *Bootstrap* configuration file as follows:

```yaml
spec:
  network:
    # !mark(1:2)
    quicv0:
      enable: true
```

By default, the *Cluster* uses the port `8443` for all *Gateways*. You can override the port number as follows:

```yaml
spec:
  network:
    quicv0:
      enable: true
      # !mark
      gatewayPort: 45678
```

Also, currently an MTU value of `1280` is used by all *Gateways*. You can override that value as follows:

```yaml
spec:
  network:
    quicv0:
      enable: true
      # !mark
      mtu: 1190
```
