Created
August 12, 2025 04:07
-
-
Save thrawn01/0ad114e7eb77f4332eb56ed17651224b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const pulumi = require("@pulumi/pulumi"); | |
const uncloud = require("@uncloud/pulumi"); | |
// Configure the Uncloud provider | |
const provider = new uncloud.Provider("uncloud-provider", { | |
// Connect to any machine in the cluster via SSH | |
sshHost: "[email protected]", | |
sshPort: 22, | |
// Optional: specify cluster if you have multiple | |
cluster: "production", | |
// Optional: SSH key path (defaults to ~/.ssh/id_rsa) | |
sshKeyPath: "~/.ssh/uncloud_key" | |
}); | |
// Create a persistent volume for PostgreSQL data | |
const pgVolume = new uncloud.Volume("postgres-data", { | |
name: "postgres-data", | |
// Uncloud manages volumes across cluster nodes | |
}, { provider }); | |
// Deploy PostgreSQL database | |
const database = new uncloud.Service("postgres", { | |
name: "postgres", | |
image: "postgres:15-alpine", | |
// Environment variables for PostgreSQL | |
environment: { | |
POSTGRES_DB: "webapp", | |
POSTGRES_USER: "webapp_user", | |
POSTGRES_PASSWORD: pulumi.secret("super_secret_password"), | |
PGDATA: "/var/lib/postgresql/data/pgdata" | |
}, | |
// Mount the persistent volume | |
volumes: [{ | |
name: pgVolume.name, | |
mountPath: "/var/lib/postgresql/data" | |
}], | |
// Internal port for database connections | |
ports: [{ | |
containerPort: 5432, | |
protocol: "tcp" | |
}], | |
// Deployment configuration | |
replicas: 1, // Database should typically be single instance | |
// Resource limits | |
resources: { | |
memory: "512Mi", | |
cpu: "0.5" | |
}, | |
// Health check | |
healthCheck: { | |
command: ["pg_isready", "-U", "webapp_user", "-d", "webapp"], | |
intervalSeconds: 10, | |
timeoutSeconds: 5, | |
retries: 3 | |
}, | |
// Restart policy | |
restartPolicy: "always" | |
}, { provider }); | |
// Create a volume for web app uploads/data (optional) | |
const appVolume = new uncloud.Volume("webapp-uploads", { | |
name: "webapp-uploads" | |
}, { provider }); | |
// Deploy the web application | |
const webApp = new uncloud.Service("webapp", { | |
name: "webapp", | |
image: "mycompany/webapp:latest", | |
// Environment variables for the web app | |
environment: { | |
DATABASE_URL: pulumi.interpolate`postgresql://webapp_user:super_secret_password@${database.internalHostname}:5432/webapp`, | |
NODE_ENV: "production", | |
PORT: "3000" | |
}, | |
// Mount uploads volume | |
volumes: [{ | |
name: appVolume.name, | |
mountPath: "/app/uploads" | |
}], | |
// Port configuration | |
ports: [{ | |
containerPort: 3000, | |
protocol: "http", | |
// Expose via custom domain with automatic HTTPS | |
publicDomain: "myapp.example.com" | |
}], | |
// Scale to multiple replicas for high availability | |
replicas: 3, | |
// Resource limits | |
resources: { | |
memory: "256Mi", | |
cpu: "0.25" | |
}, | |
// Health check | |
healthCheck: { | |
httpPath: "/health", | |
port: 3000, | |
intervalSeconds: 15, | |
timeoutSeconds: 10, | |
retries: 3 | |
}, | |
// Deployment strategy | |
deploymentStrategy: { | |
type: "rolling", | |
maxUnavailable: 1, | |
maxSurge: 1 | |
}, | |
// Dependencies - ensure database starts first | |
dependsOn: [database], | |
// Restart policy | |
restartPolicy: "always" | |
}, { provider }); | |
// Optional: Deploy a Redis cache | |
const cache = new uncloud.Service("redis", { | |
name: "redis", | |
image: "redis:7-alpine", | |
ports: [{ | |
containerPort: 6379, | |
protocol: "tcp" | |
}], | |
replicas: 1, | |
resources: { | |
memory: "128Mi", | |
cpu: "0.1" | |
}, | |
// Redis persistence | |
volumes: [{ | |
name: "redis-data", | |
mountPath: "/data" | |
}], | |
healthCheck: { | |
command: ["redis-cli", "ping"], | |
intervalSeconds: 10, | |
timeoutSeconds: 3, | |
retries: 3 | |
} | |
}, { provider }); | |
// Optional: Create a network policy (if Uncloud supports it) | |
const networkPolicy = new uncloud.NetworkPolicy("webapp-network", { | |
name: "webapp-network", | |
// Allow webapp to communicate with database and cache | |
rules: [{ | |
from: [{ service: webApp.name }], | |
to: [ | |
{ service: database.name, ports: [5432] }, | |
{ service: cache.name, ports: [6379] } | |
] | |
}], | |
// Allow external traffic to webapp | |
ingress: [{ | |
from: "external", | |
to: { service: webApp.name, ports: [3000] } | |
}] | |
}, { provider }); | |
// Output important information | |
exports.webAppUrl = webApp.publicUrl; | |
exports.webAppInternalHostname = webApp.internalHostname; | |
exports.databaseInternalHostname = database.internalHostname; | |
exports.clusterDomain = webApp.clusterDomain; | |
// Output cluster information | |
exports.cluster = { | |
machines: provider.clusterMachines, | |
domain: provider.clusterDomain | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment