diff --git a/docs/guide/quickstart.md b/docs/guide/quickstart.md index e6dfe67..71e2504 100644 --- a/docs/guide/quickstart.md +++ b/docs/guide/quickstart.md @@ -8,7 +8,7 @@ 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/faq#services-exposal) and manage **domains** and **certificates** for you. +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. 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**. diff --git a/docs/reference/applications.md b/docs/reference/applications.md index 4576d24..6c8daa3 100644 --- a/docs/reference/applications.md +++ b/docs/reference/applications.md @@ -4,7 +4,7 @@ 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/faq#services-exposal) 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/targets#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. @@ -30,7 +30,7 @@ This prevent a target from having dangling applications. ### Production -Represents the main environment. The default service will be exposed on `://.`. Any additional exposed services will add another level such as `://..`. +Represents the main environment. The **default service** will be exposed on `://.`. Any additional exposed services will add another level such as `://..`. ### Staging diff --git a/docs/reference/faq.md b/docs/reference/faq.md index 0578138..6b9e6de 100644 --- a/docs/reference/faq.md +++ b/docs/reference/faq.md @@ -1,104 +1,8 @@ # Frequently asked question -## How does seelf know which services to expose from a `compose.yml` file? {#services-exposal} +## How does seelf know which services to expose from a `compose.yml` file? -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`. - -Whatever method you choose when deploying your application, seelf will look for a compose file at the root of a deployment build directory in this order: - -::: info -In this list, `production` represents the actual environment name and will vary depending on where the deployment is occuring (`production` or `staging`). -::: - -``` -- compose.seelf.production.yml -- compose.seelf.production.yaml -- docker-compose.seelf.production.yml -- docker-compose.seelf.production.yaml -- compose.production.yml -- compose.production.yaml -- docker-compose.production.yml -- docker-compose.production.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 -``` - -Once it has found a valid compose file, it will apply some **heuristics** to determine which services should be exposed and where. - -Let's say you have this `compose.yml` file: - -```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. - -::: 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. -::: - -To expose those services, seelf will add appropriate container labels related to the target on which they should be exposed. - -## Docker labels appended by seelf - -To identify which resources are managed by seelf, some **docker labels** are appended during the deployment process. - -| 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" -``` +See the [providers page](/reference/targets#docker) for more information. ## Integrating seelf in your CI diff --git a/docs/reference/targets.md b/docs/reference/targets.md index 219ba23..95e53f5 100644 --- a/docs/reference/targets.md +++ b/docs/reference/targets.md @@ -11,17 +11,123 @@ For now, only one target per host is allowed. 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**. +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. ::: ### Docker -The only supported provider for now. Uses **Docker Compose** to launch your services by looking in the project root for specific files, see [services exposal](/reference/faq#services-exposal). +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! ::: +#### 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. +::: + +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. + +::: 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). +::: + +#### 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.