strapi / strapi-docker

Install and run your first Strapi project using Docker
https://strapi.io
MIT License
1.16k stars 447 forks source link

Building in Docker-in-Docker environment - missing node_modules etc. #316

Closed davesade closed 2 years ago

davesade commented 2 years ago

Hello! I'm new to Strapi, but I found some integral issues with the concept of operations.

In the age of cloud providers, it doesn't seems to be best solution to rely on external volume for managing application files. We tried to avoid this issue by running application in develop mode locally, then commiting changes to repository and run our own Docker build. This way we can version changes of data structures and deploy to any of target environments.

However, when running this in GitLab Runner, which uses DockerInDocker solution for builds, we encountered a problem. See our Dockerfile:

FROM strapi/strapi
WORKDIR /srv/app
COPY app/ .
RUN yarn install && strapi build
CMD ["yarn", "start"]

COPY command will copy over only relevant json files with datastructures, not node_modules or build (it's gitignored / dockerignored), including package.json etc.

However, the RUN command, when executed in DockerInDocker, will store data only in ephemeral storage and the intermediate container was thrown away during build time. I checked the instance via SSH - I can confirm node_modules were present during the build time.

After many hours of investigation I figured out, that the issue is actually in VOLUME definition in strapi/strapi image. Simply by changing WORKDIR above to srv/strapi it all started to work as a charm.

I only assume it's caused by DockerInDocker, because when I ran the build on my local machine, it actually works correctly even with VOLUME in Dockerfile.

So I'd like to suggest to remove VOLUME from Dockerfile completely and rethink a way, how Strapi is suppose to be operated in Docker environments (ie. people can actually version changes, instead doing changes in live system manually).

Thank you for consideration.

ChristianHeimke commented 2 years ago

@davesade I totally agree with your thoughts. But as far as I understand the starpi-docker universe, the starpi/strapi image is only for development and testing purpose.

If you want to run strapi in a production env inside docker you should use the strapi/base image, as described in the readme:

When deploying a strapi application to production you can use docker to package your whole app in an image (https://github.com/strapi/strapi-docker#how-to-use-strapibase)

I hope this will help for your production setup ;-)

davesade commented 2 years ago

@ChristianHeimke Thanks for a response - and I understand and agree, this is issue only if used with strapi/strapi image. We did a switch to strapi/base already.

For future reference I'd like add my two cents:

Most of the documentation seems to be written in a way of running Strapi on standalone machine with one persistent volume (example). It is assumed, that one will SSH into the instance, make necessary changes, rebuild application and then run it.

Running Strapi in Docker, using recommended Dockerfiles, will result a fresh build on runtime, which is taking many minutes even on powerful instances and it's not designed to run in parallel with single volume on cluster. Upgrading application and it's plugins or configuration requires change on the volume and restarting containers, initiating rebuild. This approach might be fine for some cases.

Approach we took, as outlined above, is to have app folder in GIT and then running yarn build in Dockerfile. That will create Docker image with versioned configurations, no extra volume mount (we use an external bucket for media files) and that enables us to run Strapi in multiple replicas with very short boot time - making it more usable for cloud workloads.

It would be awesome to see those features being implemented in Strapi directly, plus staging of content between environments.

That's all from my side, have a great day!