From 4f3c608c9ae9f00afc37734c2c636e218ccd9a92 Mon Sep 17 00:00:00 2001 From: Yar Kravtsov Date: Sun, 19 Jan 2025 12:24:23 +0200 Subject: [PATCH] docs: enhance configuration guide with defaults and environment variables --- www/.vitepress/config.mts | 203 ++++++++++--------- www/.vitepress/theme/index.ts | 16 +- www/.vitepress/theme/style.css | 6 +- www/.vitepress/theme/vars.css | 82 ++++---- www/docs/configuration/dependencies.md | 119 +++++++---- www/docs/configuration/index.md | 4 +- www/docs/configuration/services.md | 32 ++- www/docs/core-tasks/building.md | 40 ++-- www/docs/core-tasks/deployment.md | 177 +++++++++------- www/docs/getting-started/configuration.md | 129 +++++++----- www/docs/getting-started/first-deployment.md | 36 +--- www/docs/guides/health-checks.md | 164 ++------------- www/docs/guides/ssl-management.md | 3 - www/docs/guides/zero-downtime.md | 122 ++++------- www/docs/index.md | 3 +- www/docs/reference/configuration-file.md | 192 +++++++++++------- 16 files changed, 662 insertions(+), 666 deletions(-) diff --git a/www/.vitepress/config.mts b/www/.vitepress/config.mts index 2deab1b..559a4ac 100644 --- a/www/.vitepress/config.mts +++ b/www/.vitepress/config.mts @@ -1,111 +1,116 @@ import { defineConfig } from "vitepress"; import { withMermaid } from "vitepress-plugin-mermaid"; -export default withMermaid(defineConfig({ - title: "FTL Documentation", - description: "Documentation for FTL - Faster Than Light Deployment Tool", - srcDir: "./docs", +export default withMermaid( + defineConfig({ + title: "FTL Documentation", + description: "Documentation for FTL - Faster Than Light Deployment Tool", + srcDir: "./docs", - markdown: { - theme: { - light: 'github-light', - dark: 'github-dark' + markdown: { + theme: { + light: "github-light", + dark: "github-dark", + }, + languages: ["yaml", "bash", "javascript", "json", "dockerfile"], }, - languages: ['yaml', 'bash', 'javascript', 'json', 'dockerfile'] - }, - themeConfig: { - nav: [ - { text: "Home", link: "/" }, - { text: "Getting Started", link: "/getting-started/" }, - { text: "Core Tasks", link: "/core-tasks/" }, - { text: "Configuration", link: "/configuration/" }, - { text: "Guides", link: "/guides/" }, - { text: "Reference", link: "/reference/" } - ], - - sidebar: { - "/": [ - { - text: "Getting Started", - collapsed: false, - items: [ - { text: "Introduction", link: "/getting-started/" }, - { text: "Installation", link: "/getting-started/installation" }, - { text: "Configuration", link: "/getting-started/configuration" }, - { - text: "First Deployment", - link: "/getting-started/first-deployment", - }, - ], - }, - { - text: "Core Tasks", - collapsed: false, - items: [ - { text: "Overview", link: "/core-tasks/" }, - { text: "Server Setup", link: "/core-tasks/server-setup" }, - { text: "Building", link: "/core-tasks/building" }, - { text: "Deployment", link: "/core-tasks/deployment" }, - { text: "Logging", link: "/core-tasks/logging" }, - { text: "Tunneling", link: "/core-tasks/tunneling" }, - ], - }, - { - text: "Configuration", - collapsed: true, - items: [ - { text: "Overview", link: "/configuration/" }, - { - text: "Project Settings", - link: "/configuration/project-settings", - }, - { text: "Services", link: "/configuration/services" }, - { text: "Dependencies", link: "/configuration/dependencies" }, - { text: "Volumes", link: "/configuration/volumes" }, - ], - }, - { - text: "Guides", - collapsed: true, - items: [ - { text: "Overview", link: "/guides/" }, - { text: "Zero-downtime Deployment", link: "/guides/zero-downtime" }, - { text: "Health Checks", link: "/guides/health-checks" }, - { text: "SSL Management", link: "/guides/ssl-management" }, - ], - }, - { - text: "Reference", - collapsed: true, - items: [ - { text: "Overview", link: "/reference/" }, - { text: "CLI Commands", link: "/reference/cli-commands" }, - { - text: "Configuration File", - link: "/reference/configuration-file", - }, - { text: "Environment Variables", link: "/reference/environment" }, - { text: "Troubleshooting", link: "/reference/troubleshooting" }, - ], - }, + themeConfig: { + nav: [ + { text: "Home", link: "/" }, + { text: "Getting Started", link: "/getting-started/" }, + { text: "Core Tasks", link: "/core-tasks/" }, + { text: "Configuration", link: "/configuration/" }, + { text: "Guides", link: "/guides/" }, + { text: "Reference", link: "/reference/" }, ], - }, - socialLinks: [{ icon: "github", link: "https://github.com/yarlson/ftl" }], + sidebar: { + "/": [ + { + text: "Getting Started", + collapsed: false, + items: [ + { text: "Introduction", link: "/getting-started/" }, + { text: "Installation", link: "/getting-started/installation" }, + { text: "Configuration", link: "/getting-started/configuration" }, + { + text: "First Deployment", + link: "/getting-started/first-deployment", + }, + ], + }, + { + text: "Core Tasks", + collapsed: false, + items: [ + { text: "Overview", link: "/core-tasks/" }, + { text: "Server Setup", link: "/core-tasks/server-setup" }, + { text: "Building", link: "/core-tasks/building" }, + { text: "Deployment", link: "/core-tasks/deployment" }, + { text: "Logging", link: "/core-tasks/logging" }, + { text: "Tunneling", link: "/core-tasks/tunneling" }, + ], + }, + { + text: "Configuration", + collapsed: true, + items: [ + { text: "Overview", link: "/configuration/" }, + { + text: "Project Settings", + link: "/configuration/project-settings", + }, + { text: "Services", link: "/configuration/services" }, + { text: "Dependencies", link: "/configuration/dependencies" }, + { text: "Volumes", link: "/configuration/volumes" }, + ], + }, + { + text: "Guides", + collapsed: true, + items: [ + { text: "Overview", link: "/guides/" }, + { + text: "Zero-downtime Deployment", + link: "/guides/zero-downtime", + }, + { text: "Health Checks", link: "/guides/health-checks" }, + { text: "SSL Management", link: "/guides/ssl-management" }, + ], + }, + { + text: "Reference", + collapsed: true, + items: [ + { text: "Overview", link: "/reference/" }, + { text: "CLI Commands", link: "/reference/cli-commands" }, + { + text: "Configuration File", + link: "/reference/configuration-file", + }, + { text: "Environment Variables", link: "/reference/environment" }, + { text: "Troubleshooting", link: "/reference/troubleshooting" }, + ], + }, + ], + }, - footer: { - message: "Released under the MIT License.", - copyright: "Copyright © 2024-present FTL Contributors", - }, + socialLinks: [{ icon: "github", link: "https://github.com/yarlson/ftl" }], - search: { - provider: "local", - }, + footer: { + message: "Released under the MIT License.", + copyright: "Copyright © 2024-present FTL Contributors", + }, + + search: { + provider: "local", + }, - outline: { - level: [2, 3], - label: "On this page", + outline: { + level: [2, 3], + label: "On this page", + }, }, - }, -})); + }), +); diff --git a/www/.vitepress/theme/index.ts b/www/.vitepress/theme/index.ts index a94e7d1..f776258 100644 --- a/www/.vitepress/theme/index.ts +++ b/www/.vitepress/theme/index.ts @@ -1,18 +1,18 @@ // https://vitepress.dev/guide/custom-theme -import { h } from 'vue' -import type { Theme } from 'vitepress' -import DefaultTheme from 'vitepress/theme' -import './vars.css' -import './style.css' +import { h } from "vue"; +import type { Theme } from "vitepress"; +import DefaultTheme from "vitepress/theme"; +import "./vars.css"; +import "./style.css"; export default { extends: DefaultTheme, Layout: () => { return h(DefaultTheme.Layout, null, { // https://vitepress.dev/guide/extending-default-theme#layout-slots - }) + }); }, enhanceApp({ app, router, siteData }) { // ... - } -} satisfies Theme + }, +} satisfies Theme; diff --git a/www/.vitepress/theme/style.css b/www/.vitepress/theme/style.css index 80ac341..422896d 100755 --- a/www/.vitepress/theme/style.css +++ b/www/.vitepress/theme/style.css @@ -17,7 +17,9 @@ --vp-c-brand-soft: var(--flexoki-blue-100); /* Buttons with improved contrast */ - --vp-button-brand-bg: var(--flexoki-blue-700); /* Darkened for better contrast on white */ + --vp-button-brand-bg: var( + --flexoki-blue-700 + ); /* Darkened for better contrast on white */ --vp-button-brand-hover-bg: var(--flexoki-blue-800); --vp-button-brand-active-bg: var(--flexoki-blue-900); @@ -74,7 +76,7 @@ --vp-c-bg-alt: var(--flexoki-850); /* Adjusted text colors for better contrast */ - --vp-c-text-1: var(--flexoki-50); /* Lightened from 100 */ + --vp-c-text-1: var(--flexoki-50); /* Lightened from 100 */ --vp-c-text-2: var(--flexoki-200); /* Lightened from 300 */ --vp-c-text-3: var(--flexoki-300); /* Lightened from 400 */ diff --git a/www/.vitepress/theme/vars.css b/www/.vitepress/theme/vars.css index 2e06541..fbd3e35 100755 --- a/www/.vitepress/theme/vars.css +++ b/www/.vitepress/theme/vars.css @@ -1,63 +1,63 @@ :root { /* Base colors */ - --flexoki-black: #100F0F; - --flexoki-paper: #FFFCF0; + --flexoki-black: #100f0f; + --flexoki-paper: #fffcf0; /* Base scale */ - --flexoki-50: #F2F0E5; - --flexoki-100: #E6E4D9; - --flexoki-150: #DAD8CE; - --flexoki-200: #CECDC3; - --flexoki-300: #B7B5AC; - --flexoki-400: #9F9D96; + --flexoki-50: #f2f0e5; + --flexoki-100: #e6e4d9; + --flexoki-150: #dad8ce; + --flexoki-200: #cecdc3; + --flexoki-300: #b7b5ac; + --flexoki-400: #9f9d96; --flexoki-500: #878580; - --flexoki-600: #6F6E69; + --flexoki-600: #6f6e69; --flexoki-700: #575653; - --flexoki-800: #403E3C; + --flexoki-800: #403e3c; --flexoki-850: #343331; --flexoki-900: #282726; - --flexoki-950: #1C1B1A; + --flexoki-950: #1c1b1a; /* Blue */ - --flexoki-blue-50: #E1ECEB; - --flexoki-blue-100: #C6DDE8; - --flexoki-blue-200: #92BFDB; - --flexoki-blue-300: #66A0C8; - --flexoki-blue-400: #4385BE; - --flexoki-blue-500: #3171B2; - --flexoki-blue-600: #205EA6; - --flexoki-blue-700: #1A4F8C; - --flexoki-blue-900: #12253B; + --flexoki-blue-50: #e1eceb; + --flexoki-blue-100: #c6dde8; + --flexoki-blue-200: #92bfdb; + --flexoki-blue-300: #66a0c8; + --flexoki-blue-400: #4385be; + --flexoki-blue-500: #3171b2; + --flexoki-blue-600: #205ea6; + --flexoki-blue-700: #1a4f8c; + --flexoki-blue-900: #12253b; /* Red */ - --flexoki-red-50: #FFE1D5; - --flexoki-red-300: #E8705F; - --flexoki-red-400: #D14D41; - --flexoki-red-600: #AF3029; + --flexoki-red-50: #ffe1d5; + --flexoki-red-300: #e8705f; + --flexoki-red-400: #d14d41; + --flexoki-red-600: #af3029; --flexoki-red-700: #942822; --flexoki-red-950: #261312; /* Green */ - --flexoki-green-50: #EDEECF; - --flexoki-green-300: #A0AF54; - --flexoki-green-400: #879A39; - --flexoki-green-600: #66800B; + --flexoki-green-50: #edeecf; + --flexoki-green-300: #a0af54; + --flexoki-green-400: #879a39; + --flexoki-green-600: #66800b; --flexoki-green-700: #536907; - --flexoki-green-950: #1A1E0C; + --flexoki-green-950: #1a1e0c; /* Yellow */ - --flexoki-yellow-50: #FAEEC6; - --flexoki-yellow-300: #DFB431; - --flexoki-yellow-400: #D0A215; - --flexoki-yellow-600: #AD8301; - --flexoki-yellow-700: #8E6B01; - --flexoki-yellow-950: #241E08; + --flexoki-yellow-50: #faeec6; + --flexoki-yellow-300: #dfb431; + --flexoki-yellow-400: #d0a215; + --flexoki-yellow-600: #ad8301; + --flexoki-yellow-700: #8e6b01; + --flexoki-yellow-950: #241e08; /* Magenta */ - --flexoki-magenta-50: #FEE4E5; - --flexoki-magenta-300: #E47DA8; - --flexoki-magenta-400: #CE5D97; - --flexoki-magenta-600: #A02F6F; - --flexoki-magenta-700: #87285E; - --flexoki-magenta-950: #24131D; + --flexoki-magenta-50: #fee4e5; + --flexoki-magenta-300: #e47da8; + --flexoki-magenta-400: #ce5d97; + --flexoki-magenta-600: #a02f6f; + --flexoki-magenta-700: #87285e; + --flexoki-magenta-950: #24131d; } diff --git a/www/docs/configuration/dependencies.md b/www/docs/configuration/dependencies.md index eac4674..e6f3f6e 100755 --- a/www/docs/configuration/dependencies.md +++ b/www/docs/configuration/dependencies.md @@ -5,61 +5,112 @@ description: Configure supporting services like databases for your FTL deploymen # Dependencies Configuration -The `dependencies` section defines supporting services like databases that your application requires. +The `dependencies` section defines supporting services (such as databases, caches, or message queues) that your application requires. You can declare each dependency in one of two ways: -## Configuration Fields +- **Short Notation** – Simply specify the service name and optional version (for example, `"mysql:8"`, `"postgres:16"`, or `"redis"`). When using short notation, FTL automatically applies default settings such as typical ports, volumes, and environment variables. +- **Detailed Definition** – Provide a full configuration (with fields like `name`, `image`, `volumes`, and `env`) for additional customization or for services where you want to override the defaults. + +## Default Configurations + +For many popular services, FTL supplies default settings including: + +- **Image Tag**: The default Docker image (e.g. `"postgres:latest"`) is modified by specifying a version. For example, `"postgres:16"` sets the image to `postgres:16`. +- **Ports**: Typical ports are preconfigured (e.g. `5432` for PostgreSQL, `3306` for MySQL). +- **Volumes**: Default named volumes are provided (e.g. `postgres_data:/var/lib/postgresql/data`). +- **Environment Variables**: Common environment variables include placeholders that support expansion. For example: + ```yaml + env: + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-production-secret} + - POSTGRES_USER=${POSTGRES_USER:-postgres} + - POSTGRES_DB=${POSTGRES_DB:-app} + ``` + +### Using Short Notation + +When you declare a dependency using short notation, FTL will merge the dependency with default values. For example: + +```yaml +dependencies: + - "mysql:8" + - "redis" +``` + +- `"mysql:8"`: FTL sets the dependency name to `mysql`, uses the image `mysql:8`, and automatically applies defaults for ports (e.g. `3306`), a named volume (e.g. `mysql_data:/var/lib/mysql`), and environment variables (e.g. `MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-secret}`). +- `"redis"`: FTL uses the image `redis:latest` and applies defaults for ports, volumes, and environment variables as defined by its default configuration. + +### Providing a Detailed Definition + +If you need to customize settings beyond the defaults, or if you are using a service that does not have a preset configuration, you can provide a detailed definition: ```yaml dependencies: - - name: postgres - image: postgres:16 + - name: "postgres" + image: "postgres:16" volumes: - - postgres_data:/var/lib/postgresql/data + - my_pg_data:/custom/postgres/path env: - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_USER=${POSTGRES_USER:-postgres} - - POSTGRES_DB=${POSTGRES_DB:-app} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-secret} + - POSTGRES_USER=${POSTGRES_USER:-myuser} ``` -| Field | Description | -| --------- | ---------------------------------------- | -| `name` | Unique identifier for the dependency | -| `image` | Docker image to use for this dependency | -| `volumes` | Volume mounts for persistent storage | -| `env` | Environment variables for the dependency | +This approach gives you full control over the dependency configuration, allowing you to override default ports, volume mappings, or environment variables. + +## Environment Variable Expansion + +FTL supports environment variable expansion in dependency configurations. You can use the following patterns: -## Environment Variables +- **Optional with default**: -Dependencies support environment variable substitution with required variables and optional variables with defaults: + ```yaml + SOME_VAR=${SOME_VAR:-defaultValue} + ``` + + If `SOME_VAR` is not set, `defaultValue` is used. + +- **Required**: + + ```yaml + SOME_VAR=${SOME_VAR:?error message} + ``` + + FTL will produce an error if `SOME_VAR` is not set. + +- **Plain reference**: + ```yaml + SOME_VAR=${SOME_VAR} + ``` + This inserts the current value of `SOME_VAR` (or an empty string if it’s not set, depending on configuration). + +## Examples + +### Short Notation (Using Defaults) ```yaml dependencies: - - name: postgres - env: - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} # Required - - POSTGRES_USER=${POSTGRES_USER:-postgres} # Optional with default - - POSTGRES_DB=${POSTGRES_DB:-app} # Optional with default + - "redis:7" + - "postgres:16" ``` -Required variables must be set in the environment before running FTL commands. Optional variables will use their default values if not set. +This configuration: + +- Sets the dependency for Redis to use the image `redis:7` and applies default settings for ports, volumes, and environment variables. +- Sets the PostgreSQL dependency to use the image `postgres:16` with default named volumes and environment variable expansion (for example, `POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-production-secret}`). -## Example +### Detailed Definition for Customization ```yaml dependencies: - - name: postgres - image: postgres:16 + - name: "postgres" + image: "postgres:16" volumes: - - postgres_data:/var/lib/postgresql/data + - my_pg_data:/custom/postgres/path env: - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_USER=${POSTGRES_USER:-postgres} - - POSTGRES_DB=${POSTGRES_DB:-app} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-secret} + - POSTGRES_USER=${POSTGRES_USER:-myuser} ``` -This configuration: +In this case, you explicitly override the default volume mapping and environment variable settings for PostgreSQL. + +--- -- Creates a PostgreSQL database service -- Uses the official PostgreSQL 16 image -- Mounts persistent storage for the database -- Sets required and optional environment variables +By using short notation, you can quickly set up dependencies with sensible defaults, while a detailed definition gives you the power to fine-tune settings when needed. Environment variable expansion ensures that sensitive values and deployment-specific settings are managed dynamically. diff --git a/www/docs/configuration/index.md b/www/docs/configuration/index.md index 3443bb9..d8c3c21 100755 --- a/www/docs/configuration/index.md +++ b/www/docs/configuration/index.md @@ -33,9 +33,7 @@ server: services: - name: web - build: - context: . - dockerfile: Dockerfile + path: ./src port: 3000 routes: - path: / diff --git a/www/docs/configuration/services.md b/www/docs/configuration/services.md index 0cc0004..58c72bc 100755 --- a/www/docs/configuration/services.md +++ b/www/docs/configuration/services.md @@ -12,22 +12,20 @@ The `services` section defines your application services that will be deployed a ```yaml services: - name: web - build: - context: . - dockerfile: Dockerfile + path: ./src port: 3000 routes: - path: / ``` -| Field | Description | -| -------- | ---------------------------------------------------- | -| `name` | Unique identifier for the service | -| `build` | Docker build configuration for the service | -| `port` | Port that the service listens on | -| `routes` | HTTP route configuration for the Nginx reverse proxy | +| Field | Description | +| -------- | ------------------------------------------------------------------------------ | +| `name` | Unique identifier for the service | +| `path` | Path to directory containing Dockerfile and source code (relative to ftl.yaml) | +| `port` | Port that the service listens on | +| `routes` | HTTP route configuration for the Nginx reverse proxy | -## Build Configuration +## Image Configuration You can specify how to build your service's Docker image in two ways: @@ -38,9 +36,7 @@ When no `image` field is specified, FTL will build and transfer the image direct ```yaml services: - name: web - build: - context: . - dockerfile: Dockerfile + path: ./src ``` ### Registry-based Deployment @@ -51,9 +47,7 @@ When using a Docker registry: services: - name: web image: registry.example.com/my-app:latest - build: - context: . - dockerfile: Dockerfile + path: ./src ``` ## Health Checks @@ -103,6 +97,7 @@ services: - name: web port: ${PORT} image: ${IMAGE_NAME} + path: ${SOURCE_PATH} ``` All environment variables must be set in the environment before running FTL commands. @@ -113,13 +108,10 @@ All environment variables must be set in the environment before running FTL comm services: - name: my-app image: my-app:latest + path: ./src port: 80 health_check: path: / - interval: 10s - timeout: 5s - retries: 3 routes: - path: / - strip_prefix: false ``` diff --git a/www/docs/core-tasks/building.md b/www/docs/core-tasks/building.md index b3dc8f9..32aacf4 100755 --- a/www/docs/core-tasks/building.md +++ b/www/docs/core-tasks/building.md @@ -31,11 +31,11 @@ When no `image` field is specified in your service configuration, FTL will: ```yaml services: - name: web - build: - context: . - dockerfile: Dockerfile + path: ./src ``` +The path is relative to your `ftl.yaml` file location and should contain your application's source code and Dockerfile. + ::: tip This method is simpler as it doesn't require registry configuration and credentials management. ::: @@ -54,9 +54,7 @@ When you specify the `image` field, FTL will: services: - name: web image: registry.example.com/my-app:latest - build: - context: . - dockerfile: Dockerfile + path: ./src ``` ::: warning @@ -74,13 +72,27 @@ ftl build --skip-push ## Understanding Docker Builds -### Build Context +### Source Code Location + +The source code and Dockerfile should be placed in the directory specified by the `path` field. This path is resolved relative to your `ftl.yaml` file location. For example: + +If your project structure is: -The build context is the set of files located in the specified `context` path. Docker sends this context to the daemon during the build. Keep your context clean to ensure faster builds: +``` +/project + ├── ftl.yaml + └── src + ├── Dockerfile + └── app files... +``` -- Use `.dockerignore` to exclude unnecessary files -- Keep build context as small as possible -- Place Dockerfile in a clean directory if needed +Your configuration would be: + +```yaml +services: + - name: web + path: ./src +``` ### Layer Caching @@ -155,7 +167,7 @@ Benefits: - Leverage Docker layer caching - Use `.dockerignore` effectively - - Keep build context minimal + - Keep source directory clean 6. **Security** - Use official base images @@ -169,7 +181,7 @@ Benefits: If builds are slow: -- Check build context size +- Check source directory size - Optimize layer caching - Use `.dockerignore` appropriately - Consider multi-stage builds @@ -191,8 +203,6 @@ If cache isn't working effectively: - Verify file changes aren't invalidating cache - Use appropriate COPY commands -## Common Issues - ### Registry Authentication If using registry-based deployment: diff --git a/www/docs/core-tasks/deployment.md b/www/docs/core-tasks/deployment.md index 836afad..fd63ba9 100755 --- a/www/docs/core-tasks/deployment.md +++ b/www/docs/core-tasks/deployment.md @@ -5,7 +5,7 @@ description: Learn how to deploy applications with FTL # Deployment -FTL automates the deployment of your applications, handling everything from image transfers to SSL certificate management. +FTL automates the deployment of your applications by taking care of image transfers, volume and network setups, SSL certificate management, and much more. ## Basic Usage @@ -17,46 +17,50 @@ ftl deploy ## Deployment Process -The deployment process follows these steps: +FTL follows these steps when deploying an application: 1. **SSH Connection** - - Connects to your configured server via SSH - - Verifies server access and permissions + - Connects to your configured server via SSH. + - Verifies server access and permissions. 2. **Image Handling** - - For direct SSH transfer (no `image` field): - - Verifies server access and permissions - - Transfers Docker images directly to server - - Uses FTL's layer caching for optimization - - For registry-based deployment (`image` field specified): - - Pulls images from configured registry - - Requires registry authentication (username/password only) + - **Direct Transfer** (when no `image` field is specified): + - Verifies server access and permissions. + - Transfers Docker images directly to the server. + - Uses layer caching for faster transfers. + - **Registry Deployment** (when an `image` field is provided): + - Pulls images from the specified registry. + - Requires registry authentication (username/password). 3. **Environment Setup** - - Sets up volumes and networks - - Configures environment variables - - Starts dependencies if defined + - Creates and attaches named volumes. + - Configures networks. + - Expands and injects environment variables. + - Starts any supporting services defined as dependencies. 4. **Service Deployment** - - Launches services with health checks - - Performs zero-downtime container replacement - - Configures Nginx reverse proxy + - Launches application services with health checks. + - Performs zero-downtime container replacements. + - Configures the Nginx reverse proxy for routing. 5. **SSL/TLS Setup** - - Manages SSL/TLS certificates via ACME - - Configures HTTPS endpoints + - Manages SSL/TLS certificates via ACME. + - Configures HTTPS endpoints for your application. 6. **Cleanup** - - Removes unused containers - - Cleans up temporary resources + + - Removes unused containers. + - Cleans up temporary resources. ## Configuration +FTL uses a YAML configuration file where you define your project, server, services, dependencies, and volumes. FTL supports default settings and dynamic expansion of environment variables. Below are examples for various sections. + ### Basic Service Configuration ```yaml @@ -73,92 +77,121 @@ server: services: - name: web port: 80 + path: ./src health_check: path: / - interval: 10s - timeout: 5s - retries: 3 routes: - path: / - strip_prefix: false ``` ### Dependencies Configuration +Dependencies are used to launch supporting services (for example, databases and caches). You can either use a short notation to take advantage of default settings or provide a full configuration when you need to override defaults. + +**Using default settings:** + +```yaml +dependencies: + - "postgres:16" +``` + +In the above example, FTL will automatically: + +- Set the dependency’s name to `postgres` +- Use the Docker image `postgres:16` +- Configure standard ports and named volumes (e.g. `postgres_data:/var/lib/postgresql/data`) +- Expand environment variables such as: + ```yaml + env: + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_USER=${POSTGRES_USER:-postgres} + - POSTGRES_DB=${POSTGRES_DB:-app} + ``` + +**Overriding defaults:** + ```yaml dependencies: - name: postgres image: postgres:16 volumes: - - postgres_data:/var/lib/postgresql/data + - my_pg_data:/custom/postgres/path env: - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_USER=${POSTGRES_USER:-postgres} - - POSTGRES_DB=${POSTGRES_DB:-app} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-secret} + - POSTGRES_USER=${POSTGRES_USER:-customuser} ``` +When you override defaults, FTL uses your provided values rather than applying the built-in settings. + ### Volume Configuration +Named volumes can be provided explicitly. FTL collects volume names from your services and dependencies. + ```yaml volumes: - postgres_data ``` -## Environment Variables +### Environment Variables + +FTL supports environment variable expansion in all configuration fields. You can define variables as follows: + +- **Required Variables:** + + ```yaml + env: + - DATABASE_URL=${DATABASE_URL} + ``` -FTL supports two types of environment variables: +- **Optional Variables with Defaults:** -1. **Required Variables** + ```yaml + env: + - POSTGRES_USER=${POSTGRES_USER:-postgres} + ``` - ```yaml - env: - - DATABASE_URL=${DATABASE_URL} - ``` +- **Required with Custom Message:** -2. **Optional Variables with Defaults** - ```yaml - env: - - POSTGRES_USER=${POSTGRES_USER:-postgres} - ``` + ```yaml + env: + - API_KEY=${API_KEY:?API_KEY must be set} + ``` ## Health Checks -Health checks ensure your services are running correctly: +Health checks are critical for ensuring that your services are running properly. For example: ```yaml services: - name: api health_check: path: /health - interval: 10s - timeout: 5s - retries: 3 ``` ## Best Practices 1. **Configuration Management** - - Use environment variables for sensitive data - - Keep configuration DRY - - Document all required variables + - Use environment variables to securely manage sensitive data. + - Keep configuration DRY and well-documented. + - Document all required environment variables. 2. **Deployment Strategy** - - Start with dependencies first - - Use health checks for all services - - Monitor logs during deployment + - Start dependent services before deploying the main application. + - Define health checks for every service. + - Monitor logs during deployment for any issues. 3. **Security** - - Use HTTPS for all services - - Keep SSL certificates up to date - - Secure sensitive environment variables + - Use HTTPS for all external communications. + - Regularly update and manage SSL certificates. + - Secure sensitive environment variables with proper expansion patterns. 4. **Monitoring** - - Check service health after deployment - - Monitor resource usage - - Keep track of logs + - Verify service health post-deployment. + - Monitor application resource usage. + - Review logs to proactively address issues. ## Common Issues @@ -166,37 +199,37 @@ services: If services fail health checks: -- Verify the health check endpoint -- Check service logs -- Ensure correct port configuration -- Verify service startup time +- Verify the health check endpoint is correct. +- Inspect service logs. +- Ensure correct port and path configurations. +- Adjust startup time if necessary. ### SSL Certificate Issues -If SSL setup fails: +If SSL/TLS setup fails: -- Verify domain DNS configuration -- Check email configuration -- Ensure ports 80/443 are accessible +- Ensure DNS records are correct. +- Verify email configuration. +- Confirm ports 80 and 443 are accessible. ### Network Issues -If services can't communicate: +If services cannot communicate: -- Check network configuration -- Verify port mappings -- Ensure dependencies are running +- Check your network configuration. +- Verify volume mappings and port exposures. +- Ensure all required services are running. ## Next Steps -After successful deployment: +After deployment: 1. Learn about [Logging](./logging.md) 2. Configure [SSL Management](../guides/ssl-management.md) -3. Explore [Zero-downtime Deployments](../guides/zero-downtime.md) +3. Explore [Zero-Downtime Deployments](../guides/zero-downtime.md) ::: warning -Always verify your application's functionality after deployment. +Always verify your application’s functionality after deployment. ::: ## Reference diff --git a/www/docs/getting-started/configuration.md b/www/docs/getting-started/configuration.md index af2445a..d7ae1bc 100755 --- a/www/docs/getting-started/configuration.md +++ b/www/docs/getting-started/configuration.md @@ -5,7 +5,7 @@ description: Learn how to configure FTL for your project using the ftl.yaml conf # Configuring FTL -FTL uses a single YAML configuration file (`ftl.yaml`) to define your project's deployment settings. This guide will walk you through creating and configuring this file. +FTL uses a single YAML configuration file (`ftl.yaml`) to define your project's deployment settings. This guide walks you through creating and configuring the file to leverage defaults for common settings and dynamic environment variable expansion. ## Basic Configuration Structure @@ -45,9 +45,9 @@ The `project` section defines your project's basic information: ```yaml project: - name: my-project # Required: Project name (used for Docker networks and containers) + name: my-project # Required: used for naming Docker networks and containers domain: example.com # Required: Primary domain for your application - email: admin@example.com # Required: Email for SSL certificate notifications + email: admin@example.com # Required: Contact email for notifications and SSL certificates ``` ### Server Configuration @@ -64,69 +64,100 @@ server: ### Services -The `services` section defines your application services: +The `services` section defines the application services. For many services, you can simply specify the image (or even use environment variable substitution to choose the image) while relying on default settings for aspects like ports, health checks, and routes. ```yaml services: - name: web # Required: Service name - image: my-app:latest # Required: Docker image - port: 80 # Required: Container port to expose + image: ${DOCKER_IMAGE:-my-project:latest} # Uses an environment variable with a default + port: 80 # Required: The port exposed by the container health_check: # Optional but recommended - path: /health # Health check endpoint - interval: 10s # Check interval - timeout: 5s # Check timeout - retries: 3 # Retries before marking unhealthy + path: / # Health check endpoint + interval: 10s # Frequency of health checks + timeout: 5s # Timeout for each check + retries: 3 # Number of retries before considering the service unhealthy routes: # Required: HTTP routing rules - path: / # URL path to match - strip_prefix: false # Whether to remove prefix before forwarding + strip_prefix: false # Whether to remove the prefix before forwarding requests ``` ### Dependencies -Define service dependencies like databases: +Use the `dependencies` section to define supporting services—such as databases or caches—that your application requires. When you reference a service by a short identifier (for example, `"postgres:16"`, `"mysql:8"`, or `"redis"`), FTL automatically applies default configurations (including typical ports, named volumes, and environment variable substitutions). You can also override these defaults by specifying fields explicitly. + +**Example using defaults:** + +```yaml +dependencies: + - "postgres:16" +``` + +This sets up a PostgreSQL dependency with: + +- The image set to `postgres:16` +- A default named volume (e.g. `postgres_data:/var/lib/postgresql/data`) +- Preconfigured environment variables such as: + ```yaml + env: + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_USER=${POSTGRES_USER:-postgres} + - POSTGRES_DB=${POSTGRES_DB:-app} + ``` + +**Example with custom settings:** ```yaml dependencies: - name: postgres image: postgres:16 volumes: - - postgres_data:/var/lib/postgresql/data + - my_pg_data:/custom/postgres/path env: - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_USER=${POSTGRES_USER:-postgres} - - POSTGRES_DB=${POSTGRES_DB:-app} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-secret} + - POSTGRES_USER=${POSTGRES_USER:-customuser} ``` ### Volumes -Declare persistent volumes: +Declare persistent storage volumes explicitly. FTL collects volume names from both services and dependencies. ```yaml volumes: - - postgres_data # Volume name + - postgres_data ``` ## Environment Variables -FTL supports environment variable substitution in your configuration: +FTL supports dynamic environment variable substitution throughout your configuration file. You can use the following patterns: -- **Required variables**: `${VAR_NAME}` -- **Optional variables with defaults**: `${VAR_NAME:-default_value}` +- **Required variables**: -Example usage: + ```yaml + env: + - DATABASE_URL=${DATABASE_URL} + ``` -```yaml -services: - - name: web - image: ${DOCKER_IMAGE:-my-app:latest} - env: - - DATABASE_URL=${DATABASE_URL} - - API_KEY=${API_KEY:-development-key} -``` + FTL will fail if `DATABASE_URL` is not set. + +- **Optional variables with defaults**: + + ```yaml + env: + - POSTGRES_USER=${POSTGRES_USER:-postgres} + ``` + + If `POSTGRES_USER` is not set, it uses `postgres`. + +- **Custom required with message**: + ```yaml + env: + - API_KEY=${API_KEY:?API_KEY must be set} + ``` ## Configuration Best Practices -1. **Use Health Checks** +1. **Health Checks** + Define health checks for all services to ensure their proper functioning: ```yaml services: @@ -140,37 +171,37 @@ services: 2. **Secure Sensitive Data** - - Use environment variables for sensitive information - - Never commit actual secrets to version control + - Use environment variables to manage secrets. + - Never commit actual secrets to version control. 3. **Organize Services** - - Group related services together - - Use clear, descriptive names - - Document service dependencies + - Group related services together. + - Use clear, descriptive names. + - Document service dependencies and required environment variables. 4. **Volume Management** - - Always declare volumes for persistent data - - Use meaningful volume names - - Consider backup strategies + - Always declare volumes for persistent data. + - Use meaningful volume names. + - Plan for backups of persistent volumes. ## Validation -FTL validates your configuration when running commands. Common validation checks include: +FTL validates your configuration during execution. Common checks include: -- Required fields presence -- Valid port numbers -- Proper URL formats -- SSH key file existence -- Environment variable resolution +- Presence of required fields +- Valid port numbers and formats +- Proper URL and email formats +- Existence of the SSH key file +- Resolution of environment variable placeholders ## Next Steps -After configuring your project: +After configuring your project, you can: -1. Move on to [First Deployment](./first-deployment.md) to deploy your application -2. Learn about [Zero-downtime Deployments](/guides/zero-downtime) -3. Explore [SSL Management](/guides/ssl-management) +1. Proceed to [First Deployment](./first-deployment.md) to deploy your application. +2. Learn about [Zero-downtime Deployments](/guides/zero-downtime). +3. Explore [SSL Management](/guides/ssl-management). ## Reference diff --git a/www/docs/getting-started/first-deployment.md b/www/docs/getting-started/first-deployment.md index bf8754f..05fa375 100755 --- a/www/docs/getting-started/first-deployment.md +++ b/www/docs/getting-started/first-deployment.md @@ -46,15 +46,15 @@ If you don't specify an `image` field in your service configuration, FTL will: - Transfer it directly to your server via SSH - Optimize transfers using layer caching +The `path` field in your service configuration specifies the directory containing your application's source code and Dockerfile. This path is resolved relative to the location of your `ftl.yaml` file. For example: + ```yaml services: - name: web - build: - context: . - dockerfile: Dockerfile + path: ./src ``` -This method is simpler as it doesn't require registry setup. +In this configuration, if your `ftl.yaml` is in `/project/ftl.yaml`, FTL will look for the Dockerfile in `/project/src/Dockerfile`. #### Registry-based Deployment @@ -102,19 +102,13 @@ The deployment process: After deployment, verify your application is running: -1. Check the application status: - - ```bash - ftl status - ``` - -2. View application logs: +1. View application logs: ```bash ftl logs ``` -3. Access your application through the configured domain +2. Access your application through the configured domain ## Common First Deployment Issues @@ -161,18 +155,12 @@ Here's a complete example of deploying a simple web application: services: - name: web - build: - context: . - dockerfile: Dockerfile + path: ./src port: 3000 health_check: path: /health - interval: 10s - timeout: 5s - retries: 3 routes: - path: / - strip_prefix: false ``` This example uses direct SSH transfer. For registry-based deployment, add the `image` field: @@ -182,17 +170,12 @@ Here's a complete example of deploying a simple web application: - name: web image: registry.example.com/my-web-app:latest build: - context: . - dockerfile: Dockerfile + path: ./src # Path to directory containing Dockerfile port: 3000 health_check: path: /health - interval: 10s - timeout: 5s - retries: 3 routes: - path: / - strip_prefix: false ``` 2. Deployment commands: @@ -205,8 +188,7 @@ Here's a complete example of deploying a simple web application: ftl build ftl deploy - # Check status and logs - ftl status + # Check logs ftl logs ``` diff --git a/www/docs/guides/health-checks.md b/www/docs/guides/health-checks.md index 22000ad..cd74b6f 100755 --- a/www/docs/guides/health-checks.md +++ b/www/docs/guides/health-checks.md @@ -20,7 +20,7 @@ FTL uses health checks to: ### Basic Health Check -The minimal health check configuration in your `ftl.yaml`: +The minimal health check configuration in your `ftl.yaml` only requires the path: ```yaml services: @@ -29,30 +29,42 @@ services: port: 80 health_check: path: / - interval: 10s - timeout: 5s - retries: 3 ``` -### Configuration Parameters +You can optionally configure timing parameters: -Each health check has four key parameters: +```yaml +services: + - name: my-app + image: my-app:latest + port: 80 + health_check: + path: / + interval: 15s # optional + timeout: 10s # optional + retries: 3 # optional +``` + +### Configuration Parameters -- `path`: The HTTP endpoint to check +Health check has one required and three optional parameters: +- `path`: (Required) The HTTP endpoint to check - Must return 2xx or 3xx status code - Should be a lightweight endpoint - Typically `/health`, `/`, or similar +Optional timing parameters: + - `interval`: Time between checks - - Default: 10 seconds + - Default: 15 seconds - Should be short enough to detect issues quickly - But not so frequent as to overload the service - `timeout`: Maximum time to wait for response - - Default: 5 seconds + - Default: 10 seconds - Should be less than the interval - Consider your service's normal response time @@ -74,9 +86,6 @@ services: port: 80 health_check: path: / - interval: 10s - timeout: 5s - retries: 3 ``` ### 2. Dedicated Health Endpoint @@ -90,9 +99,6 @@ services: port: 3000 health_check: path: /health - interval: 10s - timeout: 5s - retries: 3 ``` ### 3. Deep Health Check @@ -106,132 +112,7 @@ services: port: 8080 health_check: path: /health/deep - interval: 15s - timeout: 10s - retries: 3 -``` - -## Best Practices - -### Health Check Endpoint Design - -1. **Keep It Light** - - - Avoid expensive operations - - Don't query large datasets - - Minimize dependency checks - -2. **Response Time** - - - Should respond within 1-2 seconds - - Set timeout accordingly - - Consider background processing - -3. **Dependency Checks** - - Include critical dependencies only - - Use timeouts for external services - - Have fallback mechanisms - -### Common Patterns - -1. **Basic Availability** - -```yaml -health_check: - path: / - interval: 10s - timeout: 5s - retries: 2 -``` - -2. **Quick Response** - -```yaml -health_check: - path: /ping - interval: 5s - timeout: 2s - retries: 3 -``` - -3. **Thorough Check** - -```yaml -health_check: - path: /health/deep - interval: 30s - timeout: 10s - retries: 2 -``` - -## Monitoring Health Checks - -Track health check status using FTL's logging: - -```bash -ftl logs -f -``` - -The logs will show: - -- Health check attempts -- Success/failure status -- Response times -- Error messages - -## Troubleshooting - -### 1. Failed Health Checks - -**Problem**: Health checks consistently fail during deployment. - -**Solution**: - -- Verify the health check endpoint exists -- Check endpoint permissions -- Review service logs: - -```bash -ftl logs service-name -``` - -### 2. Slow Health Checks - -**Problem**: Health checks timeout frequently. - -**Solution**: - -- Optimize the health check endpoint -- Increase the timeout value -- Reduce dependency checks - -### 3. Flaky Health Checks - -**Problem**: Health checks pass intermittently. - -**Solution**: - -- Add retry logic in the health check -- Increase the retry count -- Check for resource constraints - -## Example Implementations - -### HTTP Service - -```yaml -services: - - name: http-service - image: http-service:latest - port: 80 - health_check: - path: /health - interval: 10s - timeout: 5s - retries: 3 - routes: - - path: / - strip_prefix: false + interval: 30s # customized for deeper checks ``` ### API Service @@ -248,7 +129,6 @@ services: retries: 3 routes: - path: /api - strip_prefix: true ``` ::: tip diff --git a/www/docs/guides/ssl-management.md b/www/docs/guides/ssl-management.md index 9568540..1db1ec2 100755 --- a/www/docs/guides/ssl-management.md +++ b/www/docs/guides/ssl-management.md @@ -34,7 +34,6 @@ services: port: 80 routes: - path: / - strip_prefix: false ``` The essential fields for SSL management are: @@ -80,14 +79,12 @@ services: port: 80 routes: - path: / - strip_prefix: false - name: api image: api:latest port: 3000 routes: - path: /api - strip_prefix: true ``` ## Best Practices diff --git a/www/docs/guides/zero-downtime.md b/www/docs/guides/zero-downtime.md index 05e460a..bdd81cb 100755 --- a/www/docs/guides/zero-downtime.md +++ b/www/docs/guides/zero-downtime.md @@ -28,7 +28,7 @@ Before implementing zero-downtime deployments, ensure you have: ### 1. Configure Health Checks -Health checks are crucial for zero-downtime deployments. FTL uses them to verify that new containers are ready before routing traffic. +Health checks are crucial for zero-downtime deployments. FTL uses them to verify that new containers are ready before routing traffic. The minimal required configuration only needs the path to your health check endpoint: ```yaml services: @@ -37,21 +37,48 @@ services: port: 80 health_check: path: / - interval: 10s - timeout: 5s - retries: 3 ``` -The health check configuration parameters: +You can further customize the health check behavior with additional timing parameters. The `interval`, `timeout`, and `retries` fields are all optional, with defaults of 15s, 10s, and 3 respectively: -- `path`: The endpoint to check (must return 2xx or 3xx status) -- `interval`: Time between health checks -- `timeout`: Maximum time to wait for a response -- `retries`: Number of consecutive successful checks required +```yaml +services: + - name: my-app + image: my-app:latest + port: 80 + health_check: + path: / + interval: 15s + timeout: 10s + retries: 3 +``` ### 2. Configure Service Routes -Proper route configuration ensures traffic is handled correctly during deployments: +For route configuration, only the path is required. Here's a minimal route setup: + +```yaml +services: + - name: my-app + image: my-app:latest + port: 80 + routes: + - path: / +``` + +Routes can be customized with the `strip_prefix` parameter, which defaults to false if not specified: + +```yaml +services: + - name: my-app + image: my-app:latest + port: 80 + routes: + - path: / + strip_prefix: false +``` + +Here's a complete example showing project configuration with minimal service settings: ```yaml project: @@ -68,9 +95,10 @@ services: - name: my-app image: my-app:latest port: 80 + health_check: + path: /health routes: - path: / - strip_prefix: false ``` ### 3. Deployment Process @@ -113,6 +141,8 @@ FTL will automatically: ### 3. Configuration Recommendations +Here's a minimal recommended configuration that includes only the required parameters: + ```yaml services: - name: my-app @@ -120,78 +150,8 @@ services: port: 80 health_check: path: /health - interval: 10s - timeout: 5s - retries: 3 routes: - path: / - strip_prefix: false -``` - -## Common Issues and Solutions - -### 1. Failed Health Checks - -**Problem**: New containers fail health checks during deployment. - -**Solution**: - -- Verify health check endpoint functionality -- Increase timeout or retries if needed -- Check application logs using: - -```bash -ftl logs my-app -``` - -### 2. Lingering Connections - -**Problem**: Old containers have lingering connections. - -**Solution**: - -- Implement graceful shutdown in your application -- Handle SIGTERM signals properly -- Consider increasing shutdown timeout if needed - -### 3. Database Migrations - -**Problem**: Schema changes can break zero-downtime deployments. - -**Solution**: - -- Use backward-compatible database migrations -- Deploy schema changes separately from application changes -- Consider using blue-green deployment for major database changes - -## Monitoring Deployments - -Track deployment progress using FTL's logging capabilities: - -```bash -ftl logs -f -``` - -This will show real-time logs during deployment, including: - -- Container health check status -- Traffic routing changes -- Container lifecycle events - -## Rollback Procedure - -If issues occur during deployment: - -1. Stop the problematic deployment: - -```bash -Ctrl+C -``` - -2. Redeploy the previous version: - -```bash -ftl deploy ``` FTL will automatically handle the rollback process with zero downtime. diff --git a/www/docs/index.md b/www/docs/index.md index b264c14..47dc7f4 100755 --- a/www/docs/index.md +++ b/www/docs/index.md @@ -142,8 +142,7 @@ services: # Need a database? Just add it here dependencies: - - name: postgres - image: postgres:16 + - postgres:16 ``` diff --git a/www/docs/reference/configuration-file.md b/www/docs/reference/configuration-file.md index 11c86aa..1810b92 100755 --- a/www/docs/reference/configuration-file.md +++ b/www/docs/reference/configuration-file.md @@ -5,7 +5,7 @@ description: Complete specification of the FTL configuration file format and opt # Configuration File Reference -FTL uses a YAML configuration file (`ftl.yaml`) to define project settings, server configurations, services, dependencies, and volumes. +FTL uses a YAML configuration file (`ftl.yaml`) to define project settings, server configurations, services, dependencies, and volumes. FTL automatically applies default settings—such as standard ports, volume mappings, and environment variables—for common services when you provide a short image reference. You can override these defaults by explicitly specifying settings. ## File Structure @@ -19,13 +19,13 @@ volumes: # Persistent storage definitions ## Project Configuration -Top-level project settings that define basic information about your deployment. +Top-level project settings define basic information about your deployment. ```yaml project: - name: my-project # Required: Project identifier - domain: my-project.example.com # Required: Primary domain for the project - email: my-project@example.com # Required: Contact email for SSL certificates + name: my-project # Required: Project identifier used for resource naming + domain: my-project.example.com # Required: Primary domain for the deployment + email: my-project@example.com # Required: Contact email for SSL certificate notifications ``` | Field | Type | Required | Description | @@ -40,99 +40,132 @@ Defines the target server for deployment. ```yaml server: - host: my-project.example.com # Required: Server hostname or IP + host: my-project.example.com # Required: Server hostname or IP address port: 22 # Optional: SSH port (default: 22) - user: my-project # Required: SSH user - ssh_key: ~/.ssh/id_rsa # Required: Path to SSH private key + user: my-project # Required: SSH username for authentication + ssh_key: ~/.ssh/id_rsa # Required: Path to SSH private key file ``` -| Field | Type | Required | Default | Description | -| --------- | ------- | -------- | ------- | ------------------------------- | -| `host` | string | Yes | - | Server hostname or IP address | -| `port` | integer | No | 22 | SSH port number | -| `user` | string | Yes | - | SSH username for authentication | -| `ssh_key` | string | Yes | - | Path to SSH private key file | +| Field | Type | Required | Default | Description | +| --------- | ------- | -------- | ------- | -------------------------------- | +| `host` | string | Yes | - | Server hostname or IP address | +| `port` | integer | No | 22 | SSH port number | +| `user` | string | Yes | - | SSH username for authentication | +| `ssh_key` | string | Yes | - | Path to the SSH private key file | ## Services -Defines the application services to be deployed. +Defines the application services to be deployed. Each service must have either a path to the source code or a Docker image reference. ```yaml services: - - name: my-app # Required: Service identifier - image: my-app:latest # Optional: Docker image name - build: # Optional: Build configuration - context: . # Required for build: Build context path - dockerfile: Dockerfile # Optional: Dockerfile path + - name: my-app # Required: Unique service identifier + path: ./src # Required if no image: Path to source code and Dockerfile + image: my-app:latest # Required if no path: Docker image used for deployment port: 80 # Required: Container port to expose - health_check: # Optional: Health check configuration - path: / # Required for health check: HTTP path - interval: 10s # Optional: Check interval - timeout: 5s # Optional: Check timeout - retries: 3 # Optional: Number of retries - routes: # Required: Routing configuration + health_check: # Optional: Health check settings + path: / # Required for health check: HTTP path to check + interval: 15s # Optional: Health check interval (default: 15s) + timeout: 10s # Optional: Health check timeout (default: 10s) + retries: 3 # Optional: Number of health check retries (default: 3) + routes: # Required: HTTP routing configuration - path: / # Required: URL path to match - strip_prefix: false # Optional: Strip path prefix + strip_prefix: false # Optional: Strip path prefix when proxying (default: false) ``` -| Field | Type | Required | Default | Description | -| -------------- | ------- | -------- | ------- | ------------------------------------------ | -| `name` | string | Yes | - | Unique service identifier | -| `image` | string | No | - | Docker image for registry-based deployment | -| `build` | object | No | - | Build configuration for direct transfer | -| `port` | integer | Yes | - | Container port to expose | -| `health_check` | object | No | - | Health check configuration | -| `routes` | array | Yes | - | Nginx routing configuration | +| Field | Type | Required | Default | Description | +| -------------- | ------- | -------- | ------- | -------------------------------------------------------------------------- | +| `name` | string | Yes | - | Unique service identifier | +| `path` | string | Yes\* | - | Path to source code directory containing Dockerfile (relative to ftl.yaml) | +| `image` | string | Yes\* | - | Docker image for deployment (can include environment substitutions) | +| `port` | integer | Yes | - | Container port to expose | +| `health_check` | object | No | - | Health check configuration | +| `routes` | array | Yes | - | Routing configuration for the reverse proxy | + +\*Either `path` or `image` must be specified, but not both. ## Dependencies -Defines supporting services required by the application. +Defines supporting services (such as databases, caches, or message queues) that your application requires. Dependencies can be declared in two ways: + +### 1. Short Notation + +Simply specify the service name and optional version. FTL will automatically apply default settings: ```yaml dependencies: - - name: postgres # Required: Dependency identifier - image: postgres:16 # Required: Docker image - volumes: # Optional: Volume mounts - - postgres_data:/var/lib/postgresql/data - env: # Optional: Environment variables - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_USER=${POSTGRES_USER:-postgres} + - "postgres:16" # Uses default settings for PostgreSQL 16 + - "redis:7" # Uses default settings for Redis 7 + - "mysql:8" # Uses default settings for MySQL 8 +``` + +When using short notation, FTL automatically configures: + +- Default image tag (modified by the specified version) +- Standard ports (e.g., 5432 for PostgreSQL) +- Default volume mappings +- Common environment variables with defaults + +### 2. Detailed Definition + +For custom configurations or overriding defaults: + +```yaml +dependencies: + - name: postgres # Required: Unique identifier for the dependency + image: postgres:16 # Required: Docker image reference + volumes: # Optional: Override default volume mappings + - my_pg_data:/custom/postgres/path + env: # Optional: Override default environment variables + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-secret} + - POSTGRES_USER=${POSTGRES_USER:-myuser} - POSTGRES_DB=${POSTGRES_DB:-app} ``` -| Field | Type | Required | Description | -| --------- | ------ | -------- | -------------------------------- | -| `name` | string | Yes | Unique dependency identifier | -| `image` | string | Yes | Docker image to use | -| `volumes` | array | No | Volume mount definitions | -| `env` | array | No | Environment variable definitions | +| Field | Type | Required | Description | +| --------- | ------ | -------- | ------------------------------------------------------- | +| `name` | string | Yes\* | Unique dependency identifier | +| `image` | string | Yes\* | Docker image used for the dependency | +| `volumes` | array | No | Volume mount definitions | +| `env` | array | No | Environment variable definitions (supporting expansion) | + +\*Only required when using detailed definition. For short notation, these are derived from the service string. ## Volumes -Defines persistent storage volumes. +Defines persistent storage volumes for your deployment. Each entry in the `volumes` array is a string representing the volume name. ```yaml volumes: - - postgres_data # Volume name + - postgres_data # Volume name that can be referenced elsewhere ``` -Each entry in the `volumes` array is a string representing the volume name. These volumes can be referenced in service and dependency configurations. - ## Environment Variables -The configuration file supports environment variable substitution in two formats: +FTL supports environment variable substitution throughout the configuration. You can use the following formats: -1. Required variables: +1. **Required variables:** ```yaml ${VARIABLE_NAME} ``` -2. Optional variables with defaults: +2. **Optional variables with default values:** ```yaml ${VARIABLE_NAME:-default_value} ``` +Example usage: + +```yaml +services: + - name: my-app + image: ${DOCKER_IMAGE:-my-app:latest} + env: + - DATABASE_URL=${DATABASE_URL} + - API_KEY=${API_KEY:-development-key} +``` + ## Complete Example ```yaml @@ -143,33 +176,56 @@ project: server: host: my-project.example.com - port: 22 user: my-project ssh_key: ~/.ssh/id_rsa services: - - name: my-app - image: my-app:latest + - name: web-app + path: ./src port: 80 health_check: path: / - interval: 10s - timeout: 5s - retries: 3 routes: - path: / + + - name: admin-app + image: ${DOCKER_IMAGE:-admin-app:latest} + port: 80 + health_check: + path: /health + interval: 15s + timeout: 10s + retries: 3 + routes: + - path: /admin strip_prefix: false dependencies: - - name: postgres - image: postgres:16 + - "postgres:16" # Using short notation with defaults + - name: redis # Using detailed definition for customization + image: redis:7 volumes: - - postgres_data:/var/lib/postgresql/data + - redis_data:/custom/redis/path env: - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_USER=${POSTGRES_USER:-postgres} - - POSTGRES_DB=${POSTGRES_DB:-app} + - REDIS_PASSWORD=${REDIS_PASSWORD:-secret} volumes: - postgres_data ``` + +## Summary + +- **Default Settings:** + FTL automatically applies default settings like ports, volumes, and environment variable substitutions when you specify a service or dependency with a short Docker image reference. + +- **Environment Variable Expansion:** + Configuration supports dynamic substitution for both required and optional variables using the `${...}` syntax. + +- **Customization:** + Override any default setting by explicitly specifying the corresponding configuration fields. + +For additional details, refer to: + +- [Configuration File Guide](/guides/configuration) +- [Environment Variables Reference](/reference/environment) +- [CLI Commands Reference](/reference/cli-commands)