Giter VIP home page Giter VIP logo

ghost-storage-adapter-s3's People

Contributors

amd-nick avatar ashald avatar bluehatbrit avatar chrisdlangton avatar christianreed avatar colinmeinke avatar eofs avatar etanb avatar gerardvivancos avatar iamakulov avatar matitalatina avatar mightyscollins avatar seanhayes avatar vstabile avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ghost-storage-adapter-s3's Issues

Presigned URLs

How to generate presigned URLs when files are uploaded?

ERROR: Cannot find module '../../../core/server/storage/base'

Hey guys.
Attempting to get this module up and running inside of a docker container.

I have a reasonable amount of experience with Docker and have had a lot of luck getting a full ghost environment up and running locally (and also setup with a full ci pipeline for production).

I am running based off of the official ghost:0.11.3 image which works flawlessly without the module added. I did a fresh NPM install of the module when I created the Dockerfile to build the container. Here's the config:

Debian Jessie
Ghost v0.11.3
Node v4.7.2
NPM v2.15.11
ghost-storage-adapter-s3 v1.2.0

That being the case, my latest attempt to integrate the ghost-storage-adapter-s3 has failed with the following error:

ERROR: Cannot find module '../../../core/server/storage/base'
ghost |
ghost | IncorrectUsage: Cannot find module '../../../core/server/storage/base'
ghost | at Error.IncorrectUsage (/usr/src/ghost/core/server/errors/incorrect-usage.js:3:18)
ghost | at Object.getStorage (/usr/src/ghost/core/server/storage/index.js:36:19)
ghost | at setupMiddleware (/usr/src/ghost/core/server/middleware/index.js:126:44)

I shelled a new terminal inside of the container and verified that the /usr/src/ghost/node_modules/ghost-storage-adapter-s3/
DOES exist.

Then I shifted over to check to make sure that my copy functionality properly copied the contents also into: /usr/src/ghost/content/storage/s3
ALSO Exists and all contents appear to be in the folder.

After verifying the above, I added / installed vim inside of the container in an effort to inspect the source of the error (which now existed in two places since the above mentioned copy).

Since was in /usr/src/ghost/content/storage/s3 I figured I would mess with that one first. I found the following line:
var _base = require('../../../core/server/storage/base');

And changed it to the absolute path:
var _base = require('/usr/src/ghost/core/server/storage/base');

Then I cd'd over to /usr/src/ghost/node_modules/ghost-storage-adapter-s3/ to edit index.js over there. Code was the same so I replaced the line exactly as mentioned above.

Next I exited the container and did a docker ps, no container running.
Did a docker run to bring the container back up and it booted back up properly.

Still trying to figure out WHY it happened, if I knew I would fix it and submit a PR but figured I would bring it to your attention incase its happening to others. For now I am going to patch my Dockerfile to copy an alternate version of the index.js file overtop of the one causing the problems to quiet it down on myside (until I know for sure that its happening to everyone and not just docker peeps).

Prepending of blog url to assethost.

I don't think this is necessarily an issue with your plugin but I figured I'd check if you had experience with it. I am using cloud front in front of S3 for my image hosting. The images are uploading fine but in the actually ghost story it's prepending the url of my blog to the assethost url.

For example say the asset host URL is "xxxxx.cloudfront.net/2018/01/image.png" for a particular image and my ghost instance is blog.fakedomain.com in the actual article it's requesting the link like so:

https://blog.fakedomain.com/articletitle/xxxxx.cloudfront.net/2018/01/image.png

Has anyone else experienced this?

I'm building from ghost 1.20.2

Any and all help is appreciated!

About the installation

I think the original command in the installation cp -r ./node_modules/ghost-storage-adapter-s3 ./content/storage/s3 should change to cp -r ./node_modules/ghost-storage-adapter-s3/index.js ./content/storage/s3

Ghost 2.x + Storage Adapter not using CDN URL?

Hey guys,
So this one is weird, and a non-standard use case.
I am hoping I am missing something simple here as I have more than a few hours into this (after previously quickly running through and adding S3 storage adapter on earlier ghost versions).

