docs: add Coolify documentation with apps list, add sync-vault script

This commit is contained in:
Tiago Ribeiro 2026-02-21 16:43:58 -03:00
parent 9a768f3816
commit 1cb2db4b54
4 changed files with 240 additions and 0 deletions

View file

@ -0,0 +1,70 @@
# Coolify - Redbull (PaaS)
**Arquivo:** `~/.ssh/coolify-redbull-token`
| Propriedade | Valor |
|-------------|-------|
| URL | https://redbull.rede5.com.br |
| API | https://redbull.rede5.com.br/api/v1 |
| Token | Ver arquivo |
| Server IP | 185.194.141.70 |
## Status
✅ API funcionando
## Aplicações
| Nome | UUID |
|------|------|
| gohorsejobs-backend-dev | `iw4sow8s0kkg4cccsk08gsoo` |
| gohorsejobs-frontend-dev | `ao8g40scws0w4cgo8coc8o40` |
| gohorsejobs-backoffice-dev | `hg48wkw4wggwsswcwc8sooo4` |
| gohorsejobs-seeder-dev | `q4w48gos8cgssso00o8w8gck` |
| obramarket-backend-dev | `ws08owk8ocog0gswg8ogo8c4` |
| q1food-backend-dev | `eosgwscc4g044c884k0ws4gc` |
| q1food-frontend-dev | `g8w440g0w0oowo8skss440wk` |
## Comandos API
```bash
TOKEN=$(cat ~/.ssh/coolify-redbull-token)
URL="https://redbull.rede5.com.br/api/v1"
# Listar aplicações
curl -s -H "Authorization: Bearer $TOKEN" "$URL/applications"
# Listar databases
curl -s -H "Authorization: Bearer $TOKEN" "$URL/databases"
# Listar serviços
curl -s -H "Authorization: Bearer $TOKEN" "$URL/services"
# Deploy aplicação
curl -s -H "Authorization: Bearer $TOKEN" "$URL/deploy?uuid=<APP_UUID>"
# Obter detalhes
curl -s -H "Authorization: Bearer $TOKEN" "$URL/applications/<UUID>"
# Atualizar domínio
curl -s -X PATCH -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"$URL/applications/<UUID>" \
-d '{"domains":"https://novo.dominio.com","instant_deploy":true}'
```
## Acesso SSH
```bash
ssh redbull
# ou
ssh -i ~/.ssh/civo root@185.194.141.70
```
## Console Web
https://redbull.rede5.com.br
---
*Atualizado em: 2026-02-21*

View file

@ -53,6 +53,7 @@
| Forgejo | ✅ OK | API apenas | | Forgejo | ✅ OK | API apenas |
| MXRoute | ✅ OK | Email API | | MXRoute | ✅ OK | Email API |
| Cloudflare | ✅ OK | DNS/Proxy API | | Cloudflare | ✅ OK | DNS/Proxy API |
| Coolify | ✅ OK | PaaS API |
| Azure DevOps | ❌ FAIL | Registrar ic-ad.pub | | Azure DevOps | ❌ FAIL | Registrar ic-ad.pub |
| OCI CLI | ✅ OK | Conectado | | OCI CLI | ✅ OK | Conectado |

37
scripts/README.md Normal file
View file

@ -0,0 +1,37 @@
# Scripts de Utilidade
## sync-vault.js
Sincroniza credenciais SSH entre local e Object Storages (Civo e Euronodes).
### Uso
```bash
# Listar arquivos nos buckets
node scripts/sync-vault.js list
# Upload local -> cloud
node scripts/sync-vault.js upload
# Download cloud -> local
node scripts/sync-vault.js download
```
### Requisitos
```bash
npm install aws-sdk
```
### Variáveis de ambiente (opcional)
```bash
export CIVO_ACCESS_KEY="xxx"
export CIVO_SECRET_KEY="xxx"
export EURONODES_ACCESS_KEY="xxx"
export EURONODES_SECRET_KEY="xxx"
```
---
*Atualizado em: 2026-02-21*

132
scripts/sync-vault.js Normal file
View file

