diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 5761579..2732ccf 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -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", diff --git a/docs/guide/quickstart.md b/docs/guide/quickstart.md index 71e2504..5406358 100644 --- a/docs/guide/quickstart.md +++ b/docs/guide/quickstart.md @@ -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/). diff --git a/docs/reference/api.md b/docs/reference/api.md index fc5a6a2..efba142 100644 --- a/docs/reference/api.md +++ b/docs/reference/api.md @@ -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. diff --git a/docs/reference/applications.md b/docs/reference/applications.md index 6c8daa3..feaa2a5 100644 --- a/docs/reference/applications.md +++ b/docs/reference/applications.md @@ -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**. diff --git a/docs/reference/deployments.md b/docs/reference/deployments.md index 1f34df3..a3014d5 100644 --- a/docs/reference/deployments.md +++ b/docs/reference/deployments.md @@ -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 diff --git a/docs/reference/faq.md b/docs/reference/faq.md index 6b9e6de..9b82a38 100644 --- a/docs/reference/faq.md +++ b/docs/reference/faq.md @@ -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 diff --git a/docs/reference/jobs.md b/docs/reference/jobs.md index 29dba85..4e21a8f 100644 --- a/docs/reference/jobs.md +++ b/docs/reference/jobs.md @@ -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**. diff --git a/docs/reference/providers.md b/docs/reference/providers.md new file mode 100644 index 0000000..5f0cb0b --- /dev/null +++ b/docs/reference/providers.md @@ -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) diff --git a/docs/reference/providers/docker.md b/docs/reference/providers/docker.md new file mode 100644 index 0000000..9453cbf --- /dev/null +++ b/docs/reference/providers/docker.md @@ -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-/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. +::: diff --git a/docs/reference/targets.md b/docs/reference/targets.md index 55c1989..5dedd74 100644 --- a/docs/reference/targets.md +++ b/docs/reference/targets.md @@ -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-/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.