I had previously been running a ghost 0.11.x install with S3 storage adapter baked in to the docker file (essentially just added as you normally would to the base Alpine image (https://hub.docker.com/_/ghost/).

I am in the process of rebuilding that setup on Ghost 2.x (2.7.1 to be specific).
I basically thought I had everything working again with 2.x — everything except for Ghost S3 Storage Adapter. I know that this one could be docker related but I figured I would post here in case someone else runs into the issue.

Problem 1

My first problem was that for whatever reason my docker based ghost Container always seems to be looking in the following directory:
/var/lib/ghost/versions/2.7.1/core/server/adapters/storage/s3

That's obviously different from the directory discussed in the docs (see: https://github.com/colinmeinke/ghost-storage-adapter-s3#installation) or in the blog mentioned in some of the other Ghost 2.x threads (https://it.ismy.fun/2018/08/26/ghost-custom-storage-module/) all of which indicate that the storage module should be copied into:
/var/lib/ghost/content/adapters/storage/s3

I couldn't get Ghost to look in that location no matter what I did — so instead I just copied my S3 storage adapter director into the alternate directory: /var/lib/ghost/versions/2.7.1/core/server/adapters/storage/s3

That worked. No more adapter not found — and I can see my images (which I bulk uploaded to S3 previously). The images are not available locally in any of the content directories.

Problem 2

The next issue is that I can't (for whatever reason) upload a new image to S3. When uploading a new image from the editor I see the image visually in the editor for a split second before the editor shows an error like:

screen shot 2018-12-18 at 4 03 13 pm

In my console (keep in mind the container name is printed here) I get:

ghost-s3-os       | ERROR [2018-12-18 20:46:16] "POST /ghost/api/v2/admin/uploads/" 403 2023ms
ghost-s3-os       | 
ghost-s3-os       | NAME: InternalServerError
ghost-s3-os       | CODE: AccessDenied
ghost-s3-os       | MESSAGE: Access Denied
ghost-s3-os       | 
ghost-s3-os       | level:normal
ghost-s3-os       | 
ghost-s3-os       | empty
ghost-s3-os       | empty
ghost-s3-os       | ERROR DETAILS:
ghost-s3-os       |     empty
ghost-s3-os       | 
ghost-s3-os       | InternalServerError: Access Denied
ghost-s3-os       |     at new GhostError (/var/lib/ghost/versions/2.7.1/core/server/lib/common/errors.js:10:26)
ghost-s3-os       |     at _private.prepareError (/var/lib/ghost/versions/2.7.1/core/server/web/shared/middlewares/error-handler.js:42:19)
ghost-s3-os       |     at Layer.handle_error (/var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/layer.js:71:5)
ghost-s3-os       |     at trim_prefix (/var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/index.js:315:13)
ghost-s3-os       |     at /var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/index.js:284:7
ghost-s3-os       |     at Function.process_params (/var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/index.js:335:12)
ghost-s3-os       |     at next (/var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/index.js:275:10)
ghost-s3-os       |     at Layer.handle_error (/var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/layer.js:67:12)
ghost-s3-os       |     at trim_prefix (/var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/index.js:315:13)
ghost-s3-os       |     at /var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/index.js:284:7
ghost-s3-os       |     at Function.process_params (/var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/index.js:335:12)
ghost-s3-os       |     at next (/var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/index.js:275:10)
ghost-s3-os       |     at /var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/index.js:635:15
ghost-s3-os       |     at next (/var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/index.js:260:14)
ghost-s3-os       |     at next (/var/lib/ghost/versions/2.7.1/node_modules/express/lib/router/route.js:127:14)
ghost-s3-os       |     at apiImpl.then.catch (/var/lib/ghost/versions/2.7.1/core/server/api/shared/http.js:59:17)
ghost-s3-os       | 
ghost-s3-os       | AccessDenied: Access Denied
ghost-s3-os       |     at Request.extractError (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/services/s3.js:283:35)
ghost-s3-os       |     at Request.callListeners (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/sequential_executor.js:103:18)
ghost-s3-os       |     at Request.callListeners (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/sequential_executor.js:104:14)
ghost-s3-os       |     at Request.emit (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
ghost-s3-os       |     at Request.emit (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/request.js:584:14)
ghost-s3-os       |     at Request.transition (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/request.js:16:12)
ghost-s3-os       |     at AcceptorStateMachine.runTo (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/state_machine.js:14:12)
ghost-s3-os       |     at /var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/state_machine.js:26:10
ghost-s3-os       |     at Request.<anonymous> (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/request.js:22:9)
ghost-s3-os       |     at Request.<anonymous> (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/request.js:586:12)
ghost-s3-os       |     at Request.callListeners (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/sequential_executor.js:87:20)
ghost-s3-os       |     at Request.callListeners (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/sequential_executor.js:104:14)
ghost-s3-os       |     at Request.emit (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
ghost-s3-os       |     at Request.emit (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/request.js:584:14)
ghost-s3-os       |     at Request.transition (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/request.js:16:12)
ghost-s3-os       |     at AcceptorStateMachine.runTo (/var/lib/ghost/versions/2.7.1/node_modules/aws-sdk/lib/state_machine.js:14:12)

Basically that seems (to me) to indicate that AWS for whatever reason is not able to upload the images (possibly due to IAM permissions). That isn't the case since I can execute the cp command to manually utilize the same Key / Secret to do the upload from within the container, for example:

aws s3 cp file.txt s3://some-bucket/

Problem 3 (the weirdest one)

The last problem is that it appears that S3 is in fact working properly, my images are available, but when I inspect the site — the images are loading from the container (which DOES NOT have the images stored anywhere inside).

The reason I know there are no images in the container is because a bulk find from within the contianer shows nothing except theme images:

$ find / -name "*jpg" 

/var/lib/ghost/versions/2.7.1/content/themes/casper/assets/screenshot-desktop.jpg
/var/lib/ghost/versions/2.7.1/content/themes/casper/assets/screenshot-mobile.jpg
/var/lib/ghost/versions/2.7.1/core/built/assets/img/themes/nurui-146ba228f415aa6dc073911c5eedd524.jpg
/var/lib/ghost/versions/2.7.1/core/built/assets/img/themes/farafra-800f5fbb100aaefbefe42e8f79fa3391.jpg
/var/lib/ghost/versions/2.7.1/core/built/assets/img/themes/valkyrie-3ce1c51ff5a8fb77494a97ee192f199a.jpg
/var/lib/ghost/versions/2.7.1/core/built/assets/img/themes/sente-3c2bd8202c626b11048c3bc6bddc250a.jpg
/var/lib/ghost/versions/2.7.1/core/built/assets/img/themes/massively-06edf00108429f7fb8e65f190fba34fe.jpg
/var/lib/ghost/versions/2.7.1/core/built/assets/img/themes/pacific-182fa717198992c893b4afd7b1dd1096.jpg
/home/node/.cache/yarn/v2/npm-browserify-zlib-0.1.4-bb35f8a519f600e0fa6b8485241c979d0141fb2d/test/fixtures/person.jpg

So basically the net result appears to be that the Ghost install is some how grabbing images from S3 — but then serving them as if they are local (ie. from the standard /content/whatever.jpg URL, rather than the CDN / cloudfront URL specified in my config). How that could be happening I have NO idea.

(Bonus) Problem 4

Last issue — probably related to the above — is that some images that are in S3 (manually uploaded) apparently are not accessible on S3 (which would indicate that yes S3 can be connected to). Specifically I get a single error (where this file DOES exist in S3):

ghost-s3-os       | [2018-12-18 20:41:26] ERROR
ghost-s3-os       | 
ghost-s3-os       | NAME: InternalServerError
ghost-s3-os       | CODE: IMAGE_SIZE_STORAGE
ghost-s3-os       | MESSAGE: /2018/11/Original-Skateboards-Logo-175.png is not stored in s3
ghost-s3-os       | 
ghost-s3-os       | level:critical
ghost-s3-os       | 
ghost-s3-os       | "/2018/11/Original-Skateboards-Logo-175.png"
ghost-s3-os       | empty
ghost-s3-os       | ERROR DETAILS:
ghost-s3-os       |     {"originalPath":"http://dev.originalskateboards.com/content/images/2018/11/Original-Skateboards-Logo-175.png","reqFilePath":"/2018/11/Original-Skateboards-Logo-175.png"}
ghost-s3-os       | 
ghost-s3-os       | InternalServerError: /2018/11/Original-Skateboards-Logo-175.png is not stored in s3
ghost-s3-os       |     at new InternalServerError (/var/lib/ghost/versions/2.7.1/node_modules/ghost-ignition/lib/errors/index.js:71:23)
ghost-s3-os       |     at storage.getStorage.read.then.catch.catch (/var/lib/ghost/versions/2.7.1/core/server/lib/image/image-size.js:214:35)
ghost-s3-os       |     at tryCatcher (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/util.js:16:23)
ghost-s3-os       |     at Promise._settlePromiseFromHandler (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/promise.js:512:31)
ghost-s3-os       |     at Promise._settlePromise (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/promise.js:569:18)
ghost-s3-os       |     at Promise._settlePromise0 (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/promise.js:614:10)
ghost-s3-os       |     at Promise._settlePromises (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/promise.js:690:18)
ghost-s3-os       |     at _drainQueueStep (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/async.js:138:12)
ghost-s3-os       |     at _drainQueue (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/async.js:131:9)
ghost-s3-os       |     at Async._drainQueues (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/async.js:147:5)
ghost-s3-os       |     at Immediate.Async.drainQueues (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/async.js:17:14)
ghost-s3-os       |     at runCallback (timers.js:810:20)
ghost-s3-os       |     at tryOnImmediate (timers.js:768:5)
ghost-s3-os       |     at processImmediate [as _immediateCallback] (timers.js:745:5)
ghost-s3-os       | 
ghost-s3-os       | Error: /2018/11/Original-Skateboards-Logo-175.png is not stored in s3
ghost-s3-os       |     at /var/lib/ghost/versions/2.7.1/core/server/adapters/storage/s3/index.js:174:16
ghost-s3-os       |     at Promise._execute (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/debuggability.js:313:9)
ghost-s3-os       |     at Promise._resolveFromExecutor (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/promise.js:483:18)
ghost-s3-os       |     at new Promise (/var/lib/ghost/versions/2.7.1/node_modules/bluebird/js/release/promise.js:79:10)
ghost-s3-os       |     at Store.read (/var/lib/ghost/versions/2.7.1/core/server/adapters/storage/s3/index.js:168:12)
ghost-s3-os       |     at getImageSizeFromStoragePath (/var/lib/ghost/versions/2.7.1/core/server/lib/image/image-size.js:188:10)
ghost-s3-os       |     at Object.getImageSizeFromUrl (/var/lib/ghost/versions/2.7.1/core/server/lib/image/image-size.js:88:16)
ghost-s3-os       |     at Object.getCachedImageSizeFromUrl (/var/lib/ghost/versions/2.7.1/core/server/lib/image/cached-image-size-from-url.js:21:26)
ghost-s3-os       |     at getImageDimensions (/var/lib/ghost/versions/2.7.1/core/server/data/meta/image-dimensions.js:17:24)
ghost-s3-os       |     at getMetaData (/var/lib/ghost/versions/2.7.1/core/server/data/meta/index.js:97:26)
ghost-s3-os       |     at Object.ghost_head (/var/lib/ghost/versions/2.7.1/core/server/helpers/ghost_head.js:124:12)
ghost-s3-os       |     at Object.returnAsync (/var/lib/ghost/versions/2.7.1/core/server/helpers/register.js:16:28)
ghost-s3-os       |     at Function.Waiter.resolve (/var/lib/ghost/versions/2.7.1/node_modules/express-hbs/lib/async.js:83:3)
ghost-s3-os       |     at Object.<anonymous> (/var/lib/ghost/versions/2.7.1/node_modules/express-hbs/lib/hbs.js:396:18)
ghost-s3-os       |     at Object.eval [as main] (eval at createFunctionContext (/var/lib/ghost/versions/2.7.1/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js:254:23), <anonymous>:22:166)
ghost-s3-os       |     at main (/var/lib/ghost/versions/2.7.1/node_modules/handlebars/dist/cjs/handlebars/runtime.js:173:32)

Config File

For reference my config file looks like:

{
    "server": {
        "host": "0.0.0.0",
        "port": 2368
    },
    "process": "local",
    "paths": {
        "contentPath": "content/"
    },
    "storage": {
        "active": "s3",
        "s3": {
            "accessKeyId": "KEYHERE",
            "secretAccessKey": "SECRETHERE",
            "assetHost": "https://somecloudfronturl.cloudfront.net",
            "region": "us-east-1",
            "bucket": "some-bucket",
            "forcePathStyle": true
        }
    },
}

I can properly access the host in my browser (and as mentioned) I can even see the images — which do not exist locally. The weirdness is that those images appear to be HOSTED locally some how — and I can't upload anything.

Here's hoping you guys might have some ideas!
If you made it this far — Thanks in advance.

Files not being uploaded to S3

Even though all the config were correct and the s3 folder was there in the content/adapters/storage, files weren't uploaded to S3, instead were uploaded to local.

Add a proxy feature for images uploaded before installation of the adapter

When the adapter is installed it works flawlessly for newly uploaded images but, of course, it does not work for pre-existing ones.

These are usually linked using relative URLs. Because of this, by using the serve() method, they can be served from S3 by proxying them from the bucket, provided they are copied there, without needing to edit every link on previously published posts.

We've got a PR ready for this.

IMAGE_SIZE_URL statusCode 403

Hi everyone,
Seems like I am doing something wrong. But can't figure it out. Getting error below when I try to start Ghost (if adapter enabled).
Any help appreciated!

Environment:

  • AWS ECS (Amazon Linux 2)
  • Instance IAM Role has S3 Full Access
  • Bucket exists (but empty)

Config:
"storage": { "active": "s3", "s3": { "bucket: "my-bucket", "pathPrefix": "test" }

Error:
{ "name": "Log", "hostname": "ip-10-192-50-105.ec2.internal", "pid": 15984, "level": 50, "err": { "id": "f5418a30-e640-11ea-bb9f-155e217295a3", "domain": "https://MY_DOMAIN.org", "code": "IMAGE_SIZE_URL", "name": "InternalServerError", "statusCode": 403, "level": "critical", "message": "Unknown Request error.", "context": "\"https://static.ghost.org/v3.0.0/images/publication-cover.png\"", "stack": "InternalServerError: Unknown Request error.\n at new InternalServerError (/var/www/ghost/versions/3.31.1/node_modules/ghost-ignition/lib/errors/index.js:90:23)\n at /var/www/ghost/versions/3.31.1/core/server/lib/image/image-size.js:176:31\n at tryCatcher (/var/www/ghost/versions/3.31.1/node_modules/bluebird/js/release/util.js:16:23)\n at Promise._settlePromiseFromHandler (/var/www/ghost/versions/3.31.1/node_modules/bluebird/js/release/promise.js:547:31)\n at Promise._settlePromise (/var/www/ghost/versions/3.31.1/node_modules/bluebird/js/release/promise.js:604:18)\n at Promise._settlePromise0 (/var/www/ghost/versions/3.31.1/node_modules/bluebird/js/release/promise.js:649:10)\n at Promise._settlePromises (/var/www/ghost/versions/3.31.1/node_modules/bluebird/js/release/promise.js:725:18)\n at _drainQueueStep (/var/www/ghost/versions/3.31.1/node_modules/bluebird/js/release/async.js:93:12)\n at _drainQueue (/var/www/ghost/versions/3.31.1/node_modules/bluebird/js/release/async.js:86:9)\n at Async._drainQueues (/var/www/ghost/versions/3.31.1/node_modules/bluebird/js/release/async.js:102:5)\n at Immediate.Async.drainQueues [as _onImmediate] (/var/www/ghost/versions/3.31.1/node_modules/bluebird/js/release/async.js:15:14)\n at processImmediate (internal/timers.js:456:21)\n\nProbeError: bad status code: 403\n at Request.<anonymous> (/var/www/ghost/versions/3.31.1/node_modules/probe-image-size/http.js:46:19)\n at Request.emit (events.js:315:20)\n at Request.EventEmitter.emit (domain.js:483:12)\n at Request.onRequestResponse (/var/www/ghost/versions/3.31.1/node_modules/request/request.js:1059:10)\n at ClientRequest.emit (events.js:315:20)\n at ClientRequest.EventEmitter.emit (domain.js:483:12)\n at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:596:27)\n at HTTPParser.parserOnHeadersComplete (_http_common.js:119:17)\n at TLSSocket.socketOnData (_http_client.js:469:22)\n at TLSSocket.emit (events.js:315:20)\n at TLSSocket.EventEmitter.emit (domain.js:483:12)\n at addChunk (_stream_readable.js:295:12)\n at readableAddChunk (_stream_readable.js:271:9)\n at TLSSocket.Readable.push (_stream_readable.js:212:10)\n at TLSWrap.onStreamRead (internal/stream_base_commons.js:186:23)" }, "msg": "Unknown Request error.", "time": "2020-08-24T19:35:25.524Z", "v": 0 }

Ghost 5 Dockerfile

I found out it works with ghost 5, but we have to upgrade packages aws-sdk and ghost-storage-base

FROM ghost:5.2.4-alpine AS ghost-base

RUN npm install --prefix /tmp/ghost-storage-adapter-s3 ghost-storage-adapter-s3 && \
    cp -r /tmp/ghost-storage-adapter-s3/node_modules/ghost-storage-adapter-s3 current/core/server/adapters/storage/s3 && \
    rm -r /tmp/ghost-storage-adapter-s3

RUN npm install ghost-storage-base && npm install aws-sdk

Allow IAM Roles

It would be nice if we could create and IAM Role and attach it to the Ghost server. I tried this and got an InternalServerError: Access Denied

Ghost 0.11.10 deleting picture

Hello. i have the adapter installed and configured. when i upload an image from the editor and file uploads to the bucket successfully, however, when i delete it, it doesn't get deleted from the bucket. is there a way to delete it automatically ? the delete function is there

Asset Host not working

I am attempting to use assetHost to point to my cloudfront url : cloud.myDomain.com

I have tried the following URLs without luck:

cloud.myDomain.com

&

https://cloud.myDomain.com

Is there something wrong with that option?

ERROR: We cannot find your adapter in

Hey Colin,

Getting this error when starting ghost :

npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm info prestart [email protected]
npm info start [email protected]

> [email protected] start /usr/src/ghost
> node index


ERROR: We cannot find your adpter in: /var/lib/ghost/storage/ or: /usr/src/ghost/core/server/storage/

 Error
    at Error.IncorrectUsage (/usr/src/ghost/core/server/errors/incorrect-usage.js:3:18)
    at Object.getStorage (/usr/src/ghost/core/server/storage/index.js:45:19)
    at setupMiddleware (/usr/src/ghost/core/server/middleware/index.js:126:44)
    at /usr/src/ghost/core/server/index.js:188:9
    at tryCatcher (/usr/src/ghost/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/usr/src/ghost/node_modules/bluebird/js/release/promise.js:510:31)
    at Promise._settlePromise (/usr/src/ghost/node_modules/bluebird/js/release/promise.js:567:18)
    at Promise._settlePromise0 (/usr/src/ghost/node_modules/bluebird/js/release/promise.js:612:10)
    at Promise._settlePromises (/usr/src/ghost/node_modules/bluebird/js/release/promise.js:691:18)
    at Promise._fulfill (/usr/src/ghost/node_modules/bluebird/js/release/promise.js:636:18)
    at PromiseArray._resolve (/usr/src/ghost/node_modules/bluebird/js/release/promise_array.js:125:19)
    at PromiseArray._promiseFulfilled (/usr/src/ghost/node_modules/bluebird/js/release/promise_array.js:143:14)
    at Promise._settlePromise (/usr/src/ghost/node_modules/bluebird/js/release/promise.js:572:26)
    at Promise._settlePromise0 (/usr/src/ghost/node_modules/bluebird/js/release/promise.js:612:10)
    at Promise._settlePromises (/usr/src/ghost/node_modules/bluebird/js/release/promise.js:691:18)
    at Async._drainQueue (/usr/src/ghost/node_modules/bluebird/js/release/async.js:138:16)

npm info poststart [email protected]
npm info ok

Observation 1

About:

ERROR: We cannot find your adpter in: /var/lib/ghost/storage/ or: /usr/src/ghost/core/server/storage/

It's weird that the error's path is /var/lib/ghost/storage and NOT /var/lib/ghost/content/storage

Observation 2

I see errors related to bluebird. Could it be possible we need to fix this?

This is how my directories look like:

root@c6adb074c8d1:/usr/src/ghost# ls -lh
total 292K
-rw-r--r--  1 root root    0 Dec 19 18:22 DIRgst2-base-0.11.2-colinmeinke_BYPascal-Andy_2016-12-19_18h22_51-5H.txt
-rw-r--r--  1 root root  32K Oct 11 12:40 Gruntfile.js
-rw-r--r--  1 root root 1.1K Oct 11 12:40 LICENSE
-rw-r--r--  1 root root 2.9K Oct 11 12:40 PRIVACY.md
-rw-r--r--  1 root root 4.6K Oct 11 12:40 README.md
-rw-r--r--  1 root root 4.5K Oct 11 12:40 config.example.js
drwxr-xr-x  7 root root 4.0K Dec 19 18:23 content
drwxr-xr-x  5 root root 4.0K Oct 11 12:51 core
-rw-r--r--  1 root root  725 Oct 11 12:40 index.js
drwxr-xr-x 93 root root 4.0K Dec 19 18:22 node_modules
-rw-r--r--  1 root root 164K Oct 11 12:51 npm-shrinkwrap.json
-rw-r--r--  1 root root 3.0K Oct 11 12:40 package.json
-rw-r--r--  1 root root  52K Dec 19 18:24 tree.txt

root@c6adb074c8d1:/usr/src/ghost/content/storage# ls
s3

root@c6adb074c8d1:/usr/src/ghost/content/storage/s3# ls -lh
total 36K
-rw-r--r-- 1 root root 3.2K Dec 19 18:23 CODE_OF_CONDUCT.md
-rw-r--r-- 1 root root 2.4K Dec 19 18:23 CONTRIBUTING.md
-rw-r--r-- 1 root root  808 Dec 19 18:23 LICENSE.md
-rw-r--r-- 1 root root  579 Dec 19 18:23 README.md
-rw-r--r-- 1 root root 6.2K Dec 19 18:23 index.js
drwxr-xr-x 3 root root 4.0K Dec 19 18:23 node_modules
-rw-r--r-- 1 root root 2.5K Dec 19 18:23 package.json
drwxr-xr-x 2 root root 4.0K Dec 19 18:23 src

Observation 3

The index.js file is not the same as what I see from https://github.com/colinmeinke/ghost-storage-adapter-s3/blob/master/src/index.js

root@c6adb074c8d1:/usr/src/ghost/content/storage/s3# cat index.js
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _awsSdk = require('aws-sdk');

var _awsSdk2 = _interopRequireDefault(_awsSdk);

var _base = require('../../../core/server/storage/base');

var _base2 = _interopRequireDefault(_base);

var _path = require('path');

var _bluebird = require('bluebird');

var _bluebird2 = _interopRequireDefault(_bluebird);

var _fs = require('fs');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var readFileAsync = (0, _bluebird.promisify)(_fs.readFile);

var stripLeadingSlash = function stripLeadingSlash(s) {
  return s.indexOf('/') === 0 ? s.substring(1) : s;
};

var Store = function (_BaseStore) {
  _inherits(Store, _BaseStore);

  function Store() {
    var config = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

    _classCallCheck(this, Store);

    var _this = _possibleConstructorReturn(this, (Store.__proto__ || Object.getPrototypeOf(Store)).call(this, config));

    _awsSdk2.default.config.setPromisesDependency(_bluebird2.default);

    var accessKeyId = config.accessKeyId;
    var assetHost = config.assetHost;
    var bucket = config.bucket;
    var region = config.region;
    var secretAccessKey = config.secretAccessKey;
    var pathPrefix = config.pathPrefix;


    _this.accessKeyId = accessKeyId;
    _this.bucket = bucket;
    _this.host = assetHost ? assetHost : 'https://s3' + (region === 'us-east-1' ? '' : '-' + region) + '.amazonaws.com/' + bucket;
    _this.region = region;
    _this.secretAccessKey = secretAccessKey;
    _this.pathPrefix = stripLeadingSlash(pathPrefix || '');
    return _this;
  }

  _createClass(Store, [{
    key: 'delete',
    value: function _delete(fileName, targetDir) {
      var _this2 = this;

      var directory = targetDir || this.getTargetDir(this.pathPrefix);

      return new _bluebird2.default(function (resolve, reject) {
        return _this2.s3().deleteObject({
          Bucket: _this2.bucket,
          Key: stripLeadingSlash((0, _path.join)(directory, fileName))
        }).promise().then(function () {
          return resolve(true);
        }).catch(function () {
          return resolve(false);
        });
      });
    }
  }, {
    key: 'exists',
    value: function exists(fileName) {
      var _this3 = this;

      return new _bluebird2.default(function (resolve, reject) {
        return _this3.s3().getObject({
          Bucket: _this3.bucket,
          Key: stripLeadingSlash(fileName)
        }).promise().then(function () {
          return resolve(true);
        }).catch(function () {
          return resolve(false);
        });
      });
    }
  }, {
    key: 's3',
    value: function s3() {
      return new _awsSdk2.default.S3({
        accessKeyId: this.accessKeyId,
        bucket: this.bucket,
        region: this.region,
        secretAccessKey: this.secretAccessKey
      });
    }
  }, {
    key: 'save',
    value: function save(image, targetDir) {
      var _this4 = this;

      var directory = targetDir || this.getTargetDir(this.pathPrefix);

      return new _bluebird2.default(function (resolve, reject) {
        _bluebird2.default.all([_this4.getUniqueFileName(_this4, image, directory), readFileAsync(image.path)]).then(function (_ref) {
          var _ref2 = _slicedToArray(_ref, 2);

          var fileName = _ref2[0];
          var file = _ref2[1];
          return _this4.s3().putObject({
            ACL: 'public-read',
            Body: file,
            Bucket: _this4.bucket,
            CacheControl: 'max-age=' + 30 * 24 * 60 * 60,
            ContentType: image.type,
            Key: stripLeadingSlash(fileName)
          }).promise().then(function () {
            return resolve(_this4.host + '/' + fileName);
          });
        }).catch(function (error) {
          return reject(error);
        });
      });
    }
  }, {
    key: 'serve',
    value: function serve() {
      return function (req, res, next) {
        next();
      };
    }
  }]);

  return Store;
}(_base2.default);

exports.default = Store;
module.exports = exports['default'];

Observation 4

In other Ghost adaptors projects like this one they require to:

Create a file called `index.js` (./content/storage/index.js) and insert the following code

'use strict';
module.exports = require('ghost-storage-adapter-s3'); 

I guess it's not need here but I'm just trying to find leads about why Ghost is complaining.

Thanks in advance!
twitter.com/_pascalandy

'We have detected an error in your custom storage adapter.'

I can't seem to my storage adapter working. Whenever I run 'ghost start' I get an error message saying there's an error in my custom storage adapter.

ghost-start

This is my config:
(I have already tried several things like adding or removing signatureVersion and pathPrefix)

config

log

Does anyone know what the problem could be? (I'm using a Digital Ocean droplet for my ghost instance.)

I also already tried to run 'npm install' agian, like @yuhr123 mentioned in another topic, but that didn't work for me.

Using adapter with a bucket that is private

I am unable to view the images when connecting to a private bucket. The image gets saved in the bucket just fine, but when viewed in browser I can only see the broken image icon. Copying the image path into the browser I get the following error:

InvalidArgument
Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.

Do you have any knowledge on how to get this working if the bucket isn't made public?

anyone using this on docker alpine?

I'm having some issues when trying to install this on docker alpine, any tips?

ghost_1  | [2019-03-26 03:16:33] ERROR
ghost_1  |
ghost_1  | We detected a misuse. Please read the stack trace.
ghost_1  |
ghost_1  | "We cannot find your adapter in: /var/lib/ghost/content/adapters/storage/ or: /var/lib/ghost/versions/2.18.3/core/server/adapters/stora
ge/"
ghost_1  |
ghost_1  | Error ID:
ghost_1  |     8e6e9310-4f75-11e9-9e4b-a961edf5f3bf
ghost_1  |
ghost_1  | Error Code:
ghost_1  |     MODULE_NOT_FOUND
ghost_1  |
ghost_1  | ----------------------------------------

ghost_1  |
ghost_1  | IncorrectUsageError: We detected a misuse. Please read the stack trace.
ghost_1  |     at new IncorrectUsageError (/var/lib/ghost/versions/2.18.3/node_modules/ghost-ignition/lib/errors/index.js:85:23)

Dockerfile:

FROM ghost:2.18.3-alpine

# Copy Ghost config.json
COPY ghost/config.production.json .

# Install S3 Pkg
RUN npm install ghost-storage-adapter-s3 && \
    mkdir -p /var/lib/ghost/content/adapters/storage/ && \
    cp -r ./node_modules/ghost-storage-adapter-s3 /var/lib/ghost/content/adapters/storage/s3 && \
    cd /var/lib/ghost/content/adapters/storage/s3 && \
    npm install && \
    npm audit fix

Support for AWS4-HMAC-SHA256

Hi,

Firstly thanks for authoring this adapter. Really is great.

When I was deploying this earlier for my blog, I created an S3 Bucket in eu-west-2, which is the London Region. As per https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region, this S3 region only supports the latest Version 4 signature.

When configuring the ghost-storage-adapter-s3 plugin to point to this S3 endpoint, image uploads lead to the following error message: NAME: InternalServerError CODE: InvalidRequest MESSAGE: The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.

Recreating the S3 bucket in the Ireland region, which supports Version 2 makes this error go away. I am unsure if this is a plugin specific issue or related to the AWS-SDK.

Installation instructions did not work in docker container

Example of my Dockerfile:

FROM ghost:alpine

RUN cd current;                                   \
    npm install ghost-storage-adapter-s3;         \
    mkdir -p ./content/adapters/storage;          \
    cp -r ./node_modules/ghost-storage-adapter-s3 \
          ./content/adapters/storage/s3;          \
    rm -f /var/lib/ghost/content/data/ghost.db;   \
    rm -f /var/lib/ghost/configuration.production.json

ENV server__host 0.0.0.0

This Dockerfile works as long as I do not try to activate the s3 storage module.

Stacktrace when I do invoke the s3 storage module:

NAME: IncorrectUsageError
CODE: MODULE_NOT_FOUND
MESSAGE: We detected a misuse. Please read the stack trace.

level:critical

We cannot find your adapter in: /var/lib/ghost/content/adapters/storage/ or: /var/lib/ghost/versions/1.12.1/core/server/adapters/stor
age/
IncorrectUsageError: We detected a misuse. Please read the stack trace.
    at new IncorrectUsageError (/var/lib/ghost/versions/1.12.1/node_modules/ghost-ignition/lib/errors/index.js:79:23)
    at Object.getStorage (/var/lib/ghost/versions/1.12.1/core/server/adapters/storage/index.js:62:19)
    at setupBlogApp (/var/lib/ghost/versions/1.12.1/core/server/blog/app.js:64:66)
    at setupParentApp (/var/lib/ghost/versions/1.12.1/core/server/app.js:54:36)
    at /var/lib/ghost/versions/1.12.1/core/server/index.js:70:37

    at tryCatcher (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:693:18)
    at Promise._fulfill (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:638:18)
    at PromiseArray._resolve (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise_array.js:126:19)
    at PromiseArray._promiseFulfilled (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise_array.js:144:14)
    at Promise._settlePromise (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:574:26)
    at Promise._settlePromise0 (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:672:20)
    at tryOnImmediate (timers.js:645:5)
    at processImmediate [as _immediateCallback] (timers.js:617:5)

Error: Cannot find module '/var/lib/ghost/versions/1.12.1/core/server/adapters/storage/s3'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.getStorage (/var/lib/ghost/versions/1.12.1/core/server/adapters/storage/index.js:59:42)
    at setupBlogApp (/var/lib/ghost/versions/1.12.1/core/server/blog/app.js:64:66)
    at setupParentApp (/var/lib/ghost/versions/1.12.1/core/server/app.js:54:36)

    at /var/lib/ghost/versions/1.12.1/core/server/index.js:70:37
    at tryCatcher (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:693:18)
    at Promise._fulfill (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:638:18)
    at PromiseArray._resolve (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise_array.js:126:19)
    at PromiseArray._promiseFulfilled (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise_array.js:144:14)
    at Promise._settlePromise (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:574:26)
    at Promise._settlePromise0 (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/var/lib/ghost/versions/1.12.1/node_modules/bluebird/js/release/async.js:17:14)

Example Dockerfile that I created that works using S3 storage adapter:

FROM ghost:alpine

RUN cd current;                                   \
    npm install ghost-storage-adapter-s3;         \
    mkdir -p ./content/adapters/storage;          \
    cp -r ./node_modules/ghost-storage-adapter-s3 \
          ./core/server/adapters/storage/s3;          \
    rm -f /var/lib/ghost/content/data/ghost.db;   \
    rm -f /var/lib/ghost/configuration.production.json

ENV server__host 0.0.0.0

I'm positive this is something I am doing wrong so I'd like to get some feedback. I'm not blocked as I got it working.

Thanks

It seems not working on Ghost 2.x

I have tried to config this adapter on Ghost 2.x, but can not start Ghost service if I add "storage" related info into the config.production.json file.

RFE: add support for other file types

Hello @colinmeinke I have been using your storage adapter with my ghost blog for some time now, and it has been working really great in combination with Wasabi.
Recently, Ghost added the (long requested) option to attach files, videos and audio to a post or a page. But the S3 adapter currently only looks for image types.
Hence this request for enhancement:
I think it would be super helpful if your adapter could be expanded to add support for other file types.
Is this something you would consider adding?

Error when deploying to Heroku in production

Getting the following error when deploying on Heroku:

Unhandled rejection TypeError: _awsSdk2.default.config.setPromisesDependency is not a function
2018-01-31T01:45:37.615073+00:00 app[web.1]: at new Store (/app/content/adapters/storage/s3/index.js:39:29)
2018-01-31T01:45:37.615074+00:00 app[web.1]: at Object.getStorage (/app/node_modules/ghost/core/server/adapters/storage/index.js:72:21)
2018-01-31T01:45:37.615076+00:00 app[web.1]: at setupSiteApp (/app/node_modules/ghost/core/server/web/site/app.js:69:73)
2018-01-31T01:45:37.615077+00:00 app[web.1]: at setupParentApp (/app/node_modules/ghost/core/server/web/parent-app.js:54:36)
2018-01-31T01:45:37.615079+00:00 app[web.1]: at /app/node_modules/ghost/core/server/index.js:81:48
2018-01-31T01:45:37.615080+00:00 app[web.1]: at tryCatcher (/app/node_modules/bluebird/js/release/util.js:16:23)
2018-01-31T01:45:37.615084+00:00 app[web.1]: at Promise._settlePromiseFromHandler (/app/node_modules/bluebird/js/release/promise.js:512:31)
2018-01-31T01:45:37.615085+00:00 app[web.1]: at Promise._settlePromise (/app/node_modules/bluebird/js/release/promise.js:569:18)
2018-01-31T01:45:37.615086+00:00 app[web.1]: at Promise._settlePromise0 (/app/node_modules/bluebird/js/release/promise.js:614:10)
2018-01-31T01:45:37.615087+00:00 app[web.1]: at Promise._settlePromises (/app/node_modules/bluebird/js/release/promise.js:693:18)
2018-01-31T01:45:37.615088+00:00 app[web.1]: at Promise._fulfill (/app/node_modules/bluebird/js/release/promise.js:638:18)
2018-01-31T01:45:37.615089+00:00 app[web.1]: at PromiseArray._resolve (/app/node_modules/bluebird/js/release/promise_array.js:126:19)
2018-01-31T01:45:37.615090+00:00 app[web.1]: at PromiseArray._promiseFulfilled (/app/node_modules/bluebird/js/release/promise_array.js:144:14)
2018-01-31T01:45:37.615091+00:00 app[web.1]: at Promise._settlePromise (/app/node_modules/bluebird/js/release/promise.js:574:26)
2018-01-31T01:45:37.615092+00:00 app[web.1]: at Promise._settlePromise0 (/app/node_modules/bluebird/js/release/promise.js:614:10)
2018-01-31T01:45:37.615093+00:00 app[web.1]: at Promise._settlePromises (/app/node_modules/bluebird/js/release/promise.js:693:18)

File structure is:

screen shot 2018-01-30 at 9 12 24 pm

Ghost package is included as a npm module. When running locally with the Amazon s3 configuration, everything works. Only seems to be happening when deploying to Heroku.

Any ideas why this is happening and how to solve it?

S3 Query-string order seems incorrect

Ghost-storage-adapter-s3 is pushing the url "bucket.region.s3.amazonaws.com" to the browser and the images are not returning on the site from s3 properly. When I enter that url format directly into the browser I'm getting an error -code "nosuchbucket" -message "the specified bucket does not exist". It seems like if "s3" and "region" are reversed in the string, the images pull up, however I can't figure out how to update the order of the string on the return. When I use: "bucket-name.s3.region.amazonaws.com" it works. Not fully sure. help.

Access Denied for upload every time.

I can't seem to upload any new images to S3, no matter what permissions I give my IAM user, I always get:

[2020-05-15 22:35:29] ERROR "POST /ghost/api/v3/admin/images/upload/" 403 662ms
Access Denied
Error ID:
    611ac210-96fc-11ea-99f8-d9fdb0d0c7a2
Error Code: 
    AccessDenied
----------------------------------------
InternalServerError: Access Denied
    at new GhostError (/var/lib/ghost/versions/3.15.3/node_modules/@tryghost/errors/lib/errors.js:10:26)
    at _private.prepareError (/var/lib/ghost/versions/3.15.3/core/server/web/shared/middlewares/error-handler.js:53:19)
    at Layer.handle_error (/var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/layer.js:71:5)
    at trim_prefix (/var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/index.js:315:13)
    at /var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/index.js:335:12)
    at next (/var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/index.js:275:10)
    at Layer.handle_error (/var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/layer.js:67:12)
    at trim_prefix (/var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/index.js:315:13)
    at /var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/index.js:335:12)
    at next (/var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/index.js:275:10)
    at /var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/index.js:635:15
    at next (/var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/index.js:260:14)
    at next (/var/lib/ghost/versions/3.15.3/node_modules/express/lib/router/route.js:127:14)
    at /var/lib/ghost/versions/3.15.3/core/server/api/shared/http.js:96:17
    at tryCatcher (/var/lib/ghost/versions/3.15.3/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/var/lib/ghost/versions/3.15.3/node_modules/bluebird/js/release/promise.js:547:31)
    at Promise._settlePromise (/var/lib/ghost/versions/3.15.3/node_modules/bluebird/js/release/promise.js:604:18)
    at Promise._settlePromise0 (/var/lib/ghost/versions/3.15.3/node_modules/bluebird/js/release/promise.js:649:10)
    at Promise._settlePromises (/var/lib/ghost/versions/3.15.3/node_modules/bluebird/js/release/promise.js:725:18)
    at _drainQueueStep (/var/lib/ghost/versions/3.15.3/node_modules/bluebird/js/release/async.js:93:12)
AccessDenied: Access Denied
    at Request.extractError (/var/lib/ghost/node_modules/aws-sdk/lib/services/s3.js:835:35)
    at Request.callListeners (/var/lib/ghost/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/var/lib/ghost/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/var/lib/ghost/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /var/lib/ghost/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/var/lib/ghost/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
    at Request.emit (/var/lib/ghost/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/var/lib/ghost/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /var/lib/ghost/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/var/lib/ghost/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
    at callNextListener (/var/lib/ghost/node_modules/aws-sdk/lib/sequential_executor.js:96:12)
    at IncomingMessage.onEnd (/var/lib/ghost/node_modules/aws-sdk/lib/event_listeners.js:307:13)
    at IncomingMessage.emit (events.js:322:22)
    at IncomingMessage.EventEmitter.emit (domain.js:482:12)
(node:1) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated

Here's my config (without access key).

 "storage": {
    "active": "s3",
    "s3": {
      "accessKeyId": "AKIAW7GJQGVXKTM3ZH6S",
      "secretAccessKey": "REDACTED",
      "region": "us-east-1",
      "bucket": "budgets-global",
      "forcePathStyle": false
    }
  },

Can anyone spot what I'm doing incorrectly?

Cannot Get Past: NAME: IncorrectUsageError

Hi,

I've been attempting to use the ghost-storage-adapter-s3 with my Ghost / Docker implementation and cannot get past the following error:

ghost_1  | NAME: IncorrectUsageError
ghost_1  | CODE: MODULE_NOT_FOUND
ghost_1  | MESSAGE: We have detected an error in your custom storage adapter.
ghost_1  | 
ghost_1  | level:critical
ghost_1  | 
ghost_1  | IncorrectUsageError: We have detected an error in your custom storage adapter.
ghost_1  |     at new IncorrectUsageError (/var/lib/ghost/versions/1.20.3/node_modules/ghost-ignition/lib/errors/index.js:79:23)
ghost_1  |     at Object.getStorage (/var/lib/ghost/versions/1.20.3/core/server/adapters/storage/index.js:42:19)
ghost_1  |     at setupSiteApp (/var/lib/ghost/versions/1.20.3/core/server/web/site/app.js:69:73)
ghost_1  |     at setupParentApp (/var/lib/ghost/versions/1.20.3/core/server/web/parent-app.js:54:36)
ghost_1  |     at /var/lib/ghost/versions/1.20.3/core/server/index.js:81:48
ghost_1  |     at Function.Module._resolveFilename (module.js:469:15)
ghost_1  |     at Function.Module._load (module.js:417:25)
ghost_1  |     at Module.require (module.js:497:17)
ghost_1  |     at require (internal/module.js:20:19)
ghost_1  |     at Object.<anonymous> (/content/adapters/storage/ghost-imgur/index.js:4:19)
ghost_1  |     at Module._compile (module.js:570:32)
ghost_1  |     at Object.Module._extensions..js (module.js:579:10)
ghost_1  |     at Module.load (module.js:487:32)
ghost_1  |     at tryModuleLoad (module.js:446:12)
ghost_1  |     at Function.Module._load (module.js:438:3)
ghost_1  |     at Module.require (module.js:497:17)
ghost_1  |     at require (internal/module.js:20:19)
ghost_1  |     at Object.getStorage (/var/lib/ghost/versions/1.20.3/core/server/adapters/storage/index.js:32:25)
ghost_1  |     at setupSiteApp (/var/lib/ghost/versions/1.20.3/core/server/web/site/app.js:69:73)
ghost_1  |     at setupParentApp (/var/lib/ghost/versions/1.20.3/core/server/web/parent-app.js:54:36)
ghost_1  |     at /var/lib/ghost/versions/1.20.3/core/server/index.js:81:48
ghost_1  | From previous event:
ghost_1  |     at init (/var/lib/ghost/versions/1.20.3/core/server/index.js:77:8)
ghost_1  |     at makeGhost (/var/lib/ghost/versions/1.20.3/core/index.js:11:12)
ghost_1  |     at Object.<anonymous> (/var/lib/ghost/versions/1.20.3/index.js:20:1)
ghost_1  |     at Module._compile (module.js:570:32)
ghost_1  |     at Object.Module._extensions..js (module.js:579:10)
ghost_1  |     at Module.load (module.js:487:32)
ghost_1  |     at tryModuleLoad (module.js:446:12)
ghost_1  |     at Function.Module._load (module.js:438:3)
ghost_1  |     at Module.runMain (module.js:604:10)
ghost_1  |     at run (bootstrap_node.js:383:7)
ghost_1  |     at startup (bootstrap_node.js:149:9)
ghost_1  |     at bootstrap_node.js:496:3

My dockerfile looks as follows:

FROM ghost:1.20.3

# Install build dependencies
RUN apt-get update \
 && apt-get install -y --force-yes --no-install-recommends\
      apt-transport-https \
      ssh-client \
      build-essential \
      curl \
      git \
      python-all \
      rlwrap \
      unzip \
      jq \
  && apt-get upgrade -y --force-yes \
  && rm -rf /var/lib/apt/lists/*;

RUN curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip" \
 && unzip awscli-bundle.zip \
 && ./awscli-bundle/install -b ~/bin/aws \
 && ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
ENV AWS_DEFAULT_REGION us-east-1

# We want to use a non-standard `content/` path for Ghost as the base image 
# mounts the default location as a VOLUME meaning we cannot place our theme or
# s3 adapter into it as part of the dockerfile:
# https://github.com/docker-library/ghost/blob/master/1/debian/Dockerfile#L76
ENV paths__contentPath "/opt/ghost/content"
RUN mkdir -p $paths__contentPath/themes $paths__contentPath/adapters/storage

# Now build our actual source files
COPY PlaidBlog $paths__contentPath/themes/PlaidBlog/
RUN cd $paths__contentPath/themes/PlaidBlog/ && make setup
RUN cd $paths__contentPath/themes/PlaidBlog/ && make clean
RUN cd $paths__contentPath/themes/PlaidBlog/ && make build

# To use s3 as a storage system for static content (such as post images) we
# need to copy the adapter to the proper location in the ghost content path.
RUN mv $paths__contentPath/themes/PlaidBlog/node_modules/ghost-storage-adapter-s3 $paths__contentPath/adapters/storage/s3

COPY start.sh secrets.sh secrets.json ./

# Old ENTRYPOINT behavior mimicked in start.sh
# https://github.com/docker-library/ghost/blob/962323a525d020a49a9165ba62f85098b8e5e09f/1/debian/Dockerfile#L79
ENTRYPOINT []
CMD ["./start.sh"]

Does this work for Ghost 3?

I am getting access denied when connected to S3 and CloudFront

Error ID:
ghost_1 | ba4e8df0-3e9d-11eb-875f-3bf6d4f677d6
ghost_1 |
ghost_1 | Error Code:
ghost_1 | AccessDenied
ghost_1 |
ghost_1 | ----------------------------------------
ghost_1 |
ghost_1 | InternalServerError: Access Denied
ghost_1 | at new GhostError (/var/lib/ghost/versions/3.40.1/node_modules/@tryghost/errors/lib/errors.js:10:26)
ghost_1 | at _private.prepareError (/var/lib/ghost/versions/3.40.1/core/server/web/shared/middlewares/error-handler.js:53:19)
ghost_1 | at Layer.handle_error (/var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/layer.js:71:5)
ghost_1 | at trim_prefix (/var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/index.js:315:13)
ghost_1 | at /var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/index.js:284:7
ghost_1 | at Function.process_params (/var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/index.js:335:12)
ghost_1 | at next (/var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/index.js:275:10)
ghost_1 | at Layer.handle_error (/var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/layer.js:67:12)
ghost_1 | at trim_prefix (/var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/index.js:315:13)
ghost_1 | at /var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/index.js:284:7
ghost_1 | at Function.process_params (/var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/index.js:335:12)
ghost_1 | at next (/var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/index.js:275:10)
ghost_1 | at /var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/index.js:635:15
ghost_1 | at next (/var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/index.js:260:14)
ghost_1 | at next (/var/lib/ghost/versions/3.40.1/node_modules/express/lib/router/route.js:127:14)
ghost_1 | at /var/lib/ghost/versions/3.40.1/core/server/api/shared/http.js:124:17
ghost_1 |
ghost_1 | AccessDenied: Access Denied
ghost_1 | at Request.extractError (/var/lib/ghost/node_modules/aws-sdk/lib/services/s3.js:700:35)
ghost_1 | at Request.callListeners (/var/lib/ghost/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
ghost_1 | at Request.emit (/var/lib/ghost/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
ghost_1 | at Request.emit (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:688:14)
ghost_1 | at Request.transition (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:22:10)
ghost_1 | at AcceptorStateMachine.runTo (/var/lib/ghost/node_modules/aws-sdk/lib/state_machine.js:14:12)
ghost_1 | at /var/lib/ghost/node_modules/aws-sdk/lib/state_machine.js:26:10
ghost_1 | at Request. (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:38:9)
ghost_1 | at Request. (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:690:12)
ghost_1 | at Request.callListeners (/var/lib/ghost/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
ghost_1 | at Request.emit (/var/lib/ghost/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
ghost_1 | at Request.emit (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:688:14)
ghost_1 | at Request.transition (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:22:10)
ghost_1 | at AcceptorStateMachine.runTo (/var/lib/ghost/node_modules/aws-sdk/lib/state_machine.js:14:12)
ghost_1 | at /var/lib/ghost/node_modules/aws-sdk/lib/state_machine.js:26:10
ghost_1 | at Request. (/var/lib/ghost/node_modules/aws-sdk/lib/request.js:38:9)

Why are there two versions of my image in s3 bucket?

Dear Sir/Madam,

I want to ask why I get two versions of image (one with original file name and the other with added "_o"). Is it caused by the adapter or one of the amazon services? Thanks in advance.

BR,
Andy

Potential problem on stripEndingSlash function

Problem

Note the following code found in /src/index.js

const stripLeadingSlash = s => s.indexOf('/') === 0 ? s.substring(1) : s
const stripEndingSlash = s => s.indexOf('/') === (s.length - 1) ? s.substring(0, s.length - 1) : s

The expression s.indexOf("/") returns the first index in the string. That means stripEndingSlash will only strip ending slashes from strings with exactly one slash. A string containing two slashes will return with the trailing slash still in place.

Example

Consider the following cases:

const singleSlash = "index.js/"
// singleSlash.indexOf('/') equals 8
// 8 equals (singleSlash.length -1);
// Slash is removed
console.log(stripEndingSlash(singleSlash)); 
// "index.js"
const multiSlash = "/src/index.js/";
// multiSlash.indexOf('/') equals 0
// 0 doesn't equal (multiSlash.length -1)
// Slash is not removed
console.log(stripEndingSlash(multiSlash)); 
// "/src/index.js/"

Suggestion

You could fix this by changing indexOf to lastIndexOf, however, using charAt provides a more readable and performant expression:

const stripLeadingSlash = s => s.charAt(0) === "/" ? s.substring(1) : s
const stripEndingSlash = s => s.charAt(s.length - 1) === "/" ? s.substring(0, s.length - 1) : s

PathStyle for s3-like storages

Hi, I'm trying to setup this adapter in order to use it with Minio as object storage. Thing is Minio uses path style for storing objects. Unlike s3, which uses bucket.domain.com Minio one is domain.com/bucket

would it possible to use a path style setting in this adapter as well?

Possible issue using custom s3 endpoint (wasabi)

Hello,

We are trying to use this adapter with a number of Ghost blogs in order to deploy them in a cluster. This seemed to work great!
However, upon further testing, it appears that all images are referencing amazonaws.com, despite having set

      "endpoint": "https://s3.eu-central-1.wasabisys.com"

inside config.production.json.
Images are correctly uploaded to the wasabi bucket, but they are not showing in the web views because the links look like variations of this:
https://s3-eu-central-1.amazonaws.com/somebucketname/2021/02/untitled.png
This should probably be
https://somebucketname.s3.eu-central-1.wasabisys.com/2021/02/untitled.png

The full s3 block looks like this, minus the secrets:

"storage": {
    "active": "s3",
    "s3": {
      "accessKeyId": "xxx",
      "secretAccessKey": "xxx",
      "region": "eu-central-1",
      "bucket": "xxx",
      "endpoint": "https://s3.eu-central-1.wasabisys.com"
    }
  },

Did I misconfigure this in some way?

Thanks in advance for any and all help!

EDIT:
I continued trying things for a bit:
Using
"assetHost": "//bucket-name.s3.eu-central-1.wasabisys.com"
seems to have helped, but I am not sure if this is a proper solution :)

Region set to 'us-east-1' via Environment Variables does not work

this.host = process.env.GHOST_STORAGE_ADAPTER_S3_ASSET_HOST || assetHost || `https://s3${region === 'us-east-1' ? '' : `-${this.region}`}.amazonaws.com/${this.bucket}`

The last part of the || should be `https://s3${this.region === 'us-east-1' ? '' : `-${this.region}`}.amazonaws.com/${this.bucket}` instead.

I can submit a pull request to fix this or someone already set up to contribute and just make this simple change

Duplicate file

Hi,

So everytime I upload a picture, I see 2 files in my bucket. One is the original picture with _o. suffix, and the other one is the optimized version I guess without suffix.

I'm trying to figure out how to modify, either

  1. No optimization at all, just the original picture
  2. Auto delete _o. file after upload

But I couldn't figure out the part where this thing happens. I'm using the default adapter without any changes, which baffled me as I can't find this part in the source.

TypeError: Class constructor StorageBase cannot be invoked without 'new'

Using:

ghost v1.2.0
ghost-storage-adapter-s3 v2.0.0

Partial trace:

TypeError: Class constructor StorageBase cannot be invoked without 'new'\n
at new Store (/var/www/ghost/content/adapters/storage/s3/index.js:49:104)\n
at Object.getStorage (/var/www/ghost/versions/1.2.0/core/server/adapters/storage/index.js:74:21)\n
at setupBlogApp (/var/www/ghost/versions/1.2.0/core/server/blog/app.js:61:66)\n
at setupParentApp (/var/www/ghost/versions/1.2.0/core/server/app.js:65:36)\n
at /var/www/ghost/versions/1.2.0/core/server/index.js:72:37\n

Google:

Looks to be an issue with Babel transpilation. See https://github.com/gajus/react-css-modules/issues/196

PathPrefix when serving

Hi all, I see a problem that if I use pathPrefix in configuration, I might not access my current images, although I uploaded them to my proposed folder on S3 already.

For an instance, I create a bucket long.do and a folder inside that bucket as ghost, then in serving mode it ignores my pathPrefix, hence, server returns 404.

Could I make a pull request for it? Btw, my solution is adding pathPrefix with ending slash is removed before req.path (see more https://github.com/colinmeinke/ghost-storage-adapter-s3/compare/master...dotronglong:features/use-path-prefix-when-serving?expand=1)

Ghost 2.x S3 AccessDenied

Debug Information:

  • OS: Ubuntu, v18.04
  • Node Version: v8.10.0
  • NPM Version: 3.5.2
  • Ghost-CLI Version: 1.9.9
  • Ghost Version: 2.16.3
  • Environment: production

I have run into a very strange bug that I can't figure out the source of, that was never the problem with a ghost instance I built a few months back.

Setup

I followed the steps of documentation, as well as this commonly referenced blogpost it.ismy.fun/2018/08/26/ghost-custom-storage-module/ and this forum post s3-storage-adapter-and-ghost-2-9-1, but still receive the following errors:

Client-Side:

Uncaught TypeError: Cannot read property 'url' of undefined in vendor.min at editor run

Server-Side:

AccessDenied: Access Denied
    at Request.extractError (/var/www/ghost/content/adapters/storage/s3/node_modules/aws-sdk/lib/services/s3.js:585:35)

I started by installing this package to /var/www/ghost, which left node_modules folder, which I copied the contents of to /var/www/ghost/content/adapters/storage/s3. From there I noticed that the folder files only contain a skeleton of the package and that the node_module are missing, so I tried as the forum post mentions to run npm install in .../storage/s3, but ran into the errors:

npm WARN deprecated [email protected]: We recommend to use Travis Build Stages instead
npm WARN deprecated [email protected]: CircularJSON is in maintenance only, flatted is its successor.
npm ERR! Linux 4.15.0-36-generic
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install"
npm ERR! node v8.10.0
npm ERR! npm  v3.5.2

npm ERR! Cannot read property 'target' of null

Since I couldn't build the proper node_modules, I copied the rest of the folder from the initial npm install to a node_modules folder located in .../storage/s3.

From here, I updated the config.production.json file with the following code:

"paths": {
    "contentPath": "/var/www/ghost/content/"
},
"storage": {
  "active": "s3",
  "s3": {
    "accessKeyId": "*access-key*",
    "secretAccessKey": "*secret-key*",
    "region": "us-east-1",
    "bucket": "*my-app*-blog",
    "forcePathStyle": true
  }
},

The only change to the contentPath was a trailing /, which was suggested by the blogpost. I tried with and without and had the same error.

With the config modified, I updated the bucket policy as stated in the documentation,

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::*my-app*-blog"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:PutObjectVersionAcl",
                "s3:DeleteObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::*my-app*-blog/*"
        }
    ]
}

and then ghost restart, but this error appears whenever I try to upload an image from the editor. I see where the Forbidden is coming from the s3 module, but I don't know what could be triggering it. Can anyone help?

implement read method (required for favicon)

Steps to reproduce

  • Upload an image in admin->General->Publication icon and Save. I can see correctly the image in admin panel. So the upload works as expected.
  • Go to website.
  • favicon.png doesn't work.
  • I you go to /favicon.png it says: Error 500 - Cannot read property 'then' of undefined.

Ghost 1.0.0 has changed favicon logic and I can't override it with my custom logic.

Essentially it uses read method that is not implemented.

Stacktrace

TypeError: Cannot read property 'then' of undefined
    at serveFavicon (/usr/src/app/versions/1.5.1/core/server/middleware/serve-favicon.js:54:21)
    at Layer.handle [as handle_request] (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:317:13)
    at /usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:335:12)
    at next (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:275:10)
    at expressInit (/usr/src/app/versions/1.5.1/node_modules/express/lib/middleware/init.js:40:5)
    at Layer.handle [as handle_request] (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:317:13)
    at /usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:335:12)
    at next (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:275:10)
    at query (/usr/src/app/versions/1.5.1/node_modules/express/lib/middleware/query.js:44:5)
    at Layer.handle [as handle_request] (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:317:13)
    at /usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:335:12)
    at next (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:174:3)
    at EventEmitter.handle (/usr/src/app/versions/1.5.1/node_modules/express/lib/application.js:174:10)
    at mounted_app (/usr/src/app/versions/1.5.1/node_modules/express/lib/application.js:230:10)
    at Layer.handle [as handle_request] (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:317:13)
    at /usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:335:12)
    at next (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/index.js:275:10)
    at ghostLocals (/usr/src/app/versions/1.5.1/core/server/middleware/ghost-locals.js:15:5)
    at Layer.handle [as handle_request] (/usr/src/app/versions/1.5.1/node_modules/express/lib/router/layer.js:95:5)

Missing required key 'Bucket' in params

Whenever I attempt to add images I get
Missing required key 'Bucket' in params

Config is setup as...

storage: {
  active: 's3',
  s3: {
    accessKeyId: process.env.S3_ACCESS_KEY_ID,
    bucket: process.env.S3_BUCKET_NAME,
    region: process.env.S3_BUCKET_REGION,
    secretAccessKey: process.env.S3_ACCESS_SECRET_KEY
  }
}

Console out...

ghost_1  | ERROR: Missing required key 'Bucket' in params
ghost_1  |
ghost_1  |  MissingRequiredParameter: Missing required key 'Bucket' in params
ghost_1  |     at ParamValidator.fail (/app/content/storage/s3/node_modules/aws-sdk/lib/param_validator.js:50:37)
ghost_1  |     at ParamValidator.validateStructure (/app/content/storage/s3/node_modules/aws-sdk/lib/param_validator.js:61:14)
ghost_1  |     at ParamValidator.validateMember (/app/content/storage/s3/node_modules/aws-sdk/lib/param_validator.js:88:21)
ghost_1  |     at ParamValidator.validate (/app/content/storage/s3/node_modules/aws-sdk/lib/param_validator.js:34:10)
ghost_1  |     at Request.VALIDATE_PARAMETERS (/app/content/storage/s3/node_modules/aws-sdk/lib/event_listeners.js:114:42)
ghost_1  |     at Request.callListeners (/app/content/storage/s3/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
ghost_1  |     at callNextListener (/app/content/storage/s3/node_modules/aws-sdk/lib/sequential_executor.js:95:12)
ghost_1  |     at /app/content/storage/s3/node_modules/aws-sdk/lib/event_listeners.js:74:9
ghost_1  |     at finish (/app/content/storage/s3/node_modules/aws-sdk/lib/config.js:313:7)
ghost_1  |     at /app/content/storage/s3/node_modules/aws-sdk/lib/config.js:331:9
ghost_1  |     at Credentials.get (/app/content/storage/s3/node_modules/aws-sdk/lib/credentials.js:126:7)
ghost_1  |     at getAsyncCredentials (/app/content/storage/s3/node_modules/aws-sdk/lib/config.js:325:24)
ghost_1  |     at Config.getCredentials (/app/content/storage/s3/node_modules/aws-sdk/lib/config.js:345:9)
ghost_1  |     at Request.VALIDATE_CREDENTIALS (/app/content/storage/s3/node_modules/aws-sdk/lib/event_listeners.js:69:26)
ghost_1  |     at Request.callListeners (/app/content/storage/s3/node_modules/aws-sdk/lib/sequential_executor.js:101:18)
ghost_1  |     at Request.emit (/app/content/storage/s3/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
ghost_1  |     at Request.emit (/app/content/storage/s3/node_modules/aws-sdk/lib/request.js:673:14)
ghost_1  |     at Request.transition (/app/content/storage/s3/node_modules/aws-sdk/lib/request.js:22:10)
ghost_1  |     at AcceptorStateMachine.runTo (/app/content/storage/s3/node_modules/aws-sdk/lib/state_machine.js:14:12)
ghost_1  |     at Request.runTo (/app/content/storage/s3/node_modules/aws-sdk/lib/request.js:399:15)
ghost_1  |     at /app/content/storage/s3/node_modules/aws-sdk/lib/request.js:781:12
ghost_1  |     at Promise._execute (/app/node_modules/bluebird/js/release/debuggability.js:300:9)

Thanks for the help mate!

Documentation Issue: "GetBucket" is not a policy action

In the AWS configuration section of the README, you say we should use the Policy Generator to give the bucket the "GetBucket" action, but that isn't an option on AWS. There are many "GetBucket_____" options, but it's not clear which ones should and should not be granted.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.