Flujo de trabajo para limpieza del registro de Docker
Este es unEngineering, DevOps, IT Opsflujo de automatización del dominio deautomatización que contiene 16 nodos.Utiliza principalmente nodos como Set, Ssh, Code, Sort, Filter. Flujo de trabajo de limpieza del registro de Docker
- •Pueden requerirse credenciales de autenticación para la API de destino
Nodos utilizados (16)
Categoría
{
"nodes": [
{
"id": "6b1865a7-f150-4d2b-b1f7-37c68b2173d6",
"name": "Obtener resumen del manifiesto",
"type": "n8n-nodes-base.httpRequest",
"position": [
920,
-300
],
"parameters": {
"url": "={{\"https://<<your-registry-url>>/v2/\" + $json.name + \"/manifests/\" + $json.tag}}",
"options": {
"fullResponse": true
},
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"headerParametersUi": {
"parameter": [
{
"name": "Accept",
"value": "application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json"
}
]
}
},
"typeVersion": 2
},
{
"id": "3c1daca9-3897-4596-b62d-db561f8cb047",
"name": "Eliminar etiquetas antiguas",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
840,
-40
],
"parameters": {
"url": "={{\"https://<<your-registry-url>>/v2/\" + $json.image + \"/manifests/\" + $json.tag.digest}}",
"options": {},
"requestMethod": "DELETE",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"headerParametersUi": {
"parameter": [
{
"name": "Accept",
"value": "application/vnd.docker.distribution.manifest.v2+json"
}
]
}
},
"typeVersion": 2
},
{
"id": "6974749e-8c85-4334-a7e7-e964f057ed6f",
"name": "Recuperar etiquetas de imagen",
"type": "n8n-nodes-base.httpRequest",
"position": [
400,
-300
],
"parameters": {
"url": "={{\"https://<<your-registry-url>>/v2/\" + $json[\"image\"] + \"/tags/list\"}}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"headerParametersUi": {
"parameter": [
{
"name": "Accept",
"value": "application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json"
}
]
}
},
"typeVersion": 2
},
{
"id": "30857c32-508e-4f95-8e26-c9f2fc84e074",
"name": "Listar imágenes",
"type": "n8n-nodes-base.httpRequest",
"position": [
40,
-300
],
"parameters": {
"url": "https://<<your-registry-url>>/v2/_catalog",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth"
},
"typeVersion": 2
},
{
"id": "c5965a6a-28e6-4217-a846-a849de153430",
"name": "Extraer nombres de imagen",
"type": "n8n-nodes-base.code",
"position": [
220,
-300
],
"parameters": {
"jsCode": "const images = items[0].json.repositories;\nreturn images.map(image => ({ json: { image } }));"
},
"typeVersion": 2
},
{
"id": "b13eb6e5-1a16-4992-b0bd-9b228559fecf",
"name": "Identificar etiquetas a eliminar",
"type": "n8n-nodes-base.code",
"position": [
600,
-40
],
"parameters": {
"jsCode": "const result = [];\n\nfor (const item of items) {\n const tags = item.json.tags;\n if (tags) {\n const latestTag = tags.includes('latest') ? 'latest' : null;\n const sortedTags = tags.filter(tag => tag !== 'latest')\n .sort((a, b) => new Date(b.created) - new Date(a.created));\n const keepTags = sortedTags.slice(0, 10);\n if (latestTag) keepTags.push('latest');\n const deleteTags = sortedTags.slice(10);\n result.push(...deleteTags.map(tag => ({ json: { image: item.json.name, tag } })));\n }\n}\n\nreturn result;\n"
},
"typeVersion": 2
},
{
"id": "da15ae49-09ee-4658-86a5-9b0a2180c637",
"name": "Activador programado",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-140,
-300
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 1
}
]
}
},
"typeVersion": 1.2
},
{
"id": "bcc347be-5520-46c0-aac9-0b14ddd8b184",
"name": "Enviar correo de notificación",
"type": "n8n-nodes-base.emailSend",
"position": [
840,
180
],
"webhookId": "47f852c3-7136-4e6d-92f6-47322dbba5da",
"parameters": {
"text": "=Image : {{ $json.image }}\nTag : {{ $json.tag.tag }}\n\nRemoved",
"options": {},
"subject": "Docker Registry Cleaner Notification",
"toEmail": "to@example.com",
"fromEmail": "from@example.com",
"emailFormat": "text"
},
"typeVersion": 2.1
},
{
"id": "2c3770ef-cb4c-4007-8897-f4eb7ad3b7cf",
"name": "Dividir etiquetas",
"type": "n8n-nodes-base.splitOut",
"position": [
580,
-300
],
"parameters": {
"include": "selectedOtherFields",
"options": {
"destinationFieldName": "tag"
},
"fieldToSplitOut": "tags",
"fieldsToInclude": "name"
},
"typeVersion": 1
},
{
"id": "4fffa947-02cf-4608-acab-8284250cf622",
"name": "Filtrar etiquetas válidas",
"type": "n8n-nodes-base.filter",
"position": [
740,
-300
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "bb56b84e-e7cb-4867-93f8-ac40c71bde4f",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.tag }}",
"rightValue": ""
},
{
"id": "acd8e00c-5fa0-4c62-ba96-9e6f456f7703",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.name }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "c023ba14-d12d-497c-9b30-97db04a34c1b",
"name": "Obtener resumen del manifiesto para blob",
"type": "n8n-nodes-base.httpRequest",
"position": [
-120,
-40
],
"parameters": {
"url": "={{\"https://<<your-registry-url>>/v2/\" + $('Filter Valid Tags').item.json.name + \"/blobs/\" + $json.body.config.digest}}",
"options": {
"fullResponse": false
},
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"headerParametersUi": {
"parameter": [
{
"name": "Accept",
"value": "application/vnd.docker.distribution.manifest.v2+json"
}
]
}
},
"typeVersion": 2
},
{
"id": "f054b91e-abd4-4854-9bfa-e4a2b70f7e2c",
"name": "Actualizar campos",
"type": "n8n-nodes-base.set",
"position": [
60,
-40
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c970bdb8-ddbf-486b-a716-c66274a248a7",
"name": "name",
"type": "string",
"value": "={{ $('Filter Valid Tags').item.json.name }}"
},
{
"id": "7ce79761-6557-413c-a9a6-5d1ca564a3df",
"name": "tag",
"type": "string",
"value": "={{ $('Filter Valid Tags').item.json.tag }}"
},
{
"id": "45948a25-d35c-4e3f-9556-3d52a1a89f80",
"name": "created",
"type": "string",
"value": "={{ $json.created }}"
},
{
"id": "c73a14ad-91f6-477f-b4c3-037db319b9ee",
"name": "digest",
"type": "string",
"value": "={{ $('Fetch Manifest Digest').item.json.headers['docker-content-digest'] }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "54405505-8445-491a-8f5d-232da8c842d2",
"name": "Agrupar etiquetas por imagen",
"type": "n8n-nodes-base.code",
"position": [
420,
-40
],
"parameters": {
"jsCode": "const groupedData = items.reduce((acc, item) => {\n const name = item.json.name;\n if (!acc[name]) {\n acc[name] = [];\n }\n acc[name].push({\n tag: item.json.tag,\n created: item.json.created,\n digest: item.json.digest\n });\n return acc;\n}, {});\n\nreturn Object.keys(groupedData).map(name => ({\n json: { name, tags: groupedData[name] }\n}));\n"
},
"typeVersion": 2
},
{
"id": "980aab86-44cd-47d5-b3b7-42cbae26eb09",
"name": "Ordenar por fecha de creación",
"type": "n8n-nodes-base.sort",
"position": [
240,
-40
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"order": "descending",
"fieldName": "created"
}
]
}
},
"typeVersion": 1
},
{
"id": "0561efb9-4903-4bec-bc1a-8131e5f5de67",
"name": "Enviar correo de notificación de fallo",
"type": "n8n-nodes-base.emailSend",
"position": [
1120,
80
],
"webhookId": "47f852c3-7136-4e6d-92f6-47322dbba5da",
"parameters": {
"text": "=Image : {{ $json.image }}\nTag : {{ $json.tag.tag }}\n\nFailed",
"options": {},
"subject": "[FAIL] Docker Registry Cleaner Notification",
"toEmail": "to@example.com",
"fromEmail": "from@example.com",
"emailFormat": "text"
},
"typeVersion": 2.1
},
{
"id": "eaa28914-351c-4934-ba1c-0d39faf67ef3",
"name": "Ejecutar recolección de basura",
"type": "n8n-nodes-base.ssh",
"position": [
1120,
-100
],
"parameters": {
"cwd": "/opt/services/",
"command": "docker compose exec -it -u root registry bin/registry garbage-collect --delete-untagged /etc/docker/registry/config.yml",
"authentication": "privateKey"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"2c3770ef-cb4c-4007-8897-f4eb7ad3b7cf": {
"main": [
[
{
"node": "4fffa947-02cf-4608-acab-8284250cf622",
"type": "main",
"index": 0
}
]
]
},
"30857c32-508e-4f95-8e26-c9f2fc84e074": {
"main": [
[
{
"node": "c5965a6a-28e6-4217-a846-a849de153430",
"type": "main",
"index": 0
}
]
]
},
"f054b91e-abd4-4854-9bfa-e4a2b70f7e2c": {
"main": [
[
{
"node": "980aab86-44cd-47d5-b3b7-42cbae26eb09",
"type": "main",
"index": 0
}
]
]
},
"3c1daca9-3897-4596-b62d-db561f8cb047": {
"main": [
[
{
"node": "eaa28914-351c-4934-ba1c-0d39faf67ef3",
"type": "main",
"index": 0
}
],
[
{
"node": "0561efb9-4903-4bec-bc1a-8131e5f5de67",
"type": "main",
"index": 0
}
]
]
},
"4fffa947-02cf-4608-acab-8284250cf622": {
"main": [
[
{
"node": "6b1865a7-f150-4d2b-b1f7-37c68b2173d6",
"type": "main",
"index": 0
}
]
]
},
"da15ae49-09ee-4658-86a5-9b0a2180c637": {
"main": [
[
{
"node": "30857c32-508e-4f95-8e26-c9f2fc84e074",
"type": "main",
"index": 0
}
]
]
},
"c5965a6a-28e6-4217-a846-a849de153430": {
"main": [
[
{
"node": "6974749e-8c85-4334-a7e7-e964f057ed6f",
"type": "main",
"index": 0
}
]
]
},
"54405505-8445-491a-8f5d-232da8c842d2": {
"main": [
[
{
"node": "b13eb6e5-1a16-4992-b0bd-9b228559fecf",
"type": "main",
"index": 0
}
]
]
},
"6974749e-8c85-4334-a7e7-e964f057ed6f": {
"main": [
[
{
"node": "2c3770ef-cb4c-4007-8897-f4eb7ad3b7cf",
"type": "main",
"index": 0
}
]
]
},
"6b1865a7-f150-4d2b-b1f7-37c68b2173d6": {
"main": [
[
{
"node": "c023ba14-d12d-497c-9b30-97db04a34c1b",
"type": "main",
"index": 0
}
]
]
},
"980aab86-44cd-47d5-b3b7-42cbae26eb09": {
"main": [
[
{
"node": "54405505-8445-491a-8f5d-232da8c842d2",
"type": "main",
"index": 0
}
]
]
},
"b13eb6e5-1a16-4992-b0bd-9b228559fecf": {
"main": [
[
{
"node": "3c1daca9-3897-4596-b62d-db561f8cb047",
"type": "main",
"index": 0
},
{
"node": "bcc347be-5520-46c0-aac9-0b14ddd8b184",
"type": "main",
"index": 0
}
]
]
},
"c023ba14-d12d-497c-9b30-97db04a34c1b": {
"main": [
[
{
"node": "f054b91e-abd4-4854-9bfa-e4a2b70f7e2c",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Avanzado - Ingeniería, DevOps, Operaciones de TI
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Muzaffer AKYIL
@victoriousCompartir este flujo de trabajo