@ -0,0 +1,132 @@
const AWS = require('aws-sdk');
const fs = require('fs');
const path = require('path');
const sshPath = process.env.USERPROFILE || process.env.HOME + '/.ssh';
const vaultPath = path.join(sshPath, 'vault');
const civo = new AWS.S3({
endpoint: 'https://objectstore.nyc1.civo.com',
accessKeyId: process.env.CIVO_ACCESS_KEY || '0UZ69TH03Q292DMTB82B',
secretAccessKey: process.env.CIVO_SECRET_KEY || 'JJ5XXZYvoWdnqBCNP5oREjACyrXeH6EgSqeSybT7',
s3ForcePathStyle: true,
signatureVersion: 'v4'
});
const euronodes = new AWS.S3({
endpoint: 'https://eu-west-1.euronodes.com',
accessKeyId: process.env.EURONODES_ACCESS_KEY || 'XZNFA56V35MUY605XOUL',
secretAccessKey: process.env.EURONODES_SECRET_KEY || 'FYATWkgSafaEMRQlFNdSQ6BoCSxG74MY9Cd7D8AF',
s3ForcePathStyle: true,
signatureVersion: 'v4'
});
async function listObjects(s3, bucket, prefix) {
return new Promise((resolve, reject) => {
s3.listObjectsV2({ Bucket: bucket, Prefix: prefix }, (err, data) => {
if (err) reject(err);
else resolve(data.Contents || []);
});
});
}
async function uploadFile(s3, bucket, key, body) {
return new Promise((resolve, reject) => {
s3.putObject({ Bucket: bucket, Key: key, Body: body }, (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
}
async function downloadFile(s3, bucket, key) {
return new Promise((resolve, reject) => {
s3.getObject({ Bucket: bucket, Key: key }, (err, data) => {
if (err) reject(err);
else resolve(data.Body);
});
});
}
async function syncToCloud() {
console.log('=== Sincronizando ~/.ssh/vault/ para Object Storages ===\n');
if (!fs.existsSync(vaultPath)) {
fs.mkdirSync(vaultPath, { recursive: true });
}
const files = fs.readdirSync(vaultPath);
console.log(`Encontrados ${files.length} arquivos locais\n`);
for (const file of files) {
const filePath = path.join(vaultPath, file);
const key = `ssh/${file}`;
const body = fs.readFileSync(filePath);
try {
await uploadFile(civo, 'rede5', `vault/${key}`, body);
console.log(`[CIVO] ✅ ${key}`);
} catch (err) {
console.log(`[CIVO] ❌ ${key}: ${err.message}`);
}
try {
await uploadFile(euronodes, 'vault', key, body);
console.log(`[EURONODES] ✅ ${key}`);
} catch (err) {
console.log(`[EURONODES] ❌ ${key}: ${err.message}`);
}
}
}
async function syncFromCloud() {
console.log('=== Sincronizando Object Storages para ~/.ssh/vault/ ===\n');
if (!fs.existsSync(vaultPath)) {
fs.mkdirSync(vaultPath, { recursive: true });
}
const civoFiles = await listObjects(civo, 'rede5', 'vault/ssh/');
console.log(`Civo: ${civoFiles.length} arquivos`);
for (const obj of civoFiles) {
const key = obj.Key.replace('vault/', '');
const filePath = path.join(vaultPath, path.basename(key));
try {
const body = await downloadFile(civo, 'rede5', obj.Key);
fs.writeFileSync(filePath, body);
console.log(`[DOWNLOAD] ✅ ${key}`);
} catch (err) {
console.log(`[DOWNLOAD] ❌ ${key}: ${err.message}`);
}
}
}
async function listCloud() {
console.log('=== Listando arquivos nos Object Storages ===\n');
const civoFiles = await listObjects(civo, 'rede5', 'vault/ssh/');
console.log(`Civo (rede5/vault/ssh/): ${civoFiles.length} arquivos`);
civoFiles.forEach(f => console.log(` ${f.Key}`));
console.log('');
const euronodesFiles = await listObjects(euronodes, 'vault', 'ssh/');
console.log(`Euronodes (vault/ssh/): ${euronodesFiles.length} arquivos`);
euronodesFiles.forEach(f => console.log(` ${f.Key}`));
}
const action = process.argv[2] || 'list';
switch (action) {
case 'upload':
syncToCloud();
break;
case 'download':
syncFromCloud();
break;
case 'list':
default:
listCloud();
}