docker-library / ghost

Docker Official Image packaging for Ghost
https://hub.docker.com/_/ghost
MIT License
744 stars 314 forks source link

Declaring content/ path as a VOLUME mount point causing problems #195

Open maxcct opened 4 years ago

maxcct commented 4 years ago

A while ago I opened this issue: https://github.com/docker-library/ghost/issues/185, which was answered and closed before I had a chance to respond.

My problem is that this image prevents any modification of directories within content/, and I can't see why this is desirable or necessary. Probably I'm just being dense, but I can't work out how the proposed solution would enable me to use this image in a way that would make it possible to modify directories within content/.

Could the guidance be clarified/expanded, or, ideally, could the line declaring content/ as a fixed volume be removed? What useful purpose is it serving?

pascalandy commented 4 years ago

It's best practice to define the VOLUME in which the app is living in. Ghost lives inside /content per say.

mason commented 4 years ago

@pascalandy then how does one modify the content of the volume(say to add s3 storage adapter)? At the moment doing this doesn't work

FROM ghost:3.12.0

WORKDIR /var/lib/ghost

RUN npm install ghost-storage-adapter-s3 \
        && mkdir -p content/storage \
        && cp -vr ./node_modules/ghost-storage-adapter-s3 ./content/storage

declaring it as volume blows out that directory. https://docs.docker.com/engine/reference/builder/#volume

Changing the volume from within the Dockerfile: If any build steps change the data within the volume after it has been declared, those changes will be discarded.

pascalandy commented 4 years ago

I don't know. But here is where you can know :) https://ghost.org/docs/concepts/storage-adapters/

mason commented 4 years ago

I don't know. But here is where you can know :) https://ghost.org/docs/concepts/storage-adapters/

Am I missing something? I definitely checked that page before posting. It doesn't talk much about this issue. In fact, the solutions for s3 storage adapter does not work specifically for this reason.

pascalandy commented 4 years ago

As I said, I don't use storage adapters.

My gut feeling.

Install the adapter like your did. (I would add this step in the original dockerfile You need to update your config_production.json file with the appropriate ENV.

Have you checked on https://forum.ghost.org/ ?

yosifkit commented 4 years ago
    && cp -vr ./node_modules/ghost-storage-adapter-s3 ./content/storage

But why do you need to move the adapter inside of ghost content? Shouldn't npm install (or yarn add) be enough for node and ghost to be able to use it? (just like the sqlite3 that gets installed in the dockerfile) Maybe it needs a gosu node npm install ghost-storage-adapter-s3 so that it is running as the correct user?

https://github.com/docker-library/ghost/blob/20f003a55d1b52efa436df1981852155e8f418c0/3/debian/Dockerfile#L74


If it really needs to be in the content/storage directory, then you can just drop it in $GHOST_INSTALL/content.orig/storage and it will be placed into the volume on first start:

https://github.com/docker-library/ghost/blob/20f003a55d1b52efa436df1981852155e8f418c0/3/debian/docker-entrypoint.sh#L10-L20

Related/duplicate of #212.

yosifkit commented 4 years ago

Now as to the content VOLUME which is the original question.

What useful purpose is it serving?

The way I understand it, the content/ of ghost is considered the mutable state of the application. Since docker does not copy the files in the image to a bind mount, we have to copy in the default files in the entrypoint. We have the volume to ensure all users don't store stuff there so that the resulting image can be used with any kind of volume for persistent storage.

This is basically the same as the WordPress image; although it has to do all of WordPress instead of just a subdirectory https://github.com/docker-library/wordpress/issues/232#issuecomment-340613133.

mason commented 4 years ago

For anyone wondering, the following dockerfile worked for me

FROM ghost:3.12.0

WORKDIR /var/lib/ghost

RUN npm install ghost-storage-adapter-s3 \
        && mkdir -p ./content.orig/adapters/storage \
        && cp -vr ./node_modules/ghost-storage-adapter-s3 ./content.orig/adapters/storage/ghost-s3

Docker run:

docker run -p 2368:2368 -e storage__active=ghost-s3 -e storage__ghost-s3__accessKeyId=<keyid> -e storage__ghost-s3__secretAccessKey=<secret> -e storage__ghost-s3__bucket=<bucket> -e storage__ghost-s3__region=<region> ghost/s3:3.12.0

But why do you need to move the adapter inside of ghost content? Shouldn't npm install (or yarn add) be enough for node and ghost to be able to use it?

I think how it works is that the code explicitly imports from a specific directory. see here: https://github.com/TryGhost/Ghost/blob/9d4b0c09a8061768b145a737fd0a8ec25108134d/core/server/api/v2/images.js#L1

derek-adair commented 1 year ago

This is a confusing issue to me; is this an issue with your development workflow or deploying in production? Is this in a custom docker image?

Seems like some additional advice on how to pre-seed content/plugins/config is needed in the README's and that it should be done like advised here by adding to content.orig.

This was actually a point of frustration for me when first leveraging this image -- it's not a real pleasant experience learning how this image works and will trip up people who are weak system admins.

muratcorlu commented 9 months ago

For anyone wondering, the following dockerfile worked for me

FROM ghost:3.12.0

WORKDIR /var/lib/ghost

RUN npm install ghost-storage-adapter-s3 \
        && mkdir -p ./content.orig/adapters/storage \
        && cp -vr ./node_modules/ghost-storage-adapter-s3 ./content.orig/adapters/storage/ghost-s3

Docker run:

docker run -p 2368:2368 -e storage__active=ghost-s3 -e storage__ghost-s3__accessKeyId=<keyid> -e storage__ghost-s3__secretAccessKey=<secret> -e storage__ghost-s3__bucket=<bucket> -e storage__ghost-s3__region=<region> ghost/s3:3.12.0

But why do you need to move the adapter inside of ghost content? Shouldn't npm install (or yarn add) be enough for node and ghost to be able to use it?

I think how it works is that the code explicitly imports from a specific directory. see here: TryGhost/Ghost@9d4b0c0/core/server/api/v2/images.js#L1

Does this still work with v5? Is that content.orig folder is a special one that Ghost checks over regular content folder? Or do you set as your content path? (If so, what is the point here?)

I'm also having the same issue as not being able to add/change storage adapters to the projects that allready has mounted content path as volume. Added or changed storage become inside the content/adapters/storage folder of docker image, but that path is overriden by the container's volume. I feel like we need to pick specific folders inside content path those are only changed by users, like themes or images, files etc. But not the adapters folder.

muratcorlu commented 9 months ago

I tried the approach putting adapter inside content.orig folder, but that doesn't help. In Dockerfile content.orig folder is overwritten with the content from volume. Check here:

https://github.com/docker-library/ghost/blob/4a77eba274347d0835dee9f8bdca17bff44f3815/5/alpine/Dockerfile#L48

So I can not update adapter. Only option that I see now is adding multiple volumes per each needed folder in content folder, like:

volumes:
  - settings:/var/lib/ghost/content/settings
  - themes:/var/lib/ghost/content/themes
  - data:/var/lib/ghost/content/data