{
  "nodes": [
    {
      "id": "6b1865a7-f150-4d2b-b1f7-37c68b2173d6",
      "name": "Fetch Manifest Digest",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        920,
        -300
      ],
      "parameters": {
        "url": "{{ $env.BASE_URL }}",
        "options": {
          "fullResponse": true
        },
        "authentication": "{{ $credentials.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,
      "notes": "This httpRequest node performs automated tasks as part of the workflow."
    },
    {
      "id": "3c1daca9-3897-4596-b62d-db561f8cb047",
      "name": "Remove Old Tags",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        840,
        -40
      ],
      "parameters": {
        "url": "{{ $env.BASE_URL }}",
        "options": {},
        "requestMethod": "DELETE",
        "authentication": "{{ $credentials.genericCredentialType }}",
        "genericAuthType": "httpBasicAuth",
        "headerParametersUi": {
          "parameter": [
            {
              "name": "Accept",
              "value": "application/vnd.docker.distribution.manifest.v2+json"
            }
          ]
        }
      },
      "typeVersion": 2,
      "notes": "This httpRequest node performs automated tasks as part of the workflow."
    },
    {
      "id": "6974749e-8c85-4334-a7e7-e964f057ed6f",
      "name": "Retrieve Image Tags",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        400,
        -300
      ],
      "parameters": {
        "url": "{{ $env.BASE_URL }}",
        "options": {},
        "authentication": "{{ $credentials.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,
      "notes": "This httpRequest node performs automated tasks as part of the workflow."
    },
    {
      "id": "30857c32-508e-4f95-8e26-c9f2fc84e074",
      "name": "List Images",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        40,
        -300
      ],
      "parameters": {
        "url": "{{ $env.BASE_URL }}",
        "options": {},
        "authentication": "{{ $credentials.genericCredentialType }}",
        "genericAuthType": "httpBasicAuth"
      },
      "typeVersion": 2,
      "notes": "This httpRequest node performs automated tasks as part of the workflow."
    },
    {
      "id": "c5965a6a-28e6-4217-a846-a849de153430",
      "name": "Extract Image Names",
      "type": "n8n-nodes-base.code",
      "position": [
        220,
        -300
      ],
      "parameters": {
        "jsCode": "const images = items[0].json.repositories;\nreturn images.map(image => ({ json: { image } }));"
      },
      "typeVersion": 2,
      "notes": "This code node performs automated tasks as part of the workflow."
    },
    {
      "id": "b13eb6e5-1a16-4992-b0bd-9b228559fecf",
      "name": "Identify Tags to Remove",
      "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,
      "notes": "This code node performs automated tasks as part of the workflow."
    },
    {
      "id": "da15ae49-09ee-4658-86a5-9b0a2180c637",
      "name": "Scheduled Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -140,
        -300
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 1
            }
          ]
        }
      },
      "typeVersion": 1.2,
      "notes": "This scheduleTrigger node performs automated tasks as part of the workflow."
    },
    {
      "id": "bcc347be-5520-46c0-aac9-0b14ddd8b184",
      "name": "Send Notification Email",
      "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,
      "notes": "This emailSend node performs automated tasks as part of the workflow."
    },
    {
      "id": "2c3770ef-cb4c-4007-8897-f4eb7ad3b7cf",
      "name": "Split Tags",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        580,
        -300
      ],
      "parameters": {
        "include": "selectedOtherFields",
        "options": {
          "destinationFieldName": "tag"
        },
        "fieldToSplitOut": "tags",
        "fieldsToInclude": "name"
      },
      "typeVersion": 1,
      "notes": "This splitOut node performs automated tasks as part of the workflow."
    },
    {
      "id": "4fffa947-02cf-4608-acab-8284250cf622",
      "name": "Filter Valid Tags",
      "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,
      "notes": "This filter node performs automated tasks as part of the workflow."
    },
    {
      "id": "c023ba14-d12d-497c-9b30-97db04a34c1b",
      "name": "Fetch Manifest Digest for Blob",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -120,
        -40
      ],
      "parameters": {
        "url": "{{ $env.BASE_URL }}",
        "options": {
          "fullResponse": false
        },
        "authentication": "{{ $credentials.genericCredentialType }}",
        "genericAuthType": "httpBasicAuth",
        "headerParametersUi": {
          "parameter": [
            {
              "name": "Accept",
              "value": "application/vnd.docker.distribution.manifest.v2+json"
            }
          ]
        }
      },
      "typeVersion": 2,
      "notes": "This httpRequest node performs automated tasks as part of the workflow."
    },
    {
      "id": "f054b91e-abd4-4854-9bfa-e4a2b70f7e2c",
      "name": "Update Fields",
      "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,
      "notes": "This set node performs automated tasks as part of the workflow."
    },
    {
      "id": "54405505-8445-491a-8f5d-232da8c842d2",
      "name": "Group Tags by Image",
      "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,
      "notes": "This code node performs automated tasks as part of the workflow."
    },
    {
      "id": "980aab86-44cd-47d5-b3b7-42cbae26eb09",
      "name": "Sort by Creation Date",
      "type": "n8n-nodes-base.sort",
      "position": [
        240,
        -40
      ],
      "parameters": {
        "options": {},
        "sortFieldsUi": {
          "sortField": [
            {
              "order": "descending",
              "fieldName": "created"
            }
          ]
        }
      },
      "typeVersion": 1,
      "notes": "This sort node performs automated tasks as part of the workflow."
    },
    {
      "id": "0561efb9-4903-4bec-bc1a-8131e5f5de67",
      "name": "Send Failure Notification Email",
      "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,
      "notes": "This emailSend node performs automated tasks as part of the workflow."
    },
    {
      "id": "eaa28914-351c-4934-ba1c-0d39faf67ef3",
      "name": "Execute Garbage Collection",
      "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": "{{ $credentials.privateKey }}"
      },
      "typeVersion": 1,
      "notes": "This ssh node performs automated tasks as part of the workflow."
    }
  ],
  "pinData": {},
  "connections": {
    "6b1865a7-f150-4d2b-b1f7-37c68b2173d6": {
      "main": [
        [
          {
            "node": "error-handler-6b1865a7-f150-4d2b-b1f7-37c68b2173d6",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-6b1865a7-f150-4d2b-b1f7-37c68b2173d6-ae271a8d",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-6b1865a7-f150-4d2b-b1f7-37c68b2173d6-927b6779",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-6b1865a7-f150-4d2b-b1f7-37c68b2173d6-914d1414",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-6b1865a7-f150-4d2b-b1f7-37c68b2173d6-3603a5a9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3c1daca9-3897-4596-b62d-db561f8cb047": {
      "main": [
        [
          {
            "node": "error-handler-3c1daca9-3897-4596-b62d-db561f8cb047",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-3c1daca9-3897-4596-b62d-db561f8cb047-1cbbf61e",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-3c1daca9-3897-4596-b62d-db561f8cb047-9630ffbc",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-3c1daca9-3897-4596-b62d-db561f8cb047-9c9e04f1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-3c1daca9-3897-4596-b62d-db561f8cb047-1f2e1d14",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6974749e-8c85-4334-a7e7-e964f057ed6f": {
      "main": [
        [
          {
            "node": "error-handler-6974749e-8c85-4334-a7e7-e964f057ed6f",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-6974749e-8c85-4334-a7e7-e964f057ed6f-4f885bce",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-6974749e-8c85-4334-a7e7-e964f057ed6f-42bf65f7",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-6974749e-8c85-4334-a7e7-e964f057ed6f-8c4f98b9",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-6974749e-8c85-4334-a7e7-e964f057ed6f-69c25a59",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "30857c32-508e-4f95-8e26-c9f2fc84e074": {
      "main": [
        [
          {
            "node": "error-handler-30857c32-508e-4f95-8e26-c9f2fc84e074",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-30857c32-508e-4f95-8e26-c9f2fc84e074-ea99463b",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-30857c32-508e-4f95-8e26-c9f2fc84e074-c5b24aea",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-30857c32-508e-4f95-8e26-c9f2fc84e074-c2e94e93",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-30857c32-508e-4f95-8e26-c9f2fc84e074-bdf1258c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c023ba14-d12d-497c-9b30-97db04a34c1b": {
      "main": [
        [
          {
            "node": "error-handler-c023ba14-d12d-497c-9b30-97db04a34c1b",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-c023ba14-d12d-497c-9b30-97db04a34c1b-56c5de0f",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-c023ba14-d12d-497c-9b30-97db04a34c1b-ca6a4dd6",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-c023ba14-d12d-497c-9b30-97db04a34c1b-4c500945",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-c023ba14-d12d-497c-9b30-97db04a34c1b-c76cd2ab",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bcc347be-5520-46c0-aac9-0b14ddd8b184": {
      "main": [
        [
          {
            "node": "error-handler-bcc347be-5520-46c0-aac9-0b14ddd8b184-845df439",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-bcc347be-5520-46c0-aac9-0b14ddd8b184-7896573f",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-bcc347be-5520-46c0-aac9-0b14ddd8b184-a8b08510",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-bcc347be-5520-46c0-aac9-0b14ddd8b184-2b7e53d0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0561efb9-4903-4bec-bc1a-8131e5f5de67": {
      "main": [
        [
          {
            "node": "error-handler-0561efb9-4903-4bec-bc1a-8131e5f5de67-eb4eb2d8",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-0561efb9-4903-4bec-bc1a-8131e5f5de67-b1855ca4",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-0561efb9-4903-4bec-bc1a-8131e5f5de67-86d97a0d",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error-handler-0561efb9-4903-4bec-bc1a-8131e5f5de67-aa27f130",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "name": "Httprequest Workflow",
  "description": "Automated workflow: Httprequest Workflow. This workflow processes data and performs automated tasks.",
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": true,
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": null,
    "timezone": "UTC",
    "executionTimeout": 3600,
    "maxExecutions": 1000,
    "retryOnFail": true,
    "retryCount": 3,
    "retryDelay": 1000
  },
  "meta": {
    "instanceId": "workflow-47cebf0e",
    "versionId": "1.0.0",
    "createdAt": "2025-09-29T07:07:53.090637",
    "updatedAt": "2025-09-29T07:07:53.090653",
    "owner": "n8n-user",
    "license": "MIT",
    "category": "automation",
    "status": "active",
    "priority": "high",
    "environment": "production"
  },
  "tags": [
    "automation",
    "n8n",
    "production-ready",
    "excellent",
    "optimized"
  ],
  "notes": "Excellent quality workflow: Httprequest Workflow. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."
}