Este es el contenido del fichero
create_app.mdque cada desarrollador debe tener en~/.claude/create_app.md.
Claude Code lo usa como workflow para crear aplicaciones nuevas.
Opción A — Automático con Claude Code:
Durante el setup automático o al usar la plantilla CLAUDE.md, Claude Code descarga este fichero automáticamente.
Opción B — Copiar manualmente:
Copia desde # Crear una nueva aplicacion hasta el final y guárdalo como C:\Users\TU_USUARIO\.claude\create_app.md.
Opción C — Decirle a Claude Code:
Lee el fichero create_app.md de la wiki: http://192.168.1.10:3001/en/onboarding/fichero-create-app
Extrae el contenido del fichero y guárdalo como ~/.claude/create_app.md
Este archivo guia a Claude Code para crear aplicaciones nuevas en la
infraestructura de Pampling. Seguir los pasos en orden.
Las variables <ENTRE_ANGULOS> se leen del CLAUDE.md personal del desarrollador.
Las variables NOMBRE-APP y NOMBRE-REPO las proporciona el usuario.
Estos valores son fijos para toda la organizacion:
SERVER_IP = 192.168.1.10
COOLIFY_URL = http://192.168.1.10:8000
COOLIFY_SERVER = p9oujt6wvwz90l3zgzd1vexy
DEPLOY_KEY_UUID = lay870h6dq9p25wvj4la8otn
BITBUCKET_WS = pampling
Por defecto las apps van al proyecto IA Projects. Antes de crear la app,
preguntar al usuario en que proyecto debe ir:
Proyecto por defecto: IA PROJECTS → e11g6dohjsbfsucm9f2r3h9k
Claude Code: Antes de ejecutar el Paso 4, listar los proyectos
disponibles y preguntar al usuario:
"La app ira al proyecto IA PROJECTS. ¿Confirmas o prefieres otro proyecto?"Para listar proyectos:
curl -s -H 'Authorization: Bearer <COOLIFY_TOKEN>' \ http://192.168.1.10:8000/api/v1/projectsSi el usuario quiere un proyecto nuevo, crearlo:
curl -s -X POST \ -H 'Authorization: Bearer <COOLIFY_TOKEN>' \ -H 'Content-Type: application/json' \ -d '{"name": "NOMBRE PROYECTO"}' \ http://192.168.1.10:8000/api/v1/projects
<COOLIFY_TOKEN> → Token de Coolify API
<BITBUCKET_EMAIL> → Email de Atlassian
<BITBUCKET_API_TOKEN> → Token de Bitbucket API
<SSH_USER> → Usuario SSH en el servidor (opcional, para logs)
curl -s -X POST \
-u "<BITBUCKET_EMAIL>:<BITBUCKET_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"scm": "git",
"is_private": true,
"description": "Descripcion de NOMBRE-APP"
}' \
https://api.bitbucket.org/2.0/repositories/pampling/NOMBRE-REPO
Verificar que devuelve "type": "repository".
Luego anadir la deploy key de Coolify al repo:
# Obtener clave publica de Coolify
PUBKEY=$(curl -s \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
http://192.168.1.10:8000/api/v1/security/keys/lay870h6dq9p25wvj4la8otn \
| python -c "import sys,json; print(json.load(sys.stdin)['public_key'])")
# Anadir como deploy key en Bitbucket
curl -s -X POST \
-u "<BITBUCKET_EMAIL>:<BITBUCKET_API_TOKEN>" \
-H "Content-Type: application/json" \
-d "{\"key\": \"$PUBKEY\", \"label\": \"Coolify Deploy\"}" \
https://api.bitbucket.org/2.0/repositories/pampling/NOMBRE-REPO/deploy-keys
Cada aplicacion tiene su propio contenedor de base de datos. Crearlo via API:
# Generar contrasena segura
PG_PASSWORD=$(python -c "import secrets; print(secrets.token_urlsafe(48))")
# Crear contenedor PostgreSQL dedicado para esta app
DB_RESPONSE=$(curl -s -X POST \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"project_uuid": "<COOLIFY_PROJECT>",
"environment_name": "production",
"server_uuid": "p9oujt6wvwz90l3zgzd1vexy",
"name": "NOMBRE-APP-postgresql",
"postgres_user": "nombreapp_user",
"postgres_password": "'$PG_PASSWORD'",
"postgres_db": "nombreapp_db",
"image": "postgres:16-alpine",
"is_public": false
}' \
http://192.168.1.10:8000/api/v1/databases/postgresql)
DB_UUID=$(echo $DB_RESPONSE | python -c "import sys,json; print(json.load(sys.stdin)['uuid'])")
DB_INTERNAL_URL=$(echo $DB_RESPONSE | python -c "import sys,json; print(json.load(sys.stdin)['internal_db_url'])")
echo "DB UUID: $DB_UUID"
echo "DB Internal URL: $DB_INTERNAL_URL"
La respuesta devuelve:
uuid — UUID del contenedor de la BD (se usa como hostname en la red Docker)internal_db_url — Connection string para usar dentro de Docker (entre contenedores)curl -s -X POST \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
http://192.168.1.10:8000/api/v1/databases/$DB_UUID/start
Esperar ~10 segundos y verificar:
curl -s -H 'Authorization: Bearer <COOLIFY_TOKEN>' \
http://192.168.1.10:8000/api/v1/databases/$DB_UUID \
| python -c "import sys,json; print(json.load(sys.stdin).get('status'))"
Debe mostrar running:healthy.
Si el desarrollador necesita conectarse desde su maquina local:
# Buscar puerto libre para la BD (empezar desde 5433)
curl -s -H 'Authorization: Bearer <COOLIFY_TOKEN>' \
http://192.168.1.10:8000/api/v1/databases \
| python -c "
import sys, json
dbs = json.load(sys.stdin)
puertos = set()
for d in dbs:
pp = d.get('public_port')
if pp:
puertos.add(int(pp))
puerto = 5433
while puerto in puertos:
puerto += 1
print(puerto)
"
# Hacer publica la BD en el puerto encontrado
curl -s -X PATCH \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{"is_public": true, "public_port": PUERTO_BD}' \
http://192.168.1.10:8000/api/v1/databases/$DB_UUID
Guardar ambas URLs:
- Docker (para Coolify envs):
postgresql://nombreapp_user:$PG_PASSWORD@$DB_UUID:5432/nombreapp_db- Externo (para dev local):
postgresql://nombreapp_user:$PG_PASSWORD@192.168.1.10:PUERTO_BD/nombreapp_db
Adaptar al stack que necesite la app. El stack recomendado es Python + FastAPI:
mkdir -p C:\Users\User\repositorio\NOMBRE-APP\backend\routers
mkdir -p C:\Users\User\repositorio\NOMBRE-APP\frontend\css
mkdir -p C:\Users\User\repositorio\NOMBRE-APP\frontend\js
Archivos base minimos:
Procfile:
web: uvicorn backend.main:app --host 0.0.0.0 --port 8000
requirements.txt (en la raiz para Nixpacks):
fastapi>=0.115.0
uvicorn>=0.34.0
psycopg2-binary>=2.9.10
backend/main.py:
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
import os
app = FastAPI(title="NOMBRE-APP")
frontend_dir = os.path.join(os.path.dirname(__file__), "..", "frontend")
app.mount("/static", StaticFiles(directory=frontend_dir), name="static")
@app.get("/")
async def root():
return FileResponse(os.path.join(frontend_dir, "index.html"))
@app.get("/api/health")
async def health():
return {"status": "ok"}
backend/database.py:
import os
import psycopg2
import psycopg2.extras
DATABASE_URL = os.environ.get("DATABASE_URL", "")
def get_conn():
return psycopg2.connect(DATABASE_URL)
def query(sql, params=None):
conn = get_conn()
try:
cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
cur.execute(sql, params)
rows = cur.fetchall()
return [dict(r) for r in rows]
finally:
conn.close()
def query_one(sql, params=None):
rows = query(sql, params)
return rows[0] if rows else None
def execute(sql, params=None):
conn = get_conn()
try:
cur = conn.cursor()
cur.execute(sql, params)
conn.commit()
finally:
conn.close()
frontend/index.html:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NOMBRE-APP</title>
</head>
<body>
<h1>NOMBRE-APP</h1>
<p>Aplicacion funcionando correctamente.</p>
</body>
</html>
Si el stack no es Python/FastAPI, adaptar: Node.js usaria
package.json+Procfile,
Go usariago.mod, etc. Lo importante es que Nixpacks lo detecte.
Recordatorio: Confirmar el proyecto Coolify con el usuario antes de ejecutar.
APP_UUID=$(curl -s -X POST \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"project_uuid": "<COOLIFY_PROJECT>",
"environment_name": "production",
"server_uuid": "p9oujt6wvwz90l3zgzd1vexy",
"type": "private-deploy-key",
"name": "NOMBRE-APP",
"git_repository": "git@bitbucket.org:pampling/NOMBRE-REPO.git",
"git_branch": "main",
"build_pack": "nixpacks",
"base_directory": "/",
"ports_exposes": "8000",
"private_key_uuid": "lay870h6dq9p25wvj4la8otn"
}' \
http://192.168.1.10:8000/api/v1/applications/private-deploy-key \
| python -c "import sys,json; print(json.load(sys.stdin)['uuid'])")
echo "App UUID: $APP_UUID"
# Consultar puertos ocupados en Coolify
curl -s \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
http://192.168.1.10:8000/api/v1/applications \
| python -c "
import sys, json
apps = json.load(sys.stdin)
puertos = set()
for a in apps:
m = a.get('ports_mappings', '') or ''
if m and ':' in m:
puertos.add(int(m.split(':')[0]))
puerto = 3000
while puerto in puertos:
puerto += 1
print(puerto)
"
Asignar el puerto encontrado:
curl -s -X PATCH \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{"ports_mappings": "PUERTO:8000"}' \
http://192.168.1.10:8000/api/v1/applications/$APP_UUID
La app sera accesible en http://192.168.1.10:PUERTO
# DATABASE_URL (usar la URL interna Docker, NO la externa)
curl -s -X POST \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{"key": "DATABASE_URL", "value": "'$DB_INTERNAL_URL'", "is_preview": false}' \
http://192.168.1.10:8000/api/v1/applications/$APP_UUID/envs
Repetir para cada variable adicional que necesite la app (ANTHROPIC_API_KEY, etc.).
Seguir la estructura documentada en: http://192.168.1.10:3001/en/guias/claudemd-proyecto
CLAUDE.md (se commitea — compartido con el equipo)Crear CLAUDE.md en la raiz del repo. No incluir secrets:
# NOMBRE-APP
Descripcion breve de la aplicacion y para que sirve.
## Stack
[Tecnologias usadas: lenguaje, framework, base de datos, etc.]
## Estructura
[Arbol de directorios con archivos clave y descripcion de cada uno]
## Base de datos
- Contenedor: `NOMBRE-APP-postgresql` (UUID: $DB_UUID)
- Base de datos: `nombreapp_db`
- Tablas: [describir tablas principales]
- Acceso: via `backend/database.py` → `query()`, `query_one()`, `execute()`
## Produccion
- URL: http://192.168.1.10:PUERTO
- App UUID (Coolify): $APP_UUID
- DB UUID (Coolify): $DB_UUID
- Puerto: 8000 (interno) → PUERTO (externo)
## Desarrollo local
[Como instalar dependencias y arrancar. Variables necesarias en CLAUDE.local.md]
## Deploy
git push origin main + restart via Coolify API (ver seccion deploy abajo).
> `<COOLIFY_TOKEN>` viene del CLAUDE.md personal de cada desarrollador.
## Convenciones
[Estilo de codigo, naming, ramas, commits — adaptar al proyecto]
CLAUDE.local.md (gitignored — credenciales personales)## Conexion a base de datos
- DATABASE_URL (Docker): postgresql://nombreapp_user:PASSWORD@DB_UUID:5432/nombreapp_db
- DATABASE_URL (dev local): postgresql://nombreapp_user:PASSWORD@192.168.1.10:PUERTO_BD/nombreapp_db
.gitignoreCLAUDE.local.md
cd C:\Users\User\repositorio\NOMBRE-APP
git init
git remote add origin git@bitbucket.org:pampling/NOMBRE-REPO.git
git add .
git commit -m "Initial commit — NOMBRE-APP scaffold"
git push -u origin main
Deploy:
curl -s -X POST \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
-d '{}' \
http://192.168.1.10:8000/api/v1/applications/$APP_UUID/restart
Verificar (~90 segundos):
curl -s \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
http://192.168.1.10:8000/api/v1/applications/$APP_UUID \
| python -c "import sys,json; print(json.load(sys.stdin).get('status'))"
Status running = OK. exited:unhealthy = revisar logs.
Mostrar al usuario un resumen con todo lo creado:
=== NOMBRE-APP creada con exito ===
Repositorio: git@bitbucket.org:pampling/NOMBRE-REPO.git
Proyecto: <nombre del proyecto Coolify>
App UUID: $APP_UUID
URL: http://192.168.1.10:PUERTO
Base de datos:
Contenedor: NOMBRE-APP-postgresql
DB UUID: $DB_UUID
DB name: nombreapp_db
DB user: nombreapp_user
URL Docker: postgresql://...@$DB_UUID:5432/nombreapp_db
URL local: postgresql://...@192.168.1.10:PUERTO_BD/nombreapp_db
Ficheros generados:
CLAUDE.md → Info del proyecto (commiteado)
CLAUDE.local.md → Credenciales locales (gitignored)
.gitignore → Incluye CLAUDE.local.md
Si la app ya existe y solo necesitas desplegar cambios:
# 1. Push
git push origin main
# 2. Deploy
curl -s -X POST \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
-d '{}' \
http://192.168.1.10:8000/api/v1/applications/<APP_UUID>/restart
# 3. Verificar (~90s)
curl -s \
-H 'Authorization: Bearer <COOLIFY_TOKEN>' \
http://192.168.1.10:8000/api/v1/applications/<APP_UUID> \
| python -c "import sys,json; print(json.load(sys.stdin).get('status'))"
| Accion | Metodo | URL |
|---|---|---|
| Listar apps | GET | /api/v1/applications |
| Detalle app | GET | /api/v1/applications/ |
| Actualizar app | PATCH | /api/v1/applications/ |
| Listar env vars | GET | /api/v1/applications/{uuid}/envs |
| Anadir env var | POST | /api/v1/applications/{uuid}/envs |
| Borrar env var | DELETE | /api/v1/applications/{uuid}/envs/ |
| Deploy/restart | POST | /api/v1/applications/{uuid}/restart |
| Logs app | GET | /api/v1/applications/{uuid}/logs |
| Accion | Metodo | URL |
|---|---|---|
| Listar DBs | GET | /api/v1/databases |
| Crear PostgreSQL | POST | /api/v1/databases/postgresql |
| Detalle DB | GET | /api/v1/databases/ |
| Actualizar DB | PATCH | /api/v1/databases/ |
| Arrancar DB | POST | /api/v1/databases/{uuid}/start |
| Parar DB | POST | /api/v1/databases/{uuid}/stop |
| Borrar DB | DELETE | /api/v1/databases/ |
| Accion | Metodo | URL |
|---|---|---|
| Listar proyectos | GET | /api/v1/projects |
| Crear proyecto | POST | /api/v1/projects |
| Deploy keys | GET | /api/v1/security/keys |
| Detalle key | GET | /api/v1/security/keys/ |
Base URL: http://192.168.1.10:8000
Header: Authorization: Bearer <COOLIFY_TOKEN>
| Fichero | Descripción | Descargar |
|---|---|---|
CLAUDE.md |
Plantilla con auto-setup | Ver plantilla |
create_app.md |
Este fichero — workflow | Arriba |
settings.json |
Permisos de Claude Code | Ver en Setup |
Volver a: Setup automático · Home