The AutoDeploy API provides a RESTful interface for managing deployment projects and executing deployments. It runs as an Express.js server with CORS support and real-time streaming capabilities.
- SSH Key Authentication: Support for private key authentication with passphrases
- Port Forwarding: SSH tunnel configuration for database access
- Deployment History: Detailed history tracking with separate logs storage
- Statistics Endpoint: Global deployment metrics and analytics
- Enhanced Error Handling: Graceful handling of "nothing to commit" scenarios
- Monorepo Support: Full API support for monorepo deployments
- File-based Configuration: Organized storage with separate JSON files
http://localhost:3000/api
Currently, the API does not require authentication. Future versions will support token-based authentication.
All requests and responses use JSON format:
Content-Type: application/json
GET /api/healthResponse
{
"status": "ok",
"version": "1.0.0"
}GET /api/projectsResponse
[
{
"name": "my-project",
"localPath": "/home/user/projects/my-project",
"ssh": {
"host": "server.example.com",
"username": "deploy",
"port": 22,
"password": "encrypted", // Only shown if using password auth
"privateKeyPath": "/path/to/key.pem", // Only shown if using key auth
"passphrase": "encrypted" // Only shown if key has passphrase
},
"remotePath": "/var/www/my-project",
"localSteps": [
{
"name": "Build Application",
"command": "npm run build",
"workingDir": ".",
"continueOnError": false
}
],
"deploymentSteps": [
{
"name": "Install Dependencies",
"command": "npm install",
"workingDir": ".",
"continueOnError": false
}
],
"lastDeployment": "2024-01-10T10:30:00Z",
"deploymentCount": 15,
"lastDeploymentStatus": "success"
}
]GET /api/projects/:nameParameters
name(string): Project name
Response
{
"name": "my-project",
"localPath": "/home/user/projects/my-project",
"ssh": {
"host": "server.example.com",
"username": "deploy",
"port": 22
},
"remotePath": "/var/www/my-project",
"localSteps": [...],
"deploymentSteps": [...],
"deploymentHistory": [...],
"createdAt": "2024-01-01T10:00:00Z",
"updatedAt": "2024-01-10T15:30:00Z"
}Error Response (404)
{
"error": "Project not found"
}POST /api/projectsRequest Body
Option 1: Password Authentication
{
"name": "new-project",
"localPath": "/home/user/projects/new-project",
"ssh": {
"host": "server.example.com",
"username": "deploy",
"password": "secret",
"port": 22
},
"remotePath": "/var/www/new-project",
"localSteps": [],
"deploymentSteps": []
}Option 2: Private Key Authentication
{
"name": "new-project",
"localPath": "/home/user/projects/new-project",
"ssh": {
"host": "server.example.com",
"username": "deploy",
"privateKeyPath": "/Users/john/.ssh/deploy-key.pem",
"passphrase": "optional-key-passphrase", // Optional, omit if no passphrase
"port": 22
},
"remotePath": "/var/www/new-project",
"localSteps": [],
"deploymentSteps": []
}Option 3: Private Key with SSH Options
{
"name": "new-project",
"localPath": "/home/user/projects/new-project",
"ssh": {
"host": "server.example.com",
"username": "deploy",
"privateKeyPath": "/Users/john/.ssh/deploy-key.pem",
"port": 22,
"sshOptions": {
"localPortForwarding": [{
"localPort": 5433,
"remoteHost": "database.internal",
"remotePort": 5432
}]
}
},
"remotePath": "/var/www/new-project",
"localSteps": [],
"deploymentSteps": []
}Response (201)
{
"success": true,
"project": {
"name": "new-project",
...
}
}Error Response (400)
{
"error": "SSH connection failed",
"message": "Connection timeout"
}PUT /api/projects/:nameParameters
name(string): Project name
Request Body
{
"localPath": "/new/path/to/project",
"localSteps": [...],
"deploymentSteps": [...]
}Note: The project configuration is now stored in separate files:
config.json- Core settings and SSH credentialslocal-steps.json- Steps that run locallyremote-steps.json- Steps that run on the serverhistory.json- Deployment historystats.json- Deployment statistics
Response
{
"success": true
}DELETE /api/projects/:nameParameters
name(string): Project name
Response
{
"success": true
}GET /api/deployments/:nameParameters
name(string): Project name
Headers
Accept: text/event-stream
Event Stream Format
data: {"type":"start","message":"Deploying my-project..."}
data: {"type":"progress","message":"Running local steps..."}
data: {"type":"step","message":"Running: Build Application","isLocal":true}
data: {"type":"step-complete","message":"Build completed","step":"Build Application","duration":5000}
data: {"type":"progress","message":"Committing and pushing local changes..."}
data: {"type":"step","message":"Running: Install Dependencies"}
data: {"type":"step-complete","message":"npm install completed","step":"Install Dependencies","duration":15000}
data: {"type":"complete","message":"Deployment completed successfully!","totalDuration":45000}
event: close
data: {}
Event Types
start: Deployment initiatedprogress: General progress updatestep: Starting a deployment step (includesisLocalflag)step-complete: Step finished successfully (includesdurationin ms)step-error: Step failed (includes error details)error: General errorcomplete: Deployment finished successfully (includestotalDuration)stopped: Deployment was manually stoppedclose: Stream closing
GET /api/projects/:name/deploymentsParameters
name(string): Project name
Query Parameters
limit(number): Number of deployments to return (default: 10)
Response
[
{
"id": "1704883800000",
"timestamp": "2024-01-10T10:30:00Z",
"success": true,
"duration": 45000,
"stopped": false,
"error": null,
"steps": [
{
"name": "Build Application",
"success": true,
"output": "Build completed",
"duration": 5000,
"isLocal": true
},
{
"name": "Install Dependencies",
"success": true,
"output": "added 150 packages",
"duration": 15000,
"isLocal": false
}
]
}
]GET /api/statsResponse
{
"totalDeployments": 150,
"deploymentsToday": 5,
"lastDeployment": {
"timestamp": "2024-01-10T10:30:00Z",
"projectName": "my-project",
"success": true
},
"activeProjects": 3
}POST /api/test-connectionRequest Body
Option 1: Password Authentication
{
"host": "server.example.com",
"username": "deploy",
"password": "secret",
"port": 22
}Option 2: Private Key Authentication
{
"host": "server.example.com",
"username": "deploy",
"privateKeyPath": "/Users/john/.ssh/deploy-key.pem",
"passphrase": "optional-passphrase",
"port": 22
}Response
{
"success": true,
"message": "Connection successful"
}Error Response
{
"success": false,
"message": "Authentication failed"
}GET /api/statsResponse
{
"totalDeployments": 156,
"deploymentsToday": 12,
"activeProjects": 8,
"lastDeployment": {
"timestamp": "2025-01-12T10:30:00Z",
"projectName": "my-project",
"success": true
}
}{
"ssh": {
"host": "server.example.com",
"username": "deploy",
"password": "your-password",
"port": 22
}
}{
"ssh": {
"host": "server.example.com",
"username": "deploy",
"privateKeyPath": "/Users/me/.ssh/deploy-key.pem",
"passphrase": "key-passphrase",
"port": 22,
"sshOptions": {
"ServerAliveInterval": 60,
"ServerAliveCountMax": 3
}
}
}{
"ssh": {
"host": "bastion.example.com",
"username": "deploy",
"privateKeyPath": "/Users/me/.ssh/bastion-key.pem",
"port": 22,
"forwardRules": [
"5433:database.internal:5432",
"6380:redis.internal:6379"
]
}
}All endpoints may return these standard error responses:
{
"error": "Invalid request data"
}{
"error": "Resource not found"
}{
"error": "Internal server error message"
}Future versions will support WebSocket connections for real-time updates:
// Connection
ws://localhost:3000/ws
// Subscribe to project updates
{
"type": "subscribe",
"project": "my-project"
}
// Receive deployment updates
{
"type": "deployment",
"project": "my-project",
"status": "started",
"timestamp": "2024-01-10T10:30:00Z"
}Currently no rate limiting is implemented. Future versions will include:
- 100 requests per minute for general endpoints
- 10 deployments per hour per project
- Configurable limits
The API supports CORS for all origins in development mode. Production deployments should configure specific allowed origins.
// Current configuration
cors: {
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}{
"name": "node-api",
"localPath": "/Users/me/projects/api",
"remotePath": "/var/www/api",
"ssh": {
"host": "api.example.com",
"username": "deploy",
"privateKeyPath": "/Users/me/.ssh/deploy.pem",
"port": 22
},
"localSteps": [
{
"name": "Install Dependencies",
"command": "npm install",
"workingDir": ".",
"continueOnError": false
},
{
"name": "Run Tests",
"command": "npm test",
"workingDir": ".",
"continueOnError": false
}
],
"deploymentSteps": [
{
"name": "Pull Latest Code",
"command": "git pull origin main",
"workingDir": ".",
"continueOnError": false
},
{
"name": "Install Production Dependencies",
"command": "npm ci --production",
"workingDir": ".",
"continueOnError": false
},
{
"name": "Restart Application",
"command": "pm2 restart ecosystem.config.js",
"workingDir": ".",
"continueOnError": false
}
]
}{
"name": "django-app",
"localPath": "/Users/me/projects/django-app",
"remotePath": "/home/deploy/django-app",
"ssh": {
"host": "django.example.com",
"username": "deploy",
"password": "encrypted-password",
"port": 22
},
"localSteps": [
{
"name": "Create Virtual Environment",
"command": "python -m venv venv",
"workingDir": "."
},
{
"name": "Run Tests",
"command": "./venv/bin/python manage.py test",
"workingDir": "."
}
],
"deploymentSteps": [
{
"name": "Pull Latest Code",
"command": "git pull origin main",
"workingDir": "."
},
{
"name": "Install Dependencies",
"command": "pip install -r requirements.txt",
"workingDir": "."
},
{
"name": "Run Migrations",
"command": "python manage.py migrate",
"workingDir": "."
},
{
"name": "Collect Static Files",
"command": "python manage.py collectstatic --noinput",
"workingDir": "."
},
{
"name": "Restart Gunicorn",
"command": "sudo supervisorctl restart gunicorn",
"workingDir": "."
}
]
}curl http://localhost:3000/api/projectscurl -X POST http://localhost:3000/api/projects \
-H "Content-Type: application/json" \
-d '{
"name": "test-project",
"localPath": "/home/user/test",
"ssh": {
"host": "example.com",
"username": "user",
"password": "pass",
"port": 22
},
"remotePath": "/var/www/test",
"localSteps": [],
"deploymentSteps": []
}'curl -N http://localhost:3000/api/deployments/my-project \
-H "Accept: text/event-stream"// List projects
const response = await fetch('http://localhost:3000/api/projects');
const projects = await response.json();
// Start deployment with EventSource
const eventSource = new EventSource('/api/deployments/my-project');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(data.type, data.message);
};
eventSource.addEventListener('close', () => {
eventSource.close();
});import axios from 'axios';
const api = axios.create({
baseURL: 'http://localhost:3000/api',
timeout: 30000
});
// Get all projects
const { data } = await api.get('/projects');
// Create project
const newProject = await api.post('/projects', {
name: 'node-project',
// ... other fields
});# Standalone
node src/api/server.js
# With CLI
autodeploy gui --api-port 3000
# Environment variables
PORT=3001 node src/api/server.js# Health check
curl http://localhost:3000/api/health
# With jq for pretty output
curl http://localhost:3000/api/projects | jqSet DEBUG=autodeploy:* environment variable for detailed logging.
-
Authentication & Authorization
- JWT token support
- Role-based access control
- API key management
-
Advanced Features
- Deployment scheduling
- Rollback support
- Deployment queuing
- Webhook notifications
-
Monitoring
- Prometheus metrics
- Health check endpoints
- Performance tracking
-
API Versioning
- Version in URL path
- Header-based versioning
- Deprecation notices