0632f512e6
Build / build (push) Successful in 10m25s
Replace the single global webhook secret with entity-scoped secrets stored
on each project and static site. Webhook-driven project autocreate is
removed — projects must exist before their URL can trigger deploys.
Also wires static-site webhooks (sync_trigger=push|tag), turning the
previously inert "push" trigger into a functional one: POST the site's
webhook URL from a Git provider and Tinyforge re-syncs on matching refs.
- Adds webhook_secret columns + unique indexes to projects and static_sites
- Per-entity GET/regenerate endpoints under /api/projects/{id}/webhook
and /api/sites/{id}/webhook (admin-only)
- Removes /api/settings/webhook-url and the global webhook panel
- Reusable WebhookPanel Svelte component on both detail pages, i18n in en/ru
- Tests for matcher (siteRefMatches, ParseImageRef) and handler (project
match/mismatch/404 and site push/manual/branch-skip)
1130 lines
43 KiB
JSON
1130 lines
43 KiB
JSON
{
|
|
"app": {
|
|
"name": "Tinyforge",
|
|
"version": "v0.1"
|
|
},
|
|
"health": {
|
|
"connected": "connected",
|
|
"disconnected": "disconnected",
|
|
"rawError": "Technical details",
|
|
"retryNow": "Retry now"
|
|
},
|
|
"nav": {
|
|
"dashboard": "Dashboard",
|
|
"projects": "Projects",
|
|
"deploy": "Deploy",
|
|
"proxies": "Proxies",
|
|
"events": "Events",
|
|
"settings": "Settings",
|
|
"logout": "Log out",
|
|
"dns": "DNS Records",
|
|
"sites": "Sites",
|
|
"stacks": "Stacks"
|
|
},
|
|
"dashboard": {
|
|
"title": "Dashboard",
|
|
"quickDeploy": "Quick Deploy",
|
|
"totalProjects": "Total Projects",
|
|
"runningInstances": "Running Instances",
|
|
"failedInstances": "Failed Instances",
|
|
"projects": "Projects",
|
|
"retry": "Retry",
|
|
"noProjects": "No projects yet.",
|
|
"addFirst": "Add your first project",
|
|
"loadFailed": "Failed to load dashboard",
|
|
"staleContainers": "Stale Containers",
|
|
"unusedImagesWarning": "Unused Docker images are taking up disk space",
|
|
"unusedImages": "unused images",
|
|
"staticSites": "Static Sites",
|
|
"totalSites": "Total Sites",
|
|
"deployedSites": "deployed",
|
|
"failedSites": "failed",
|
|
"noSites": "No static sites yet.",
|
|
"addFirstSite": "Deploy your first site",
|
|
"viewAllSites": "View all sites"
|
|
},
|
|
"projects": {
|
|
"title": "Projects",
|
|
"addProject": "Add Project",
|
|
"cancel": "Cancel",
|
|
"newProject": "New Project",
|
|
"name": "Name",
|
|
"image": "Image",
|
|
"port": "Port",
|
|
"registry": "Registry",
|
|
"created": "Created",
|
|
"view": "View",
|
|
"noProjects": "No projects configured yet.",
|
|
"getStarted": "Click \"Add Project\" to get started.",
|
|
"createProject": "Create Project",
|
|
"creating": "Creating...",
|
|
"healthcheck": "Healthcheck Path",
|
|
"nameRequired": "Name and image are required.",
|
|
"loadFailed": "Failed to load projects",
|
|
"createFailed": "Failed to create project",
|
|
"browseImages": "Browse Images",
|
|
"selectImage": "Select an image",
|
|
"noImages": "No images found",
|
|
"loadingImages": "Loading images...",
|
|
"imageLoadFailed": "Failed to load images",
|
|
"alreadyAdded": "Already added",
|
|
"portHelpText": "Auto-detected from EXPOSE if empty",
|
|
"healthcheckHelpText": "Auto-detected from image if empty",
|
|
"searchPlaceholder": "Search projects by name, image, or registry...",
|
|
"noMatchingProjects": "No projects match your search."
|
|
},
|
|
"projectDetail": {
|
|
"webhookTitle": "Project webhook",
|
|
"webhookDesc": "POST an image reference to this URL from your CI pipeline to trigger a deploy. Stage routing uses each stage's tag pattern.",
|
|
"deleteProject": "Delete Project",
|
|
"envVars": "Environment Variables",
|
|
"volumes": "Volume Mounts",
|
|
"stages": "Stages",
|
|
"noStages": "No stages configured for this project.",
|
|
"pattern": "Pattern",
|
|
"autoDeploy": "auto-deploy",
|
|
"requiresConfirm": "requires confirm",
|
|
"instances": "instances",
|
|
"deployNewVersion": "Deploy new version",
|
|
"selectTag": "Select tag to deploy",
|
|
"loadingTags": "Loading tags...",
|
|
"chooseTag": "Choose a tag...",
|
|
"enterTag": "Enter image tag (e.g., dev-abc123)",
|
|
"registryTag": "Registry",
|
|
"localTag": "Local",
|
|
"alsoLocal": "Also available locally",
|
|
"searchTags": "Search tags...",
|
|
"deployTag": "Tag",
|
|
"deploy": "Deploy",
|
|
"deploying": "Deploying...",
|
|
"recentDeploys": "Recent Deploys",
|
|
"noDeployHistory": "No deploy history for this project.",
|
|
"tag": "Tag",
|
|
"status": "Status",
|
|
"started": "Started",
|
|
"finished": "Finished",
|
|
"error": "Error",
|
|
"noInstancesRunning": "No instances running",
|
|
"deleteConfirmTitle": "Delete Project",
|
|
"deleteConfirmMessage": "This will permanently delete the project '{name}' and all its stages, instances, and deploy history. This cannot be undone.",
|
|
"loadFailed": "Failed to load project",
|
|
"deleteFailed": "Failed to delete project",
|
|
"deployFailed": "Deploy failed",
|
|
"nameLabel": "Name *",
|
|
"imageLabel": "Image *",
|
|
"portLabel": "Port",
|
|
"healthcheckLabel": "Healthcheck Path",
|
|
"saving": "Saving...",
|
|
"addStage": "Add Stage",
|
|
"tagPattern": "Tag Pattern",
|
|
"tagPatternHelp": "Glob pattern (e.g., dev-*, v*)",
|
|
"maxInstances": "Max Instances",
|
|
"autoDeployLabel": "Auto Deploy",
|
|
"enableProxy": "Enable Proxy",
|
|
"accessListId": "NPM Access List ID",
|
|
"accessListIdHelp": "Override the global access list for this project. Clear to inherit from NPM settings.",
|
|
"localImages": "Local Docker Images",
|
|
"imageTag": "Tag",
|
|
"imageId": "Image ID",
|
|
"imageSize": "Size",
|
|
"imageCreated": "Created",
|
|
"cpuLimit": "CPU Limit (cores)",
|
|
"cpuLimitHelp": "e.g., 0.5, 1, 2. Leave 0 for unlimited",
|
|
"memoryLimit": "Memory Limit (MB)",
|
|
"memoryLimitHelp": "e.g., 256, 512, 1024. Leave 0 for unlimited",
|
|
"npmProxy": "NPM Proxy",
|
|
"creating": "Creating...",
|
|
"createStage": "Create Stage",
|
|
"noProxy": "No Proxy",
|
|
"deleteStage": "Delete stage",
|
|
"deleteStageConfirm": "Delete stage \"{name}\"?",
|
|
"stageCreated": "Stage \"{name}\" created",
|
|
"stageUpdated": "Stage updated",
|
|
"stageUpdateFailed": "Failed to update stage",
|
|
"stageDeleted": "Stage \"{name}\" deleted",
|
|
"projectUpdated": "Project updated",
|
|
"updateFailed": "Failed to update project",
|
|
"stageCreateFailed": "Failed to create stage",
|
|
"stageDeleteFailed": "Failed to delete stage"
|
|
},
|
|
"envEditor": {
|
|
"title": "Environment Variables",
|
|
"description": "Manage per-stage environment variable overrides. Stage-level values override project-level defaults.",
|
|
"stage": "Stage",
|
|
"projectDefaults": "Project-Level Defaults",
|
|
"noProjectEnv": "No project-level environment variables defined yet.",
|
|
"stageOverrides": "Stage Overrides",
|
|
"key": "Key",
|
|
"value": "Value",
|
|
"secret": "Secret",
|
|
"source": "Source",
|
|
"actions": "Actions",
|
|
"overridden": "overridden",
|
|
"inherited": "inherited",
|
|
"overridesProject": "overrides project",
|
|
"stageOnly": "stage only",
|
|
"edit": "Edit",
|
|
"change": "Change",
|
|
"delete": "Delete",
|
|
"save": "Save",
|
|
"add": "Add",
|
|
"adding": "Adding...",
|
|
"noStages": "No stages configured. Add stages to the project first.",
|
|
"loadFailed": "Failed to load project",
|
|
"envAdded": "Environment variable added",
|
|
"envUpdated": "Environment variable updated",
|
|
"envDeleted": "Environment variable deleted",
|
|
"addFailed": "Failed to add env var",
|
|
"updateFailed": "Failed to update env var",
|
|
"deleteFailed": "Failed to delete env var",
|
|
"loadEnvFailed": "Failed to load env vars",
|
|
"leaveEmptyToKeep": "Leave empty to keep current",
|
|
"deleteTitle": "Delete Environment Variable",
|
|
"deleteMessage": "Are you sure you want to delete this environment variable? This action cannot be undone."
|
|
},
|
|
"volumeEditor": {
|
|
"title": "Volume Mounts",
|
|
"description": "Configure volume mounts for containers. Choose a scope to control how volumes are shared between deploys.",
|
|
"sourceHost": "Source (Host)",
|
|
"targetContainer": "Target (Container)",
|
|
"scope": "Scope",
|
|
"nameColumn": "Name",
|
|
"namePlaceholder": "e.g. shared-db",
|
|
"requiresName": "requires name",
|
|
"noHostPath": "no host path",
|
|
"tmpfs": "tmpfs (in-memory)",
|
|
"actions": "Actions",
|
|
"edit": "Edit",
|
|
"delete": "Delete",
|
|
"save": "Save",
|
|
"add": "Add",
|
|
"adding": "Adding...",
|
|
"scopeGuide": "Volume Scopes",
|
|
"noVolumes": "No volumes configured yet. Add one above.",
|
|
"volumeAdded": "Volume added",
|
|
"volumeUpdated": "Volume updated",
|
|
"volumeDeleted": "Volume deleted",
|
|
"loadFailed": "Failed to load volumes",
|
|
"addFailed": "Failed to add volume",
|
|
"updateFailed": "Failed to update volume",
|
|
"deleteFailed": "Failed to delete volume"
|
|
},
|
|
"volumeBrowser": {
|
|
"title": "Volume Browser",
|
|
"loadFailed": "Failed to load directory",
|
|
"empty": "This directory is empty.",
|
|
"name": "Name",
|
|
"size": "Size",
|
|
"modified": "Modified",
|
|
"downloadAll": "Download volume as ZIP",
|
|
"downloadFolder": "Download folder as ZIP",
|
|
"upload": "Upload files",
|
|
"uploaded": "Uploaded",
|
|
"files": "file(s)",
|
|
"uploadFailed": "Failed to upload files",
|
|
"browse": "Browse",
|
|
"download": "Download"
|
|
},
|
|
"quickDeploy": {
|
|
"title": "Quick Deploy",
|
|
"description": "Deploy a container image with zero configuration. Paste an image URL, review the defaults, and deploy.",
|
|
"step1": "1. Enter Image URL",
|
|
"imageUrl": "Image URL",
|
|
"imageUrlHelp": "Full image URL including tag (e.g., git.example.com/user/app:dev-abc123)",
|
|
"inspect": "Inspect",
|
|
"inspecting": "Inspecting...",
|
|
"step2": "2. Review Configuration",
|
|
"reviewDesc": "These defaults were detected from the image. Adjust as needed before deploying.",
|
|
"projectName": "Project Name",
|
|
"port": "Port",
|
|
"portHelp": "Container port to expose (1-65535)",
|
|
"healthCheckPath": "Health Check Path",
|
|
"healthCheckHelp": "Optional HTTP path for health verification",
|
|
"stage": "Stage",
|
|
"development": "Development",
|
|
"release": "Release",
|
|
"production": "Production",
|
|
"stageHelp": "Deployment stage for this image",
|
|
"subdomainOverride": "Subdomain Override",
|
|
"subdomainHelp": "Leave empty to use the default subdomain pattern",
|
|
"envVars": "Environment Variables",
|
|
"envVarsHelp": "One per line, KEY=VALUE format",
|
|
"step3": "3. Deploy",
|
|
"deployDesc": "A new project will be created and the container will be deployed immediately.",
|
|
"deployBtn": "Deploy",
|
|
"inspectedSuccess": "Image inspected successfully",
|
|
"deployedSuccess": "Deployed {name} successfully!",
|
|
"inspectFailed": "Failed to inspect image",
|
|
"deployFailed": "Deployment failed",
|
|
"browseImages": "Browse",
|
|
"selectImage": "Select an image from a registry",
|
|
"noImages": "No images found",
|
|
"loadingImages": "Loading...",
|
|
"imageLoadFailed": "Failed to load images",
|
|
"autoDeployLabel": "Deploy immediately",
|
|
"lowercaseHint": "Lowercase with hyphens",
|
|
"imageAlreadyExists": "Image already deployed",
|
|
"conflictDescription": "A project using this image already exists. You can open the existing project to deploy a new version, or create a separate project.",
|
|
"openProject": "Open project \u2192",
|
|
"createNewAnyway": "Create New Project"
|
|
},
|
|
"settings": {
|
|
"title": "Settings",
|
|
"general": "General",
|
|
"integrations": "Integrations",
|
|
"dns": "DNS",
|
|
"maintenance": "Maintenance",
|
|
"registries": "Registries",
|
|
"credentials": "Credentials",
|
|
"authentication": "Authentication",
|
|
"backup": "Backups",
|
|
"appearance": "Appearance",
|
|
"groupMain": "Overview",
|
|
"groupProxy": "Routing",
|
|
"groupSystem": "System",
|
|
"groupSecurity": "Security",
|
|
"staleThreshold": "Stale threshold (days)",
|
|
"staleThresholdHelp": "Containers inactive for longer than this will be flagged as stale.",
|
|
"dockerCleanup": "Docker Image Cleanup",
|
|
"dockerCleanupHelp": "Remove unused Docker images belonging to your projects. Only images not used by active instances are removed.",
|
|
"pruneThreshold": "Warning Threshold (MB)",
|
|
"pruneThresholdHelp": "Show dashboard warning when unused project images exceed this size. 0 = disabled.",
|
|
"pruneImages": "Prune Unused Images",
|
|
"pruning": "Pruning...",
|
|
"pruneResult": "Removed {count} images, reclaimed {mb} MB",
|
|
"pruneConfirmMessage": "This will remove unused Docker images belonging to your projects. Images used by active instances will not be affected.",
|
|
"pruneFailed": "Failed to prune images",
|
|
"proxyProvider": "Proxy Provider",
|
|
"proxyProviderHelp": "Select how reverse proxy routes are managed for deployed containers.",
|
|
"proxyNone": "None",
|
|
"proxyNoneDesc": "No proxy — containers are accessed directly by port",
|
|
"proxyNpm": "Nginx Proxy Manager",
|
|
"proxyNpmDesc": "Routes managed via NPM API (configure credentials below)",
|
|
"npm": "Nginx Proxy Manager",
|
|
"traefik": "Traefik",
|
|
"traefikLabelsTitle": "Docker Labels Reference",
|
|
"traefikLabelsDesc": "These labels are automatically added to deployed containers. Shown here for reference.",
|
|
"proxyTraefik": "Traefik",
|
|
"proxyTraefikDesc": "Auto-discovery via Docker labels — no API calls needed",
|
|
"proxyNoneWarning": "Switching to None does not remove existing proxy routes. You may need to clean them up manually.",
|
|
"traefikEntrypoint": "Entrypoint",
|
|
"traefikEntrypointHelp": "Traefik entrypoint name for HTTPS routes",
|
|
"traefikCertResolver": "Cert Resolver",
|
|
"traefikCertResolverHelp": "TLS certificate resolver name (e.g., letsencrypt)",
|
|
"traefikNetwork": "Docker Network",
|
|
"traefikNetworkHelp": "Network Traefik listens on (leave empty to use global network)",
|
|
"traefikApiUrl": "Traefik API URL",
|
|
"traefikApiUrlHelp": "Optional — for health checks (e.g., http://traefik:8080)"
|
|
},
|
|
"settingsGeneral": {
|
|
"title": "General Settings",
|
|
"globalConfig": "Global Configuration",
|
|
"globalConfigDesc": "Core infrastructure: the base domain, network, and polling cadence Tinyforge uses to orchestrate containers.",
|
|
"configureNpm": "Nginx Proxy Manager is selected.",
|
|
"configureTraefik": "Traefik is selected.",
|
|
"configureLink": "Configure provider",
|
|
"domain": "Domain",
|
|
"domainHelp": "Base domain for subdomain routing (e.g., example.com → stage-dev-app.example.com)",
|
|
"serverIp": "Server IP (Docker Host)",
|
|
"serverIpHelp": "IP of the machine running Docker. Used for NPM remote forwarding.",
|
|
"publicIp": "Public IP (DNS Target)",
|
|
"publicIpHelp": "IP for DNS A records — typically your proxy/load balancer. Falls back to Server IP if empty.",
|
|
"dockerNetwork": "Docker Network",
|
|
"dockerNetworkHelp": "Docker network that containers and proxy share. Must match your NPM/Traefik network.",
|
|
"subdomainPattern": "Subdomain Pattern",
|
|
"subdomainPatternHelp": "Pattern for auto-generated subdomains",
|
|
"subdomainVarsTitle": "Available variables",
|
|
"varProject": "Project name",
|
|
"varStage": "Stage name",
|
|
"varTag": "Image tag",
|
|
"varPort": "Container port",
|
|
"pollingInterval": "Polling Interval (seconds)",
|
|
"pollingIntervalHelp": "How often to check registries for new tags (60-86400)",
|
|
"notificationUrl": "Notification URL",
|
|
"notificationUrlHelp": "Webhook URL for deploy notifications",
|
|
"saveSettings": "Save Settings",
|
|
"saving": "Saving...",
|
|
"saved": "Settings saved successfully",
|
|
"saveFailed": "Failed to save settings",
|
|
"loadFailed": "Failed to load settings",
|
|
"webhookUrl": "Webhook URL",
|
|
"webhookDesc": "This secret URL receives image push notifications from your CI pipeline.",
|
|
"noWebhookUrl": "No webhook URL configured",
|
|
"copy": "Copy",
|
|
"copied": "Webhook URL copied to clipboard",
|
|
"regenerateUrl": "Regenerate URL",
|
|
"regenerating": "Regenerating...",
|
|
"regenerated": "Webhook URL regenerated",
|
|
"regenerateFailed": "Failed to regenerate webhook URL",
|
|
"regenerateWarning": "Warning: regenerating will invalidate the current URL. Update your CI pipelines.",
|
|
"sslCertificate": "SSL Certificate",
|
|
"sslCertificateHelp": "Wildcard certificate from NPM for auto-SSL on proxy hosts",
|
|
"selectCertificate": "Select Certificate",
|
|
"noCertificate": "None (no SSL)",
|
|
"clearCertificate": "Clear",
|
|
"loadingCertificates": "Loading certificates...",
|
|
"noCertificatesFound": "No wildcard certificates found in NPM",
|
|
"dnsConfig": "DNS Configuration",
|
|
"wildcardDns": "Wildcard DNS is configured",
|
|
"wildcardDnsHelp": "When enabled, all subdomains resolve to your server via a wildcard DNS rule. Disable to manage DNS records per service.",
|
|
"dnsProvider": "DNS Provider",
|
|
"dnsProviderHelp": "Select a DNS provider for automatic record management",
|
|
"cloudflareApiToken": "Cloudflare API Token",
|
|
"cloudflareApiTokenHelp": "API token with DNS edit permissions for your zone",
|
|
"cloudflareApiTokenPlaceholder": "Enter Cloudflare API token",
|
|
"cloudflareApiTokenConfigured": "API token is configured",
|
|
"cloudflareZone": "Cloudflare Zone",
|
|
"cloudflareZoneHelp": "Select the DNS zone to manage records in",
|
|
"selectZone": "Select Zone",
|
|
"noZone": "No zone selected",
|
|
"loadingZones": "Loading zones...",
|
|
"noZonesFound": "No zones found for this token",
|
|
"testConnection": "Test Connection",
|
|
"testingConnection": "Testing...",
|
|
"connectionSuccess": "Connection successful",
|
|
"connectionFailed": "Connection failed",
|
|
"baseVolumePath": "Base Volume Path",
|
|
"baseVolumePathHelp": "Prepended to relative volume sources (e.g., /data + my-app/uploads = /data/my-app/uploads)"
|
|
},
|
|
"settingsRegistries": {
|
|
"title": "Container Registries",
|
|
"description": "Manage your container registries for image detection.",
|
|
"addRegistry": "Add Registry",
|
|
"editRegistry": "Edit Registry",
|
|
"addNewRegistry": "Add New Registry",
|
|
"name": "Name",
|
|
"nameHelp": "A friendly name for this registry",
|
|
"url": "URL",
|
|
"urlHelp": "Registry base URL",
|
|
"type": "Type",
|
|
"typeHelp": "Registry type for API compatibility",
|
|
"token": "Token",
|
|
"tokenHelpNew": "API token for authentication",
|
|
"tokenHelpEdit": "Leave empty to keep the existing token",
|
|
"owner": "Owner",
|
|
"ownerHelp": "Package owners, comma-separated (e.g., alexei,my-org)",
|
|
"save": "Save",
|
|
"saving": "Saving...",
|
|
"update": "Update",
|
|
"test": "Test",
|
|
"testing": "Testing...",
|
|
"edit": "Edit",
|
|
"delete": "Delete",
|
|
"noRegistries": "No registries configured yet.",
|
|
"addFirst": "Add your first registry",
|
|
"registryUpdated": "Registry updated",
|
|
"registryAdded": "Registry added",
|
|
"registryDeleted": "Registry \"{name}\" deleted",
|
|
"testSuccess": "Connection to \"{name}\" successful",
|
|
"saveFailed": "Failed to save registry",
|
|
"deleteFailed": "Failed to delete registry",
|
|
"testFailed": "Connection test failed",
|
|
"loadFailed": "Failed to load registries",
|
|
"deleteConfirm": "Delete registry \"{name}\"? This cannot be undone.",
|
|
"healthChecking": "Checking...",
|
|
"healthConnected": "Connected",
|
|
"healthUnreachable": "Unreachable"
|
|
},
|
|
"settingsNpm": {
|
|
"testConnection": "Test Connection",
|
|
"testing": "Testing...",
|
|
"testSuccess": "NPM connection successful",
|
|
"testFailed": "NPM connection failed",
|
|
"saveFailedConnection": "Cannot save \u2014 connection test failed",
|
|
"remoteMode": "Remote NPM",
|
|
"remoteModeHelp": "Enable when NPM runs on a different machine than Docker. Forwards to Server IP with published host ports.",
|
|
"remoteModeWarning": "Requires Server IP in General settings. Ports are auto-mapped to random host ports.",
|
|
"accessList": "Default Access List",
|
|
"accessListHelp": "NPM access list for HTTP authentication on proxy hosts. Can be overridden per project.",
|
|
"noAccessList": "Global default",
|
|
"selectAccessList": "Select an access list",
|
|
"noAccessLists": "No access lists found in NPM",
|
|
"accessListLoadFailed": "Failed to load access lists"
|
|
},
|
|
"settingsCredentials": {
|
|
"title": "Credentials",
|
|
"description": "Manage credentials for Nginx Proxy Manager and registry tokens. All values are encrypted at rest.",
|
|
"npm": "Nginx Proxy Manager",
|
|
"npmDesc": "Credentials for managing proxy hosts via NPM API",
|
|
"configured": "Configured",
|
|
"npmUrl": "NPM URL",
|
|
"npmUrlHelp": "Nginx Proxy Manager API URL",
|
|
"email": "Email",
|
|
"emailHelp": "NPM admin email",
|
|
"password": "Password",
|
|
"passwordHelpNew": "NPM admin password (will be encrypted)",
|
|
"passwordHelpEdit": "Enter the new password to replace the existing one",
|
|
"changeCredentials": "Change Credentials",
|
|
"save": "Save",
|
|
"saving": "Saving...",
|
|
"saved": "NPM credentials saved",
|
|
"saveFailed": "Failed to save NPM credentials",
|
|
"loadFailed": "Failed to load credentials",
|
|
"registryTokens": "Registry Tokens",
|
|
"registryTokensDesc": "Registry authentication tokens are managed per-registry in the",
|
|
"registriesLink": "Registries",
|
|
"registryTokensSuffix": "section. Each registry stores its token encrypted in the database.",
|
|
"notSet": "Not set"
|
|
},
|
|
"settingsBackup": {
|
|
"title": "Backup Management",
|
|
"description": "Manage database backups and configure automatic backup schedules.",
|
|
"autoBackup": "Automatic Backups",
|
|
"autoBackupHelp": "Automatically create backups at the configured interval.",
|
|
"interval": "Backup Interval",
|
|
"intervalHelp": "How often to create automatic backups.",
|
|
"intervalHours": "{hours} hours",
|
|
"retention": "Retention Count",
|
|
"retentionHelp": "Maximum number of backups to keep. Oldest are deleted first.",
|
|
"backupNow": "Backup Now",
|
|
"creatingBackup": "Creating...",
|
|
"backupCreated": "Backup created successfully",
|
|
"backupFailed": "Failed to create backup",
|
|
"backupList": "Backups",
|
|
"noBackups": "No backups yet. Create one manually or enable automatic backups.",
|
|
"columnFilename": "Filename",
|
|
"columnSize": "Size",
|
|
"columnType": "Type",
|
|
"columnDate": "Created",
|
|
"columnActions": "Actions",
|
|
"download": "Download",
|
|
"delete": "Delete",
|
|
"restore": "Restore",
|
|
"deleteConfirm": "Are you sure you want to delete this backup?",
|
|
"deleted": "Backup deleted",
|
|
"deleteFailed": "Failed to delete backup",
|
|
"restoreConfirm": "Are you sure you want to restore from this backup? This will replace the current database and restart the server. All current data will be lost.",
|
|
"restoreWarning": "This action cannot be undone!",
|
|
"restored": "Database restored. The server is restarting...",
|
|
"restoreFailed": "Failed to restore backup",
|
|
"typeManual": "Manual",
|
|
"typeAuto": "Auto",
|
|
"save": "Save",
|
|
"saving": "Saving...",
|
|
"saved": "Backup settings saved",
|
|
"saveFailed": "Failed to save backup settings"
|
|
},
|
|
"settingsAuth": {
|
|
"title": "Authentication Settings",
|
|
"description": "Configure authentication mode and manage users.",
|
|
"authMode": "Authentication Mode",
|
|
"local": "Local (username/password)",
|
|
"oidc": "OIDC (SSO)",
|
|
"oidcConfig": "OIDC Provider Configuration",
|
|
"issuerUrl": "Issuer URL",
|
|
"clientId": "Client ID",
|
|
"clientSecret": "Client Secret",
|
|
"redirectUrl": "Redirect URL",
|
|
"saveSettings": "Save Settings",
|
|
"saving": "Saving...",
|
|
"saved": "Settings saved",
|
|
"saveFailed": "Failed to save",
|
|
"loadFailed": "Failed to load settings",
|
|
"localUsers": "Local Users",
|
|
"username": "Username",
|
|
"email": "Email",
|
|
"role": "Role",
|
|
"created": "Created",
|
|
"noUsers": "No users found.",
|
|
"addUser": "Add User",
|
|
"viewer": "Viewer",
|
|
"admin": "Admin",
|
|
"userCreated": "User created",
|
|
"userDeleted": "User deleted",
|
|
"createFailed": "Failed to create user",
|
|
"deleteFailed": "Failed to delete user",
|
|
"deleteConfirm": "Are you sure you want to delete this user?",
|
|
"usernameRequired": "Username and password are required",
|
|
"networkError": "Network error",
|
|
"password": "Password"
|
|
},
|
|
"login": {
|
|
"title": "Tinyforge",
|
|
"subtitle": "Sign in to your account",
|
|
"username": "Username",
|
|
"password": "Password",
|
|
"signIn": "Sign in",
|
|
"signingIn": "Signing in...",
|
|
"or": "or",
|
|
"ssoButton": "Sign in with SSO (OIDC)",
|
|
"loginFailed": "Login failed",
|
|
"networkError": "Network error"
|
|
},
|
|
"proxies": {
|
|
"title": "Proxy Manager",
|
|
"create": "Create Proxy",
|
|
"standalone": "Standalone Proxies",
|
|
"managed": "Managed Proxies",
|
|
"noProxies": "No proxies found",
|
|
"noProxiesDesc": "Create a standalone proxy or deploy a project with proxy enabled.",
|
|
"filter": {
|
|
"search": "Search by domain or destination...",
|
|
"health": "Health",
|
|
"type": "Type",
|
|
"all": "All",
|
|
"clear": "Clear filters"
|
|
},
|
|
"health": {
|
|
"healthy": "Healthy",
|
|
"unhealthy": "Unhealthy",
|
|
"unknown": "Unknown"
|
|
},
|
|
"lastChecked": "Last checked"
|
|
},
|
|
"sites": {
|
|
"webhookTitle": "Site webhook",
|
|
"webhookDesc": "Point your Git provider's push webhook at this URL. Tinyforge will re-sync the site on matching refs (branch for push trigger, tag pattern for tag trigger). Send an empty body for an unconditional sync.",
|
|
"title": "Static Sites",
|
|
"addSite": "New Site",
|
|
"newSite": "New Static Site",
|
|
"createSite": "Create Site",
|
|
"noSites": "No static sites",
|
|
"noSitesDesc": "Deploy static content from a Git repository folder.",
|
|
"searchPlaceholder": "Search sites by name, domain, or repo...",
|
|
"noMatching": "No sites match your search.",
|
|
"name": "Name",
|
|
"domain": "Domain",
|
|
"mode": "Mode",
|
|
"status": "Status",
|
|
"lastSync": "Last Sync",
|
|
"deploy": "Deploy",
|
|
"stop": "Stop",
|
|
"start": "Start",
|
|
"openSite": "Open Site",
|
|
"confirmDelete": "Delete Site",
|
|
"confirmDeleteMsg": "This will permanently delete the site and remove its container",
|
|
"confirmDeleteSecret": "Delete Secret",
|
|
"confirmDeleteSecretMsg": "Are you sure you want to delete secret",
|
|
"siteInfo": "Site Information",
|
|
"folder": "Folder",
|
|
"syncTrigger": "Sync Trigger",
|
|
"commitSha": "Commit SHA",
|
|
"secrets": "Secrets",
|
|
"addSecret": "Add Secret",
|
|
"noSecrets": "No secrets configured. Add secrets if your site needs server-side API keys.",
|
|
"secretKey": "Key",
|
|
"secretValue": "Value",
|
|
"encryptSecret": "Encrypt value",
|
|
"saveSecret": "Add Secret",
|
|
"step1Title": "1. Repository",
|
|
"step2Title": "2. Select Branch",
|
|
"step3Title": "3. Select Folder",
|
|
"step4Title": "4. Configuration",
|
|
"step5Title": "5. Review & Create",
|
|
"fullRepoUrl": "Repository URL",
|
|
"fullRepoUrlHelp": "Paste a full URL to auto-fill the fields below (e.g., https://git.example.com/owner/repo)",
|
|
"serverUrl": "Server URL",
|
|
"repoUrl": "Git Server URL",
|
|
"repoUrlHelp": "Paste a full repo URL or enter the server base URL (Gitea, Forgejo, Gogs)",
|
|
"repoOwner": "Owner",
|
|
"repoName": "Repository",
|
|
"accessToken": "Access Token",
|
|
"accessTokenPlaceholder": "Optional — for private repos",
|
|
"accessTokenHelp": "Personal access token with repo read permissions. Leave empty for public repos.",
|
|
"noToken": "None (public repo)",
|
|
"testConnection": "Test Connection",
|
|
"connectionSuccess": "Repository is accessible",
|
|
"loadingBranches": "Loading branches...",
|
|
"selectBranch": "Select a branch",
|
|
"chooseBranch": "Choose a branch...",
|
|
"branch": "Branch",
|
|
"loadingTree": "Loading repository tree...",
|
|
"selectFolder": "Select the folder containing your site files",
|
|
"selectedFolder": "Selected folder",
|
|
"siteName": "Site Name",
|
|
"domainHelp": "Public domain for the site. Proxy will be configured automatically.",
|
|
"modeStaticDesc": "HTML, CSS, JS, images served via Nginx",
|
|
"modeDenoDesc": "Static files + server-side API from api/ folder",
|
|
"triggerManual": "Manual",
|
|
"triggerPush": "On Push",
|
|
"triggerTag": "On Tag",
|
|
"tagPattern": "Tag Pattern",
|
|
"tagPatternHelp": "Glob pattern for matching tags (e.g., v*, pages-*)",
|
|
"renderMarkdown": "Render Markdown files to HTML",
|
|
"provider": "Git Provider",
|
|
"detectedProvider": "Auto-detected",
|
|
"browseRepos": "Browse repositories",
|
|
"selectRepo": "Select a repository",
|
|
"storage": "Persistent Storage",
|
|
"enableStorage": "Enable persistent storage",
|
|
"storageHelp": "Mounts a Docker volume at /app/data for your Deno backend to read and write files that persist across deployments.",
|
|
"storageLimitMB": "Storage Limit (MB)",
|
|
"storageLimitHelp": "Maximum storage size in megabytes. 0 = unlimited.",
|
|
"storageVolume": "Volume",
|
|
"dataPath": "Data Path",
|
|
"storageMountPath": "Mount Path",
|
|
"storageLimit": "Limit",
|
|
"storageUsed": "Used",
|
|
"storageOfLimit": "of limit used",
|
|
"unlimited": "Unlimited"
|
|
},
|
|
"common": {
|
|
"cancel": "Cancel",
|
|
"confirm": "Confirm",
|
|
"delete": "Delete",
|
|
"edit": "Edit",
|
|
"change": "Change",
|
|
"save": "Save",
|
|
"retry": "Retry",
|
|
"loading": "Loading...",
|
|
"noData": "No data",
|
|
"project": "Project",
|
|
"back": "Back",
|
|
"actions": "Actions",
|
|
"stop": "Stop",
|
|
"start": "Start",
|
|
"restart": "Restart",
|
|
"remove": "Remove",
|
|
"instance": "instance",
|
|
"instances": "instances",
|
|
"next": "Next",
|
|
"yes": "Yes",
|
|
"no": "No",
|
|
"saving": "Saving..."
|
|
},
|
|
"instance": {
|
|
"stopConfirm": "This will stop the running container. The instance can be started again later.",
|
|
"restartConfirm": "This will restart the container, causing brief downtime.",
|
|
"removeConfirm": "This will permanently remove the container and its proxy configuration. This cannot be undone.",
|
|
"actionFailed": "Action failed"
|
|
},
|
|
"empty": {
|
|
"noProjects": "No projects yet",
|
|
"noProjectsDesc": "Get started by creating your first project or use Quick Deploy.",
|
|
"createProject": "Create Project",
|
|
"noInstances": "No instances",
|
|
"noInstancesDesc": "Deploy a new version to see instances here.",
|
|
"noDeploys": "No deploy history",
|
|
"noDeploysDesc": "Deploy history will appear here after your first deployment.",
|
|
"noRegistries": "No registries",
|
|
"noRegistriesDesc": "Add a container registry to enable image detection.",
|
|
"noVolumes": "No volumes",
|
|
"noVolumesDesc": "Configure volume mounts for persistent data.",
|
|
"noUsers": "No users",
|
|
"noUsersDesc": "Add local users to manage access."
|
|
},
|
|
"validation": {
|
|
"required": "{field} is required",
|
|
"invalidUrl": "Invalid URL format",
|
|
"invalidDomain": "Invalid domain format",
|
|
"invalidIp": "Invalid IP format",
|
|
"invalidEmail": "Invalid email format",
|
|
"invalidPort": "Port must be between 1 and 65535",
|
|
"invalidPollingInterval": "Polling interval must be between 60 and 86400 seconds",
|
|
"invalidProjectName": "Only lowercase letters, numbers, and hyphens allowed",
|
|
"requiredWhenUpdating": "{field} is required when updating credentials",
|
|
"requiredForNew": "{field} is required for new registries"
|
|
},
|
|
"confirm": {
|
|
"stopInstance": "Stop Instance",
|
|
"startInstance": "Start Instance",
|
|
"restartInstance": "Restart Instance",
|
|
"removeInstance": "Remove Instance",
|
|
"stopAction": "Stop",
|
|
"restartAction": "Restart",
|
|
"removeAction": "Remove"
|
|
},
|
|
"theme": {
|
|
"light": "Light",
|
|
"dark": "Dark",
|
|
"system": "System"
|
|
},
|
|
"entityPicker": {
|
|
"search": "Search...",
|
|
"noResults": "No results found"
|
|
},
|
|
"stale": {
|
|
"title": "Stale Containers",
|
|
"noStale": "No stale containers",
|
|
"noStaleDesc": "All containers are healthy and running.",
|
|
"cleanup": "Clean up",
|
|
"cleanupAll": "Clean up all",
|
|
"confirmCleanup": "This will stop and remove the container. Continue?",
|
|
"confirmBulkCleanup": "This will stop and remove all stale containers. Continue?",
|
|
"daysStale": "days stale",
|
|
"lastAlive": "Last alive",
|
|
"count": "Stale",
|
|
"cleanedUp": "Container cleaned up",
|
|
"bulkCleanedUp": "{count} containers cleaned up",
|
|
"cleanupFailed": "Cleanup failed",
|
|
"loadFailed": "Failed to load stale containers"
|
|
},
|
|
"proxies": {
|
|
"title": "Proxies",
|
|
"create": "Create Proxy",
|
|
"noProxies": "No proxies configured yet.",
|
|
"noProxiesDesc": "Create a standalone proxy or deploy a project to see proxies here.",
|
|
"standalone": "Standalone Proxies",
|
|
"managed": "Managed",
|
|
"lastChecked": "Last checked",
|
|
"health": {
|
|
"healthy": "Healthy",
|
|
"unhealthy": "Unhealthy",
|
|
"unknown": "Unknown"
|
|
},
|
|
"filter": {
|
|
"search": "Search proxies...",
|
|
"health": "Health",
|
|
"type": "Type",
|
|
"all": "All",
|
|
"clear": "Clear filters"
|
|
},
|
|
"form": {
|
|
"title": "Create Proxy",
|
|
"editTitle": "Edit Proxy",
|
|
"destination": "Destination URL / IP",
|
|
"port": "Port",
|
|
"domain": "Domain",
|
|
"domainHelp": "The public domain for this proxy.",
|
|
"validate": "Validate",
|
|
"validating": "Validating...",
|
|
"create": "Create Proxy",
|
|
"save": "Save Changes",
|
|
"cancel": "Cancel",
|
|
"delete": "Delete",
|
|
"deleteConfirm": "Delete this proxy? This cannot be undone."
|
|
},
|
|
"validation": {
|
|
"title": "Destination Validation",
|
|
"syntax": "URL syntax",
|
|
"dns": "DNS resolution",
|
|
"tcp": "TCP connection",
|
|
"http": "HTTP response",
|
|
"checking": "Checking...",
|
|
"skipped": "Skipped"
|
|
}
|
|
},
|
|
"proxies": {
|
|
"title": "Proxy Routes",
|
|
"description": "Active proxy routes from deployed containers and static sites.",
|
|
"domain": "Domain",
|
|
"project": "Project / Site",
|
|
"stage": "Stage / Mode",
|
|
"tag": "Tag",
|
|
"port": "Port",
|
|
"status": "Status",
|
|
"source": "Source",
|
|
"sourceContainer": "Container",
|
|
"sourceStatic": "Static Site",
|
|
"sourceDeno": "Deno Site",
|
|
"filterAll": "All",
|
|
"filterContainers": "Containers",
|
|
"filterSites": "Sites",
|
|
"noRoutes": "No proxy routes",
|
|
"noRoutesDesc": "Proxy routes are created automatically when you deploy a container with proxy enabled or publish a static site.",
|
|
"searchPlaceholder": "Search by domain, project, or tag...",
|
|
"noMatch": "No routes match your search.",
|
|
"loadFailed": "Failed to load proxy routes",
|
|
"route": "route",
|
|
"routes": "routes"
|
|
},
|
|
"logs": {
|
|
"title": "Container Logs",
|
|
"lines": "lines",
|
|
"follow": "Follow",
|
|
"following": "Following...",
|
|
"loading": "Loading logs...",
|
|
"noLogs": "No log output"
|
|
},
|
|
"events": {
|
|
"title": "Event Log",
|
|
"noEvents": "No events found",
|
|
"noEventsDesc": "Events will appear here as they occur.",
|
|
"loadMore": "Load more",
|
|
"newEvents": "new events",
|
|
"totalCount": "{count} total",
|
|
"clearAll": "Clear All",
|
|
"clearAllTitle": "Clear Event Log",
|
|
"clearAllMessage": "This will permanently delete all event log entries. This cannot be undone.",
|
|
"cleared": "Cleared {count} events",
|
|
"clearFailed": "Failed to clear events",
|
|
"filter": {
|
|
"severity": "Severity",
|
|
"source": "Source",
|
|
"dateRange": "Date range",
|
|
"search": "Search events...",
|
|
"lastHour": "Last hour",
|
|
"last24h": "Last 24 hours",
|
|
"last7d": "Last 7 days",
|
|
"allTime": "All time",
|
|
"clear": "Clear filters"
|
|
},
|
|
"severity": {
|
|
"info": "Info",
|
|
"warn": "Warning",
|
|
"error": "Error"
|
|
},
|
|
"source": {
|
|
"deploy": "Deploy",
|
|
"static_site": "Static Site",
|
|
"stale_scanner": "Stale Scanner",
|
|
"stale_cleanup": "Stale Cleanup",
|
|
"admin": "Admin"
|
|
},
|
|
"metadata": "Details"
|
|
},
|
|
"stats": {
|
|
"cpu": "CPU",
|
|
"mem": "MEM",
|
|
"unavailable": "Stats unavailable"
|
|
},
|
|
"systemHealth": {
|
|
"title": "System Health",
|
|
"containers": "Containers",
|
|
"proxies": "Proxies",
|
|
"recentErrors": "Recent Errors"
|
|
},
|
|
"daemons": {
|
|
"title": "Daemons",
|
|
"refresh": "Refresh",
|
|
"refreshing": "Refreshing",
|
|
"docker": "Docker Engine",
|
|
"npm": "Nginx Proxy Manager",
|
|
"traefik": "Traefik",
|
|
"proxy": "Proxy",
|
|
"online": "Online",
|
|
"offline": "Offline",
|
|
"notConfigured": "Not configured",
|
|
"containers": "Containers",
|
|
"running": "Running",
|
|
"paused": "Paused",
|
|
"stopped": "Stopped",
|
|
"version": "Version",
|
|
"apiVersion": "API Version",
|
|
"platform": "Platform",
|
|
"kernel": "Kernel",
|
|
"cpu": "CPU",
|
|
"memory": "Memory",
|
|
"storage": "Storage Driver",
|
|
"images": "Images",
|
|
"latency": "Latency",
|
|
"rootDir": "Root Dir",
|
|
"provider": "Provider",
|
|
"endpoint": "Endpoint",
|
|
"proxyHosts": "Proxy Hosts",
|
|
"managed": "managed",
|
|
"external": "external",
|
|
"accessLists": "Access Lists",
|
|
"certificates": "Certificates",
|
|
"dockerHint": "Check that the Docker daemon is running and that the socket is reachable.",
|
|
"proxyHint": "Verify the proxy URL, credentials, and that the service is listening.",
|
|
"noProxyDesc": "No proxy provider is configured. Tinyforge can manage routes via Nginx Proxy Manager or Traefik.",
|
|
"configureProxy": "Configure in Settings"
|
|
},
|
|
"dns": {
|
|
"title": "DNS Records",
|
|
"description": "View and manage DNS records created by Tinyforge.",
|
|
"wildcardActive": "Wildcard DNS Mode Active",
|
|
"wildcardActiveDesc": "DNS records are managed externally via wildcard DNS. Disable wildcard DNS in Settings to manage records individually.",
|
|
"refresh": "Refresh",
|
|
"syncNow": "Sync Now",
|
|
"syncing": "Syncing...",
|
|
"syncComplete": "Sync complete: {created} created, {deleted} deleted, {synced} already synced",
|
|
"syncFailed": "DNS sync failed",
|
|
"searchPlaceholder": "Search by FQDN...",
|
|
"allConsumers": "All consumers",
|
|
"managed": "Managed (instances)",
|
|
"standalone": "Standalone proxies",
|
|
"orphaned": "Orphaned",
|
|
"allStatuses": "All statuses",
|
|
"statusSynced": "Synced",
|
|
"statusMissing": "Missing",
|
|
"statusOrphaned": "Orphaned",
|
|
"columnFqdn": "FQDN",
|
|
"columnType": "Type",
|
|
"columnValue": "Value",
|
|
"columnConsumer": "Consumer",
|
|
"columnStatus": "Status",
|
|
"columnActions": "Actions",
|
|
"noConsumer": "No consumer",
|
|
"noRecords": "No DNS records found. Records will appear here when services are deployed.",
|
|
"noMatchingRecords": "No records match the current filters.",
|
|
"deleteRecord": "Delete record",
|
|
"recordDeleted": "DNS record {fqdn} deleted",
|
|
"deleteFailed": "Failed to delete DNS record",
|
|
"loadFailed": "Failed to load DNS records",
|
|
"totalRecords": "Total: {count}",
|
|
"syncedCount": "Synced: {count}",
|
|
"missingCount": "Missing: {count}",
|
|
"orphanedCount": "Orphaned: {count}"
|
|
},
|
|
"language": {
|
|
"en": "English",
|
|
"ru": "Russian"
|
|
},
|
|
"stacks": {
|
|
"eyebrow": "THE FORGE",
|
|
"title": "Stacks",
|
|
"lede": "Compose blueprints, forged as <em>atomic units</em>. Spin up services, iterate on revisions, roll back without breaking a sweat.",
|
|
"newStack": "New stack",
|
|
"refresh": "Refresh",
|
|
"total": "Total",
|
|
"running": "Running",
|
|
"deploying": "Forging",
|
|
"failed": "Failed",
|
|
"stopped": "Cold",
|
|
"empty": {
|
|
"title": "The anvil is cold.",
|
|
"desc": "Upload a docker-compose.yml to forge your first stack."
|
|
},
|
|
"card": {
|
|
"noDescription": "No description",
|
|
"updated": "Updated",
|
|
"start": "Start",
|
|
"stop": "Stop",
|
|
"delete": "Delete",
|
|
"open": "Open"
|
|
},
|
|
"new": {
|
|
"eyebrow": "NEW BLUEPRINT",
|
|
"title": "Forge a new stack.",
|
|
"lede": "Upload or paste a <code>docker-compose.yml</code>. All services in the blueprint deploy as a single atomic unit.",
|
|
"back": "Stacks",
|
|
"name": "Name",
|
|
"namePlaceholder": "my-app-stack",
|
|
"nameHint": "Lowercase, hyphenated. Used as the compose project name.",
|
|
"description": "Description",
|
|
"descriptionPlaceholder": "What does this stack do?",
|
|
"composeYaml": "Compose YAML",
|
|
"required": "required",
|
|
"optional": "optional",
|
|
"loadSample": "Load sample",
|
|
"uploadFile": "Upload file",
|
|
"dropHere": "Drop a docker-compose.yml here",
|
|
"dropSub": "or click to browse · or use <strong>Load sample</strong> above",
|
|
"lines": "{n} lines",
|
|
"bytes": "{n} bytes",
|
|
"clear": "Clear",
|
|
"deployImmediate": "Deploy immediately",
|
|
"deployHint": "Strike while the iron's hot. If unchecked, the stack is saved cold.",
|
|
"cancel": "Cancel",
|
|
"forging": "Forging…",
|
|
"forgeAndDeploy": "Forge & deploy",
|
|
"saveBlueprint": "Save blueprint",
|
|
"errorRequired": "Name and compose YAML are required.",
|
|
"errorCreate": "Failed to create stack"
|
|
},
|
|
"detail": {
|
|
"manifest": "MANIFEST",
|
|
"loading": "Loading blueprint…",
|
|
"composeProject": "COMPOSE PROJECT",
|
|
"noDescription": "No description",
|
|
"refresh": "Refresh",
|
|
"start": "Start",
|
|
"stop": "Stop",
|
|
"delete": "Delete",
|
|
"fault": "FAULT",
|
|
"err": "ERR",
|
|
"stats": {
|
|
"services": "Services",
|
|
"servicesSub": "in blueprint",
|
|
"running": "Running",
|
|
"runningSub": "active containers",
|
|
"revisions": "Revisions",
|
|
"revisionsSub": "in history",
|
|
"current": "Current",
|
|
"currentSub": "deployed"
|
|
},
|
|
"services": {
|
|
"title": "Services",
|
|
"count": "{n} on the floor",
|
|
"empty": "— no containers running —"
|
|
},
|
|
"tabs": {
|
|
"blueprint": "Blueprint",
|
|
"revisions": "Revisions",
|
|
"logs": "Logs"
|
|
},
|
|
"yaml": {
|
|
"currentRevision": "Current revision",
|
|
"edit": "Edit & redeploy",
|
|
"cancel": "Cancel",
|
|
"forging": "Forging…",
|
|
"deployNew": "Deploy new revision"
|
|
},
|
|
"revisions": {
|
|
"current": "CURRENT",
|
|
"by": "by",
|
|
"rollback": "← Rollback to this revision",
|
|
"rollbackTitle": "Rollback to revision?",
|
|
"rollbackMessage": "Create a new revision from rev {n} and redeploy the stack.",
|
|
"rollbackConfirm": "Rollback"
|
|
},
|
|
"logs": {
|
|
"service": "Service:",
|
|
"allServices": "All services",
|
|
"fetching": "Fetching…",
|
|
"fetch": "Fetch logs",
|
|
"empty": "— no logs loaded. tap fetch. —"
|
|
},
|
|
"delete": {
|
|
"title": "Delete stack?",
|
|
"messageBase": "This runs 'docker compose down' and removes \"{name}\".",
|
|
"messageVolumes": " Named volumes will also be removed.",
|
|
"confirm": "Delete"
|
|
},
|
|
"errors": {
|
|
"load": "Failed to load stack",
|
|
"stop": "Stop failed",
|
|
"start": "Start failed",
|
|
"update": "Update failed",
|
|
"rollback": "Rollback failed",
|
|
"delete": "Delete failed",
|
|
"fetchLogs": "Failed to load logs"
|
|
}
|
|
}
|
|
},
|
|
"timezone": {
|
|
"eyebrow": "The Forge // Chronograph",
|
|
"title": "Display timezone",
|
|
"subtitle": "All dates across Tinyforge — event log, deploys, backups, sites — render in this zone.",
|
|
"modeLabel": "Detection mode",
|
|
"modeAuto": "Auto-detect",
|
|
"modeManual": "Manual",
|
|
"autoDetect": "Auto-detect from browser",
|
|
"autoBadge": "Auto",
|
|
"activeZone": "Active zone",
|
|
"changeZone": "Change timezone",
|
|
"clickToChange": "Click to pick a zone →",
|
|
"pickerTitle": "Select timezone",
|
|
"pickerPlaceholder": "Search zones — city, region, UTC offset…",
|
|
"groupAuto": "Detection",
|
|
"groupPopular": "Popular",
|
|
"groupAll": "All timezones",
|
|
"previewFull": "Full timestamp",
|
|
"previewDate": "Date only",
|
|
"previewHint": "Timestamps like the event log will look exactly like this."
|
|
},
|
|
"settingsDns": {
|
|
"title": "DNS Configuration",
|
|
"description": "Choose whether routes rely on a wildcard record or per-subdomain records managed by a DNS provider."
|
|
},
|
|
"settingsIntegrations": {
|
|
"title": "Integrations",
|
|
"outgoing": "Outgoing notifications",
|
|
"outgoingDesc": "Where Tinyforge posts deploy and alert events. Paste a webhook URL (Apprise, Discord, Slack, your own handler).",
|
|
"incoming": "Incoming webhooks",
|
|
"incomingMovedDesc": "Inbound webhooks are now scoped per entity. Open a project or static site to view and rotate its webhook URL."
|
|
},
|
|
"webhookPanel": {
|
|
"copy": "Copy",
|
|
"copied": "Webhook URL copied to clipboard",
|
|
"copyFailed": "Failed to copy to clipboard",
|
|
"noUrl": "No webhook URL configured",
|
|
"loadFailed": "Failed to load webhook URL",
|
|
"regenerate": "Regenerate URL",
|
|
"regenerated": "Webhook URL regenerated",
|
|
"regenerateFailed": "Failed to regenerate webhook URL",
|
|
"regenerateWarning": "Regenerating invalidates the current URL. Update any CI pipeline or Git webhook that uses it.",
|
|
"confirmRegenerate": "Replace the current URL?",
|
|
"confirmYes": "Regenerate",
|
|
"confirmNo": "Cancel"
|
|
},
|
|
"settingsMaintenance": {
|
|
"title": "Maintenance",
|
|
"thresholds": "Thresholds",
|
|
"thresholdsDesc": "Tune when Tinyforge flags stale containers and warns about unused image disk usage.",
|
|
"dangerZone": "Danger zone"
|
|
}
|
|
}
|