Skip to content

Commit

Permalink
docs: add TCP / UDP documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
YuukanOO committed May 19, 2024
1 parent f295ea6 commit cef099f
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 128 deletions.
8 changes: 7 additions & 1 deletion docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ export default defineConfig({
},
{
text: "Providers",
link: "/reference/targets#providers",
link: "/reference/providers",
items: [
{
text: "Docker",
link: "/reference/providers/docker",
},
],
},
{
text: "Applications",
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ This quickstart will guide through installing and deploying your first applicati

![seelf home screenshot](/seelf-home.jpeg)

At its core, **seelf** just reads a `compose.yml` file, **deploy** services which [must be exposed](/reference/targets#docker) and manage **domains** and **certificates** for you.
At its core, **seelf** just reads a `compose.yml` file, **deploy** services which [must be exposed](/reference/providers/docker#exposing-services) and manage **domains** and **certificates** for you.

For the majority of cases, a locally working `compose.yml` file is sufficient, making the **transition from a local stack to a remote one a breeze**.

::: info
For now, only the [Docker provider](/reference/targets#docker) is available but that may change in the future to support others as well, such as **Docker swarm**, **Podman**, **Kubernetes** and so on.
For now, only the [Docker provider](/reference/providers/docker) is available but that may change in the future to support others as well, such as **Docker swarm**, **Podman**, **Kubernetes** and so on.
:::

Think of it as an alternative to services like [Heroku](https://www.heroku.com/), [Dokku](https://dokku.com/), [Caprover](https://caprover.com/), [Coolify](https://coolify.io/).
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/api.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# API

This part is currently being worked on. For now, only routes related to the deployment can be accessed with the API Key retrieved from the **profile page**. For more information, you can check the [`api.http` file](https://github.com/YuukanOO/seelf/blob/main/api.http) in the source code.
This part is currently [being worked on](https://github.com/YuukanOO/seelf/issues/45). For now, only routes related to the deployment can be accessed with the API Key retrieved from the **profile page**. For more information, you can check the [`api.http` file](https://github.com/YuukanOO/seelf/blob/main/api.http) in the source code.

Every other routes use a cookie authentication.

Expand Down
6 changes: 1 addition & 5 deletions docs/reference/applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,10 @@ Defines a new **stack of services** exposed on a [target subdomain](/reference/t

## Multiple exposed services

When you define a complete stack for your application, you may have multiple services exposed. This is totally allowed by **seelf**. When [identifying services](/reference/targets#exposing-services) which must be exposed, the first one in **alphabetical order** will become the **default service** and take the default subdomain.
When you define a complete stack for your application, you may have multiple services exposed. This is totally allowed by **seelf**. When [identifying services](/reference/providers/docker#exposing-services) which must be exposed, the first one in **alphabetical order** will become the **default service** and take the default subdomain.

Other services will be exposed using a subdomain on the default one.

::: warning
Only web services are supported [for now](https://github.com/YuukanOO/seelf/issues/17). No TCP / UDP services yet.
:::

## Environments {#environments}

Only 2 environments are managed by **seelf** at the moment: **production** and **staging**.
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/deployments.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ An archive containing your project files to be deployed.

### Raw file

A raw file. For example, a `compose.yml` content when using the [Docker provider](/reference/targets#docker).
A raw file. For example, a `compose.yml` content when using the [Docker provider](/reference/providers/docker).

### Git

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## How does seelf know which services to expose from a `compose.yml` file?

See the [providers page](/reference/targets#docker) for more information.
See the [providers page](/reference/providers/docker#exposing-services) for more information.

## Integrating seelf in your CI

Expand Down
4 changes: 4 additions & 0 deletions docs/reference/jobs.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ A number of **background tasks** are managed by **seelf**. You can check the job

For the vast majority of cases, you may never have to look at them as they are processed without issues.

::: info
By default, **jobs in error** state are retried every **15 seconds**. This is because some errors (such as the `target_configuration_in_progress`) are expected and will delay the job.
:::

## Cancellation

Since a target on which you have, in the past, successfully deployed something can be destroyed from your side, **seelf** provides the ability to **cancel some tasks**.
Expand Down
5 changes: 5 additions & 0 deletions docs/reference/providers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Providers

Depending on which provider you choose for your [target](/reference/targets), you'll have access to different parameters. See the provider reference for more information:

- [Docker](/reference/providers/docker)
138 changes: 138 additions & 0 deletions docs/reference/providers/docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Docker provider

Uses [Docker Compose](https://docs.docker.com/compose/) to launch your services by looking in the project root for specific files and configure an appropriate [traefik proxy](https://doc.traefik.io/traefik/) to expose your services.

::: warning
[Docker >= (v18.0.9) must be installed](https://docs.docker.com/get-docker/) on the target!

Docker engine `v1.41` can sometimes cause issues when attaching multiple networks on container creation. If you have any issue, consider updating.
:::

## Files looked at

When trying to process a single [deployment](/reference/deployments), it will try to find a compose file in the following order at the **project root**:

```
compose.seelf.ENVIRONMENT.yml
compose.seelf.ENVIRONMENT.yaml
docker-compose.seelf.ENVIRONMENT.yml
docker-compose.seelf.ENVIRONMENT.yaml
compose.ENVIRONMENT.yml
compose.ENVIRONMENT.yaml
docker-compose.ENVIRONMENT.yml
docker-compose.ENVIRONMENT.yaml
compose.seelf.yml
compose.seelf.yaml
docker-compose.seelf.yml
docker-compose.seelf.yaml
compose.yml
compose.yaml
docker-compose.yml
docker-compose.yaml
```

Where `ENVIRONMENT` will be one of `production`, `staging`.

## Exposing services

Once a valid compose file has been found, **seelf** will apply some **heuristics** to determine which services should be exposed and where.

It will consider any service with **port mappings** to be exposed.

::: info Why relying on **ports mappings**?
When working on a local compose stack, you make **services available by defining ports mappings**. By using this **heuristic**, we make the transition from local to remote a breeze.
:::

::: warning Exposing TCP and UDP ports
When you don't define a specific protocol, **compose** falls back to `tcp` when reading the project file. When exposing services, the distinction between `http` and `tcp` is mandatory for the proxy to work as intended.

To make the distinction, **seelf** rely on how ports are defined in the compose file:

- **Without a specific protocol** (ex `- "8080:80"`), seelf will assumes it should use an `http` router.
- **With a specific protocol** (ex `- "8080:80/tcp"` or `- "8080:80/udp"`), it will use the router associated: `tcp` or `udp`.

Using this tiny rule, **seelf** can determine the router to use correctly and your compose file **still works locally**.
:::

The first service in **alphabetical order** using an `http` router will take the [default application subdomain](/reference/applications#environments). Every other services exposed will be on a subdomain of that default one.

If some services uses custom entrypoints, the target will be [reconfigured](/reference/targets#configuration) automatically to **make them available**.

::: warning Proxy unavailability
Currently, the proxy to handle the default http entrypoints and custom ones is **shared** meaning there is a **tiny unavailability** when new entrypoints should be exposed (the first time they are seen or when they are no more needed).

In the future, it will be possible to deploy a sidecar proxy specifically for custom entrypoints to prevent this, see [this issue](https://github.com/YuukanOO/seelf/issues/62).
:::

## Labels appended by seelf

To identify which resources are managed by seelf, some **docker labels** are appended during the deployment process. Some labels such as `app.seelf.application`, `app.seelf.target`, `app.seelf.environment` and `app.seelf.custom_entrypoints` are appended to each resources: container, networks, volumes and images built while the others labels are only appended to the container.

| Name | Description |
| ---------------------------- | -------------------------------------------------------------------------------------- |
| app.seelf.exposed | Only used to identify the seelf container when exposing it through a local target |
| app.seelf.application | ID of the application |
| app.seelf.environment | [Environment](/reference/applications#environments) of the resource |
| app.seelf.target | ID of the target on which the container must be exposed |
| app.seelf.subdomain | Subdomain on which a container will be available, used as a default rule for the proxy |
| app.seelf.custom_entrypoints | Appended on a service which uses custom entrypoints |

Using those labels, you can easily filter resources managed by seelf, such as:

```sh
docker container ls --filter "label=app.seelf.target"
```

## Example

Let's take an example for an application registered with the name `sandbox` and a `production` deployment on a local target with the url set to `http://docker.localhost` and a `compose.yml` file at its root:

```yml
services:
app:
restart: unless-stopped
build: .
environment:
- DSN=postgres://app:apppa55word@db/app?sslmode=disable
depends_on:
- db
ports:
- "8080:8080"
sidecar:
image: traefik/whoami
ports:
- "8889:80"
profiles:
- production
stagingonly:
image: traefik/whoami
ports:
- "8888:80"
profiles:
- staging
db:
restart: unless-stopped
image: postgres:14-alpine
# if you wish to expose the db service, don't forget the /tcp !
# ports:
# - "5432:5432/tcp"
volumes:
- dbdata:/var/lib/postgresql/data
environment:
- POSTGRES_USER=app
- POSTGRES_PASSWORD=apppa55word
volumes:
dbdata:
```
When deploying this project on seelf, it will:
- Build an image for the `app` service named `sandbox-<application id>/app:production`
- Expose the `app` service on the default subdomain `http://sandbox.docker.localhost` because that's the first service in **alphabetical order** which has **ports mappings defined**. If environment variables has been defined for the `app` service in the production environment, they will overwrite what's in the compose file
- expose the `sidecar` service on `http://sidecar.sandbox.docker.localhost` because it has port mappings too and the **production profile** is activated
- skip the `stagingonly` service because we have requested a production deployment
- run the `db` service without exposing it because it does not have port mappings defined and has such will be kept private and use any environment variables defined for the `db` service in the production environment.

::: info
If you uncomment the `db` ports part, the db will be exposed using a custom entrypoint and a port will be allocated to handle it.
:::
124 changes: 7 additions & 117 deletions docs/reference/targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,137 +6,27 @@ Targets represents an **host** where your deployments will be exposed. When conf
For now, only one target per host is allowed.
:::

## Providers {#providers}

You must choose one provider kind when creating a target. Some providers have specific parameters for you to configure how things work.

::: warning
Whatever provider you choose, you should make sure your **DNS is correctly configured with a wildcard redirecting to the target host**, the [DigitalOcean procedure](https://docs.digitalocean.com/glossary/wildcard-record/) can be applied to your specific provider.
:::
## Url

### Docker

Uses [Docker Compose](https://docs.docker.com/compose/) to launch your services by looking in the project root for specific files.

::: warning
[Docker >= (v18.0.9) must be installed](https://docs.docker.com/get-docker/) on the target!

Docker engine `v1.41` can sometimes cause issues when attaching multiple networks on container creation. If you have any issue, consider updating.
:::
The url **determine where your applications will be made available**. It should be a **root url** as applications will use subdomains on it.

#### Files looked at
The scheme associated with this url (`http` or `https`) will determine if certificates should be generated or not.

When trying to process a single [deployment](/reference/deployments), it will try to find a compose file in the following order at the **project root**:

```
compose.seelf.ENVIRONMENT.yml
compose.seelf.ENVIRONMENT.yaml
docker-compose.seelf.ENVIRONMENT.yml
docker-compose.seelf.ENVIRONMENT.yaml
compose.ENVIRONMENT.yml
compose.ENVIRONMENT.yaml
docker-compose.ENVIRONMENT.yml
docker-compose.ENVIRONMENT.yaml
compose.seelf.yml
compose.seelf.yaml
docker-compose.seelf.yml
docker-compose.seelf.yaml
compose.yml
compose.yaml
docker-compose.yml
docker-compose.yaml
```

Where `ENVIRONMENT` will be one of `production`, `staging`.

#### Exposing services

Once a valid compose file has been found, **seelf** will apply some **heuristics** to determine which services should be exposed and where.

It will consider any service with **port mappings** to be exposed.

::: info Why relying on **ports mappings**?
When working on a local compose stack, you make **services available by defining ports mappings**. By using this **heuristic**, we make the transition from local to remote a breeze.
:::
## Providers {#providers}

The first service in **alphabetical order** will take the [default application subdomain](/reference/applications#environments). Every other services exposed will be on a subdomain of that default one.
You must choose one provider kind when creating a target. Some providers have specific parameters for you to configure how things work. See the [providers reference](/reference/providers) for more informations.

::: warning
For now, only **one port exposed per service** is allowed and **only HTTP** services can be exposed. Exposing TCP or UDP services is on [the roadmap](https://github.com/YuukanOO/seelf/issues/17).
Whatever provider you choose, you should make sure your **DNS is correctly configured with a wildcard redirecting to the target host**, the [DigitalOcean procedure](https://docs.digitalocean.com/glossary/wildcard-record/) can be applied to your specific provider.
:::

#### Labels appended by seelf

To identify which resources are managed by seelf, some **docker labels** are appended during the deployment process. Some labels such as `app.seelf.application`, `app.seelf.target` and `app.seelf.environment` are appended to each resources: container, networks, volumes and images built while the others labels are only appended to the container.

| Name | Description |
| --------------------- | -------------------------------------------------------------------------------------- |
| app.seelf.exposed | Only used to identify the seelf container when exposing it through a local target |
| app.seelf.application | ID of the application |
| app.seelf.environment | [Environment](/reference/applications#environments) of the resource |
| app.seelf.target | ID of the target on which the container must be exposed |
| app.seelf.subdomain | Subdomain on which a container will be available, used as a default rule for the proxy |

Using those labels, you can easily filter resources managed by seelf, such as:

```sh
docker container ls --filter "label=app.seelf.target"
```

#### Example

Let's take an example for an application registered with the name `sandbox` and a `production` deployment on a local target with the url set to `http://docker.localhost` and a `compose.yml` file at its root:

```yml
services:
app:
restart: unless-stopped
build: .
environment:
- DSN=postgres://app:apppa55word@db/app?sslmode=disable
depends_on:
- db
ports:
- "8080:8080"
sidecar:
image: traefik/whoami
ports:
- "8889:80"
profiles:
- production
stagingonly:
image: traefik/whoami
ports:
- "8888:80"
profiles:
- staging
db:
restart: unless-stopped
image: postgres:14-alpine
volumes:
- dbdata:/var/lib/postgresql/data
environment:
- POSTGRES_USER=app
- POSTGRES_PASSWORD=apppa55word
volumes:
dbdata:
```
When deploying this project on seelf, it will:
- Build an image for the `app` service named `sandbox-<application id>/app:production`
- Expose the `app` service on the default subdomain `http://sandbox.docker.localhost` because that's the first service in **alphabetical order** which has **ports mappings defined**. If environment variables has been defined for the `app` service in the production environment, they will overwrite what's in the compose file
- expose the `sidecar` service on `http://sidecar.sandbox.docker.localhost` because it has port mappings too and the **production profile** is activated
- skip the `stagingonly` service because we have requested a production deployment
- run the `db` service without exposing it because it does not have port mappings defined and has such will be kept private and use any environment variables defined for the `db` service in the production environment.

## Remote targets

When configuring a remote target, you'll **have to add** the public key associated with the private one you'll be using to connect to the host to the `~/.ssh/authorized_keys` file. You can check the [Digital Ocean documentation](https://docs.digitalocean.com/products/droplets/how-to/add-ssh-keys/to-existing-droplet/#with-ssh) for more information.

## Configuration {#configuration}

When creating a target or updating its URL / provider configuration, a **configuration process** will occur to make sure the target is ready to handle deployments. This [task](/reference/jobs) will deploy the [traefik proxy](https://doc.traefik.io/traefik/) and configure it accordingly.
When creating a target, updating its url / provider configuration or when new custom entrypoints should be created to handle custom ports, a **configuration process** will occur to make sure the target is ready to handle deployments. This [task](/reference/jobs) will deploy the needed infrastructure on the target.

::: info
If you messed your server up, you can **reconfigure** a target by clicking the corresponding button on the interface. It will relaunch the configuration process.
Expand Down

0 comments on commit cef099f

Please sign in to comment.