# Uncloud Tips


[Uncloud's docs](https://uncloud.run/docs) are great, but a few things are buried a bit. Hence a simple list
of things that can improve your interactions with Uncloud.

# SSH ProxyJump

Sometimes you can not directly connect to a cluster, you first have to SSH into a host that _is_ directly
connected to a cluster. If this is the case use a SSH _proxy jump_ (see ssh(1)). This allows you to, e.g. use a
local docker to build images that can then be pushed to the cluster.

When connecting to a cluster it make sense to use a proxy jump host. In your ~/.ssh/config add:

```
Host uncloud*
    ProxyJump xxxxx.science.ru.nl
```

Where all my uncloud hosts are named, `uncloudXXX`, the above says use xxxxx.science.ru.nl as the proxy jump host.

If ssh-ing into the proxy jump host is difficult as well, due to a 2nd factor use an _ControlMaster_ (see ssh(1)):

```
Host xxxxx.science.ru.nl
ControlMaster auto
    ControlPath ~/.ssh/%r@%h-%p.sock
    ControlPersist 10m
```

# SSH Keys

(SSH) keys used to authenticate against the Uncloud cluster **must not** have _a passphrase_. You can remove a
passphrase with `ssh-keygen -p -f /path/to-key-file` and then set an empty one.

Using a specific key can be done by [using a
`ssh_key_file`](https://uncloud.run/docs/cli-config-reference?_highlight=config#config-structure) in your
`uncloud/config.yaml`. This should point to your identity file (the one _without_ the `.pub` extension).

# Docker Login

Sometimes you need to reference an image that is hosted inside a registry that requires authentication. In
that case use the _local_ `docker login` to login. Those credentials are automatically pushed to the cluster
and there it will be able to pull the image!

# Uncloud socket

_Do not_ in your `compose.yaml` mount the Uncloud socket from `/run/uncloud/uncloud.sock:/run/uncloud/uncloud.sock`,
if dockerd start earlier than the uncloud daemon it will create a directory instead of a socket and will fail
the uncloudd startup. I.e. **don't do the following**:

```yaml
services:
  myserver:
    image: myimage
    volumes:
      - /run/uncloud/uncloud.sock:/run/uncloud/uncloud.sock
...
```

If you must get access to the uncloud socket, mount the entire directory:

```yaml
services:
  myserver:
    image: myimage
    volumes:
      - /run/uncloud:/run/uncloud
...
```

# Ports in compose.yaml

If you download a "ready-made-docker-compose" you can probably remove quite a bit from it. Notable any
`expose` and or `ports` are not needed. In Uncloud a container is reachable on all ports regardless of what
the compose file says.

If you want a service to be **externally** reachable you need to use
[`x-ports`](https://uncloud.run/docs/compose-file-reference/extensions#x-ports).

# Defining global snippets in Caddy

A topic that came up was to block _external_ requests to a service, this can be done via [request
matchers](https://caddyserver.com/docs/caddyfile/matchers) in Caddy.

For those matcher you can also make a [named
matcher](https://caddyserver.com/docs/caddyfile/matchers#named-matchers), which is _really_ handy. But to
prevent repetition it would be nice to define this once, so other services can reuse it.

This can be done as follows by defining an extra (bogus?) service with an `x-caddy`:

```yaml
caddy-metrics:
  image: registry.science.ru.nl/cncz/sys/image/debug:v0.1.14
  x-caddy: |
    http://:2019 {
        handle {
            metrics
        }
    }
    (block) {
      @block {
        remote_ip 131.174.0.0/16
        ...
      }
    }
```

Now another service can just `import block` to have this list, and use it in the
[handle](https://caddyserver.com/docs/caddyfile/directives/handle) directive.

```caddyfile
import block
handle @block {
    ...
}
```

See [here](https://uncloud.run/docs/concepts/ingress/publishing-services) on how to mimic the config Uncloud
would have generated for you, so you can make the `handle` block similar.

