src — deploy
src — deploy
The src/deploy module is responsible for generating various configuration files required for deploying applications to different cloud platforms and for defining declarative builds using Nix. It acts as a central hub for creating platform-specific deployment manifests and build definitions, abstracting away the intricacies of each platform's configuration syntax.
This module is designed to be extensible, allowing for easy addition of new cloud providers or build systems.
Module Structure
The src/deploy module is composed of two primary files:
cloud-configs.ts: Handles the generation of deployment configurations for popular cloud platforms like Fly.io, Railway, Render, Hetzner, Northflank, and Google Cloud Platform (GCP).nix-config.ts: Manages the generation of Nix-specific files (flake.nixanddefault.nix) for declarative builds and development environments.
Cloud Deployment Configurations (cloud-configs.ts)
This file provides a unified interface for generating deployment configuration files tailored to specific cloud providers. It aims to simplify the deployment process by producing ready-to-use configuration files based on a common set of application parameters.
Key Concepts and Types
CloudPlatform: A union type defining the currently supported cloud providers:'fly' | 'railway' | 'render' | 'hetzner' | 'northflank' | 'gcp'.DeployConfig: The primary input interface for all cloud deployment generators. It encapsulates common application parameters:
export interface DeployConfig {
platform: CloudPlatform; class="hl-cmt">// The target cloud platform
appName: string;
region?: string; class="hl-cmt">// Optional deployment region
port?: number; class="hl-cmt">// Application port, defaults to 3000
env?: Record<string, string>; class="hl-cmt">// Environment variables
memory?: string; class="hl-cmt">// e.g., "512mb", "1gb"
cpus?: number; class="hl-cmt">// Number of CPU cores
}
GenerateResult: The standard output interface for all configuration generation functions.
export interface GenerateResult {
success: boolean; class="hl-cmt">// Indicates if generation was successful
files: Array<{ path: string; content: string }>; class="hl-cmt">// List of generated files and their content
instructions: string; class="hl-cmt">// CLI or manual instructions for deployment
}
Core Logic and Functions
- Input Sanitization:
sanitizeAppName(name: string): Ensures application names adhere to platform-specific naming conventions (alphanumeric, hyphens, underscores). Throws an error for invalid names.sanitizeEnvValue(value: string): Escapes characters that might be problematic in YAML/TOML or shell contexts to prevent injection issues.
- Platform-Specific Generators:
Each supported cloud platform has its own dedicated generator function:
generateFlyConfig(config: DeployConfig): Generatesfly.toml.generateRailwayConfig(config: DeployConfig): Generatesrailway.json.generateRenderConfig(config: DeployConfig): Generatesrender.yaml.generateHetznerConfig(config: DeployConfig): Generateshetzner-cloud-init.yml(for cloud-init).generateNorthflankConfig(config: DeployConfig): Generatesnorthflank.json.generateGCPConfig(config: DeployConfig): Generatesapp.yaml(for Google Cloud Run/App Engine Flex).
These functions take a DeployConfig object, apply platform-specific defaults (e.g., default port, region), sanitize inputs, and return a GenerateResult containing the file content and deployment instructions.
- Main Dispatcher:
generateDeployConfig(config: DeployConfig): This is the central function that dispatches theDeployConfigto the appropriate platform-specific generator based onconfig.platform. It acts as a router, ensuring the correct configuration is generated.
- File System Interaction:
writeDeployConfigs(outputDir: string, config: DeployConfig): This asynchronous function orchestrates the entire process. It callsgenerateDeployConfigto get theGenerateResult, then iterates through theresult.filesarray, creating necessary directories and writing each file to the specifiedoutputDir. It logs each file written usinglogger.info.
Cloud Deployment Flow
The typical flow for generating and writing cloud deployment configurations is as follows:
graph TD
A[Start Deployment Request] --> B{DeployConfig Input};
B --> C[writeDeployConfigs(outputDir, config)];
C --> D[generateDeployConfig(config)];
D -- config.platform = 'fly' --> E[generateFlyConfig(config)];
D -- config.platform = 'render' --> F[generateRenderConfig(config)];
D -- ...other platforms... --> G[generateOtherConfig(config)];
E --> H{GenerateResult};
F --> H;
G --> H;
H --> I{Loop through result.files};
I --> J[fs.mkdir(dirname)];
J --> K[fs.writeFile(fullPath, content)];
K --> L[logger.info(Wrote file)];
L --> I;
I --> M[Return GenerateResult];
Nix Configuration Generator (nix-config.ts)
This file focuses on generating Nix-specific configuration files, flake.nix and default.nix, which enable declarative builds and reproducible development environments using the Nix package manager.
Key Concepts and Types
NixConfig: The input interface for Nix configuration generation.
export interface NixConfig {
packageName: string;
version: string;
description: string;
nodeVersion?: string; class="hl-cmt">// Optional Node.js version, defaults to 39;2239;
}
Core Logic and Functions
generateFlakeNix(config: NixConfig):
Generates the content for flake.nix. This file defines a Nix flake, which is a modern way to manage Nix projects. It includes:
- Inputs for
nixpkgsandflake-utils. - An
outputssection that defines a default package (packages.default) usingpkgs.buildNpmPackage. - A
devShells.defaultfor a development environment with Node.js and npm. - Important: It includes
npmDepsHash = "sha256-PLACEHOLDER";which needs to be filled in by the user after initial generation (e.g., usingnix flake update --commit-lock-file). - A wrapper script for the package to execute the main
index.jsfile.
generateDefaultNix(config: NixConfig):
Generates the content for default.nix. This is a more traditional Nix package definition, also using pkgs.buildNpmPackage. It's simpler than flake.nix and is often used for basic package definitions without the full flake ecosystem.
- Similar to
flake.nix, it includesnpmDepsHash = "sha256-PLACEHOLDER";.
writeNixConfigs(outputDir: string, config: NixConfig):
This asynchronous function takes an outputDir and a NixConfig object. It calls generateFlakeNix and generateDefaultNix to get the content, then writes these files to flake.nix and default.nix respectively within the outputDir. It logs the action using logger.info.
Integration and Usage
The src/deploy module is a critical utility for both CLI commands and internal tools that need to provision or configure deployment artifacts.
Incoming Calls
src/tools/deploy-tool.ts: This tool likely useswriteDeployConfigsto generate and save cloud deployment configurations andgenerateDeployConfigfor scenarios where only the configuration content is needed without writing to disk.commands/cli/deploy-command.ts: The CLIdeploycommand directly leverageswriteDeployConfigsandwriteNixConfigsto fulfill user requests for generating deployment files. This is the primary user-facing entry point for this module.scripts/tests/cat-sanitize-glob-deploy.ts: Variousgenerate*Configfunctions (e.g.,generateRailwayConfig,generateFlyConfig,generateRenderConfig,generateFlakeNix,generateDefaultNix) are called directly by test scripts to verify the correctness of the generated content.
Outgoing Calls
The module primarily interacts with:
fs/promises: For asynchronous file system operations (creating directories, writing files).path: For resolving file paths.../utils/logger.js: For logging informational messages about file operations.
Typical Workflow
A typical interaction with this module would involve:
- A user or an automated tool provides a
DeployConfig(for cloud platforms) orNixConfig(for Nix). - The
writeDeployConfigsorwriteNixConfigsfunction is called, specifying an output directory. - The module generates the appropriate configuration file(s) and writes them to the specified location.
- The
GenerateResult(for cloud configs) or a simple path object (for Nix configs) is returned, potentially including deployment instructions.