{"id":14108867,"url":"https://github.com/eexit/ghost-storage-cloudinary","last_synced_at":"2025-04-03T03:11:24.472Z","repository":{"id":30701658,"uuid":"125415211","full_name":"eexit/ghost-storage-cloudinary","owner":"eexit","description":":rocket: A fully-featured and deeply tested Cloudinary Ghost storage adapter","archived":false,"fork":false,"pushed_at":"2023-12-07T13:34:20.000Z","size":1117,"stargazers_count":83,"open_issues_count":4,"forks_count":21,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-24T16:24:28.963Z","etag":null,"topics":["cloudinary","es6","ghost","ghost-blog","ghost-storage-adapter","nodejs","nodejs-modules","plugins","retina-support","retinajs"],"latest_commit_sha":null,"homepage":"https://ghost.org/integrations/cloudinary/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eexit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-15T19:15:22.000Z","updated_at":"2024-06-19T05:14:55.189Z","dependencies_parsed_at":"2023-12-06T17:29:58.994Z","dependency_job_id":"7c7ba034-9242-4796-8775-e6b0111ccafd","html_url":"https://github.com/eexit/ghost-storage-cloudinary","commit_stats":{"total_commits":299,"total_committers":17,"mean_commits":17.58823529411765,"dds":0.7290969899665551,"last_synced_commit":"ac68fcf15e3c9f3dd0d4d1cb7738a095bac4d407"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eexit%2Fghost-storage-cloudinary","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eexit%2Fghost-storage-cloudinary/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eexit%2Fghost-storage-cloudinary/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eexit%2Fghost-storage-cloudinary/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eexit","download_url":"https://codeload.github.com/eexit/ghost-storage-cloudinary/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246927839,"owners_count":20856198,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudinary","es6","ghost","ghost-blog","ghost-storage-adapter","nodejs","nodejs-modules","plugins","retina-support","retinajs"],"created_at":"2024-08-14T10:01:52.308Z","updated_at":"2025-04-03T03:11:24.446Z","avatar_url":"https://github.com/eexit.png","language":"JavaScript","readme":"# Ghost Storage Cloudinary\n\n[![npm version](https://badge.fury.io/js/ghost-storage-cloudinary.svg)](https://badge.fury.io/js/ghost-storage-cloudinary)\n[![Test](https://github.com/eexit/ghost-storage-cloudinary/actions/workflows/test.yml/badge.svg)](https://github.com/eexit/ghost-storage-cloudinary/actions/workflows/test.yml)\n[![Maintainability](https://api.codeclimate.com/v1/badges/f55e8c82a9a526fe9b2f/maintainability)](https://codeclimate.com/github/eexit/ghost-storage-cloudinary/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/f55e8c82a9a526fe9b2f/test_coverage)](https://codeclimate.com/github/eexit/ghost-storage-cloudinary/test_coverage)\n\nA fully featured and deeply tested [Cloudinary](https://cloudinary.com/) [Ghost](https://github.com/TryGhost/Ghost) storage adapter.\n\n### Features\n\n- Up to date with latest Ghost versions :rocket:\n- Latest Cloudinary NodeJS [SDK](https://github.com/cloudinary/cloudinary_npm)\n- Image upload, existence check \u0026 deletion (when Ghost will support it)\n- Ability to upload in dated sub-directories (alike first Ghost default Local storage adapter `YYYY/MM`)\n- Ability to upload images into a specific directory\n- Ability to tag images\n- Cool [plugins](plugins)!\n\n## Installation\n\n### Install using yarn\n\n- Go into Ghost root directory\n- Download the adapter:\n\n```bash\nyarn add ghost-storage-cloudinary\nmv node_modules/ghost-storage-cloudinary content/adapters/storage/ghost-storage-cloudinary\n```\n\n- Done, go configure\n\n### Install on Docker\n\nHere's an example of using this adapter with a containerized Ghost:\n\n```Dockerfile\nFROM ghost:5-alpine as cloudinary\nRUN apk add g++ make python3\nRUN su-exec node yarn add ghost-storage-cloudinary\n\nFROM ghost:5-alpine\nCOPY --chown=node:node --from=cloudinary $GHOST_INSTALL/node_modules $GHOST_INSTALL/node_modules\nCOPY --chown=node:node --from=cloudinary $GHOST_INSTALL/node_modules/ghost-storage-cloudinary $GHOST_INSTALL/content/adapters/storage/ghost-storage-cloudinary\n# Here, we use the Ghost CLI to set some pre-defined values.\nRUN set -ex; \\\n    su-exec node ghost config storage.active ghost-storage-cloudinary; \\\n    su-exec node ghost config storage.ghost-storage-cloudinary.upload.use_filename true; \\\n    su-exec node ghost config storage.ghost-storage-cloudinary.upload.unique_filename false; \\\n    su-exec node ghost config storage.ghost-storage-cloudinary.upload.overwrite false; \\\n    su-exec node ghost config storage.ghost-storage-cloudinary.fetch.quality auto; \\\n    su-exec node ghost config storage.ghost-storage-cloudinary.fetch.cdn_subdomain true;\n```\n\nMake sure to set the content path right in the Ghost config as well:\n\n```json\n\"paths\": {\n    \"contentPath\": \"/var/lib/ghost/content/\"\n}\n```\n\n## Configuration\n\nCheck out [configuration.json.dist](configuration.json.dist) for a complete example.\n\n- Ensure to disable Ghost [Image Optimisation](https://ghost.org/docs/concepts/config/#image-optimisation)\n- The optional `useDatedFolder = false` to upload images in dated sub-directories (alike default Ghost Local storage adapter)\n- The `auth` property is optional if you use the `CLOUDINARY_URL` environment variable [authentification method](https://cloudinary.com/documentation/node_additional_topics#configuration_options)\n- The optional `upload` property contains Cloudinary API [upload options](https://cloudinary.com/documentation/image_upload_api_reference#upload)\n- The optional `fetch` property contains Cloudinary API [image transformation options](https://cloudinary.com/documentation/image_transformations)\n\n### Recommended configuration\n\n- `upload.use_filename = true` in order use the original image name\n- `upload.unique_filename = false` unlikely Ghost local storage adapter which auto-dedup an existing file name, Cloudinary will return the existing image URL instead of deduping the image\n- `upload.overwrite = false` goes along with previous option: returns existing image instead of overwriting it\n- `upload.folder = \"my-blog\"` allows to upload all your images into a specific directory instead of Cloudinary media library root\n- `upload.tags = [\"blog\", \"photography\"]` if you want to add some taxonomy to your uploaded images\n- `fetch.quality = \"auto\"` equals `auto:good` (see [doc](https://cloudinary.com/documentation/image_transformation_reference#quality_parameter))\n- `fetch.secure = false` set to true if you want to serve images over SSL (not recommended for performances)\n- `fetch.cdn_subdomain = true` to really use the benefit of Cloudinary CDN\n\n:heart: Don't forget to checkout the [plugins](plugins)!\n\n## Development\n\nRun `yarn install` without the `--production` flag.\n\nRuns the tests and generate coverage:\n\n    yarn coverage\n\nRuns the linter:\n\n    yarn eslint\n\nTo enable debug logs, set the following environment variable:\n\n    DEBUG=ghost-storage-cloudinary:*\n\nIntegration testing:\n\n```bash\ndocker build \\\n    --build-arg CLOUDINARY_URL=cloudinary://.... \\\n    --file Dockerfile.test \\\n    --tag test \\\n    .\ndocker run -itp 2368:2368 test\n```\n\nGo to \u003chttp://localhost:2368\u003e.\n\n---\n\nMany thanks to @[mmornati](https://github.com/mmornati), @[sethbrasile](https://github.com/sethbrasile) and all other contributors for their work. In the continuation of this project, don't hesitate to fork, contribute and add more features.\n","funding_links":[],"categories":["Tools","JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feexit%2Fghost-storage-cloudinary","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feexit%2Fghost-storage-cloudinary","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feexit%2Fghost-storage-cloudinary/lists"}