Files
idea.llm.gitea.repo.docker.…/api/openapi.json
Clint Masden feec35ffce Add full REST API for all deployment operations (projects, servers, docker)
Port all IPC handlers to HTTP endpoints so the UI and LLM use the same
API. Adds routes/projects.js (scan, compare, init), routes/servers.js
(CRUD, containers, logs), routes/docker.js (build, deploy, pull, vscode-diff).
Enhanced ssh.js with full SSHService class (SFTP upload/download).
Updated renderer api.js to use fetch instead of window.api IPC.
Added concurrently for npm run dev (API + Vite + Electron).
OpenAPI spec now covers all 24 endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 11:17:40 -06:00

621 lines
21 KiB
JSON

{
"openapi": "3.1.0",
"info": {
"title": "Docker Deployment & Coolify API",
"description": "REST API for managing Docker deployments, Coolify applications, Traefik routing, and server management. Used by both the desktop UI and LLM agents.",
"version": "2.0.0"
},
"servers": [
{ "url": "http://localhost:3100", "description": "Local dev" }
],
"tags": [
{ "name": "Projects", "description": "Local project scanning and comparison" },
{ "name": "Servers", "description": "Deployment server CRUD and remote scanning" },
{ "name": "Docker", "description": "Build, deploy, pull files" },
{ "name": "Coolify Apps", "description": "Coolify application management" },
{ "name": "Coolify Environment", "description": "App environment variables" },
{ "name": "Coolify Deploy", "description": "Deployment pipelines and drift checks" },
{ "name": "Coolify Infrastructure", "description": "Traefik routes and port management" },
{ "name": "System", "description": "Health checks and config" }
],
"paths": {
"/api/projects": {
"get": {
"operationId": "scanLocalProjects",
"summary": "Scan local projects",
"description": "Scans the configured projectsRoot directory for projects with Dockerfiles, docker-compose files, coolify.json, etc.",
"tags": ["Projects"],
"responses": {
"200": {
"description": "Array of local project info",
"content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/LocalProject" } } } }
}
}
}
},
"/api/projects/compare": {
"post": {
"operationId": "compareProject",
"summary": "Compare local vs deployed files",
"description": "Compares docker-compose.yml, .env, data/, and additional configured files between local and remote.",
"tags": ["Projects"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"projectPath": { "type": "string", "description": "Absolute local path to the project" },
"serverId": { "type": "string", "description": "Server ID to compare against" },
"remotePath": { "type": "string", "description": "Remote path (e.g. ~/containers/myapp)" }
},
"required": ["projectPath", "serverId", "remotePath"]
}
}
}
},
"responses": {
"200": { "description": "Comparison result with file-by-file diff statuses" }
}
}
},
"/api/projects/init": {
"post": {
"operationId": "initProject",
"summary": "Initialize a project with deployment config",
"tags": ["Projects"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"projectPath": { "type": "string" }
},
"required": ["projectPath"]
}
}
}
},
"responses": {
"200": { "description": "Init result" }
}
}
},
"/api/servers": {
"get": {
"operationId": "listServers",
"summary": "List deployment servers",
"tags": ["Servers"],
"responses": {
"200": {
"description": "Array of configured servers",
"content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Server" } } } }
}
}
},
"post": {
"operationId": "saveServer",
"summary": "Add or update a server",
"tags": ["Servers"],
"requestBody": {
"required": true,
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Server" } } }
},
"responses": {
"200": { "description": "Saved server" }
}
}
},
"/api/servers/{id}": {
"delete": {
"operationId": "deleteServer",
"summary": "Delete a server",
"tags": ["Servers"],
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": {
"200": { "description": "Deletion confirmation" }
}
}
},
"/api/servers/{id}/scan": {
"get": {
"operationId": "scanServer",
"summary": "Scan remote server for deployed containers",
"description": "Lists ~/containers on the remote server and inspects each for docker-compose.yml, .env, data/, etc.",
"tags": ["Servers"],
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": {
"200": { "description": "Array of deployed projects on the server" }
}
}
},
"/api/servers/{id}/containers": {
"get": {
"operationId": "getRunningContainers",
"summary": "List running Docker containers on server",
"tags": ["Servers"],
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": {
"200": {
"description": "Array of running containers",
"content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "containers": { "type": "array", "items": { "$ref": "#/components/schemas/Container" } } } } } }
}
}
}
},
"/api/servers/{id}/logs": {
"get": {
"operationId": "getContainerLogs",
"summary": "Get container logs from server",
"tags": ["Servers"],
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } },
{ "name": "containerName", "in": "query", "schema": { "type": "string" } },
{ "name": "remotePath", "in": "query", "schema": { "type": "string" } },
{ "name": "lines", "in": "query", "schema": { "type": "integer", "default": 100 } }
],
"responses": {
"200": { "description": "Container logs" }
}
}
},
"/api/docker/build": {
"post": {
"operationId": "buildTar",
"summary": "Build Docker image tar for a project",
"description": "Runs the project's build-image-tar.ps1 script to create a .tar image file.",
"tags": ["Docker"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"projectPath": { "type": "string" }
},
"required": ["projectPath"]
}
}
}
},
"responses": {
"200": { "description": "Build result with output" }
}
}
},
"/api/docker/deploy": {
"post": {
"operationId": "deployProject",
"summary": "Deploy project to server via SSH",
"description": "Uploads tar + compose + env files, loads Docker image, runs docker compose up. Includes health check polling.",
"tags": ["Docker"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"projectPath": { "type": "string", "description": "Local project path" },
"serverId": { "type": "string", "description": "Target server ID" },
"remotePath": { "type": "string", "description": "Remote deploy path (e.g. ~/containers/myapp)" }
},
"required": ["projectPath", "serverId", "remotePath"]
}
}
}
},
"responses": {
"200": {
"description": "Deploy result with health status",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeployResult" } } }
}
}
}
},
"/api/docker/pull": {
"post": {
"operationId": "pullFiles",
"summary": "Pull files from remote server",
"description": "Downloads files/directories from the remote server to local paths via SFTP.",
"tags": ["Docker"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"serverId": { "type": "string" },
"files": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"remotePath": { "type": "string" },
"localPath": { "type": "string" },
"type": { "type": "string", "enum": ["file", "directory"] }
}
}
}
},
"required": ["serverId", "files"]
}
}
}
},
"responses": {
"200": { "description": "Pull result with pulled/errors arrays" }
}
}
},
"/api/docker/vscode-diff": {
"post": {
"operationId": "openVSCodeDiff",
"summary": "Open VS Code diff between local and remote file",
"tags": ["Docker"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"serverId": { "type": "string" },
"localPath": { "type": "string" },
"remoteFilePath": { "type": "string" }
},
"required": ["serverId", "localPath", "remoteFilePath"]
}
}
}
},
"responses": {
"200": { "description": "Success or error" }
}
}
},
"/api/coolify/apps": {
"get": {
"operationId": "listCoolifyApps",
"summary": "List all Coolify apps",
"description": "Returns all applications from Coolify, enriched with HOST_PORT env vars.",
"tags": ["Coolify Apps"],
"responses": {
"200": {
"description": "Array of Coolify applications",
"content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CoolifyApp" } } } }
}
}
},
"post": {
"operationId": "createCoolifyApp",
"summary": "Create a new Coolify application",
"tags": ["Coolify Apps"],
"requestBody": {
"required": true,
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCoolifyAppRequest" } } }
},
"responses": {
"200": { "description": "Created app object" }
}
}
},
"/api/coolify/apps/find/{name}": {
"get": {
"operationId": "findCoolifyApp",
"summary": "Find Coolify app by name",
"tags": ["Coolify Apps"],
"parameters": [
{ "name": "name", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": {
"200": { "description": "App object or null" }
}
}
},
"/api/coolify/apps/{uuid}": {
"patch": {
"operationId": "updateCoolifyApp",
"summary": "Update an existing Coolify app",
"tags": ["Coolify Apps"],
"parameters": [
{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }
],
"requestBody": {
"required": true,
"content": { "application/json": { "schema": { "type": "object" } } }
},
"responses": { "200": { "description": "Updated app" } }
},
"delete": {
"operationId": "deleteCoolifyApp",
"summary": "Delete a Coolify app",
"tags": ["Coolify Apps"],
"parameters": [
{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Deletion confirmation" } }
}
},
"/api/coolify/apps/{uuid}/envs": {
"get": {
"operationId": "listCoolifyEnvs",
"summary": "List env vars for a Coolify app",
"tags": ["Coolify Environment"],
"parameters": [
{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Array of env vars" } }
},
"post": {
"operationId": "setCoolifyEnv",
"summary": "Set an environment variable",
"tags": ["Coolify Environment"],
"parameters": [
{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"key": { "type": "string" },
"value": { "type": "string" }
},
"required": ["key", "value"]
}
}
}
},
"responses": { "200": { "description": "Env var created/updated" } }
}
},
"/api/coolify/apps/{uuid}/deploy": {
"post": {
"operationId": "deployCoolifyApp",
"summary": "Trigger Coolify deployment",
"tags": ["Coolify Deploy"],
"parameters": [
{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Deployment triggered" } }
}
},
"/api/coolify/servers": {
"get": {
"operationId": "listCoolifyServers",
"summary": "List all Coolify servers",
"tags": ["Coolify Infrastructure"],
"responses": { "200": { "description": "Array of Coolify servers" } }
}
},
"/api/coolify/next-port": {
"get": {
"operationId": "getNextPort",
"summary": "Get next available HOST_PORT",
"description": "Scans Coolify env vars and Traefik config to find the highest used port.",
"tags": ["Coolify Infrastructure"],
"responses": {
"200": {
"description": "Next port info",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"nextPort": { "type": "integer" },
"usedPorts": { "type": "array", "items": { "type": "integer" } }
}
}
}
}
}
}
}
},
"/api/coolify/routes": {
"post": {
"operationId": "addTraefikRoute",
"summary": "Add a Traefik route via SSH",
"tags": ["Coolify Infrastructure"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"routeName": { "type": "string" },
"domain": { "type": "string" },
"port": { "type": "integer" }
},
"required": ["routeName", "domain", "port"]
}
}
}
},
"responses": { "200": { "description": "Route added or already exists" } }
}
},
"/api/coolify/drift": {
"post": {
"operationId": "checkDrift",
"summary": "Check drift between coolify.json and live state",
"tags": ["Coolify Deploy"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"projectPath": { "type": "string" },
"appName": { "type": "string" }
},
"required": ["projectPath"]
}
}
}
},
"responses": { "200": { "description": "Drift check result" } }
}
},
"/api/coolify/upsert": {
"post": {
"operationId": "upsertCoolifyApp",
"summary": "Full deploy pipeline: config → create/update → env → route → deploy",
"description": "Reads coolify.json, creates or updates the Coolify app, sets HOST_PORT, configures Traefik, writes changelog, and triggers deployment.",
"tags": ["Coolify Deploy"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"projectPath": { "type": "string" },
"appName": { "type": "string" }
},
"required": ["projectPath"]
}
}
}
},
"responses": {
"200": {
"description": "Upsert result with steps",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpsertResult" } } }
}
}
}
},
"/api/coolify/config": {
"get": {
"operationId": "readCoolifyConfig",
"summary": "Read coolify.json from a project",
"tags": ["System"],
"parameters": [
{ "name": "path", "in": "query", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Parsed coolify.json" } }
}
},
"/api/health": {
"get": {
"operationId": "healthCheck",
"summary": "Health check",
"tags": ["System"],
"responses": { "200": { "description": "Server status" } }
}
}
},
"components": {
"schemas": {
"LocalProject": {
"type": "object",
"properties": {
"name": { "type": "string" },
"path": { "type": "string" },
"hasDockerfile": { "type": "boolean" },
"hasDockerCompose": { "type": "boolean" },
"hasCoolifyJson": { "type": "boolean" },
"dockerStatus": { "type": "string", "enum": ["none", "partial", "configured"] },
"tarFile": { "type": "string", "nullable": true },
"serverId": { "type": "string", "nullable": true },
"remotePath": { "type": "string" }
}
},
"Server": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"host": { "type": "string" },
"username": { "type": "string" },
"useSudo": { "type": "boolean" }
}
},
"Container": {
"type": "object",
"properties": {
"name": { "type": "string" },
"status": { "type": "string" },
"ports": { "type": "string" }
}
},
"DeployResult": {
"type": "object",
"properties": {
"success": { "type": "boolean" },
"healthy": { "type": "boolean" },
"status": { "type": "string" },
"uploadedFiles": { "type": "array", "items": { "type": "string" } },
"message": { "type": "string" }
}
},
"CoolifyApp": {
"type": "object",
"properties": {
"uuid": { "type": "string" },
"name": { "type": "string" },
"build_pack": { "type": "string", "enum": ["dockercompose", "nixpacks", "dockerfile"] },
"git_repository": { "type": "string" },
"git_branch": { "type": "string" },
"status": { "type": "string" },
"fqdn": { "type": "string" },
"_host_port": { "type": "string", "nullable": true },
"_envs": { "type": "array" }
}
},
"CreateCoolifyAppRequest": {
"type": "object",
"properties": {
"name": { "type": "string" },
"buildpack": { "type": "string", "enum": ["dockercompose", "nixpacks"], "default": "dockercompose" },
"gitRepo": { "type": "string" },
"gitBranch": { "type": "string", "default": "master" },
"isStatic": { "type": "boolean", "default": false },
"publishDir": { "type": "string", "default": "dist" },
"portsExposes": { "type": "string", "default": "3000" },
"baseDirectory": { "type": "string", "default": "/" },
"dockerComposeLocation": { "type": "string", "default": "/docker-compose.yml" },
"serverUuid": { "type": "string" }
},
"required": ["name", "gitRepo"]
},
"UpsertResult": {
"type": "object",
"properties": {
"success": { "type": "boolean" },
"uuid": { "type": "string" },
"domain": { "type": "string" },
"changelogEntry": { "type": "object" },
"steps": { "type": "array", "items": { "$ref": "#/components/schemas/Step" } }
}
},
"Step": {
"type": "object",
"properties": {
"step": { "type": "string" },
"status": { "type": "string", "enum": ["running", "done", "error", "skipped", "warn"] },
"detail": { "type": "string" }
}
}
}
}
}