mbecker20 / komodo

🦎 a tool to build and deploy software on many servers 🦎
https://komo.do
GNU General Public License v3.0
1.74k stars 34 forks source link

[Bug] relative bind mounts in stacks are deleted after deployment #68

Closed yyogo closed 4 weeks ago

yyogo commented 1 month ago

The root stack directory in komodo/stacks is deleted immediately after deployment. This causes issues when a docker-compose.yaml contains relative bind mounts. e.g, in this compose test_relative fails after deployment:

services:
  test_relative:
    image: alpine:latest
    command: sh -c "sleep 5 &&  echo hello > /test/hello && echo success"
    volumes:
      - ./test:/test
  test_absolute:
    image: alpine:latest
    command: sh -c "sleep 5 &&  echo hello > /test/hello && echo success"
    volumes:
      - /tmp/test_komodo_bug:/test
mbecker20 commented 1 month ago

For Git repo based stack, you have to delete the folder before reclone. You should use absolute path outside of repo directory as the mount, or just use a docker volume. Because of this, I figured it was safer actually for UI defined to also keep this behavior, so a user doesn't switch to git based stack after deploying and it ends up deleting their data at that point. It won't happen if user doesn't mount anything in this folder anyways.

BUT I'm changing so UI defined compose file won't delete the stack folder after deploy. You could use a relative mount inside the folder in this case, starting from 1.14.1. But I don't think it is a good idea anyways. I just document this behavior here anyways and give my recommendation: https://komo.do/docs/docker-compose#using-bind-mounts.

Files on host mode won't touch the deploy folder at all so you can do whatever you want in this case.

yyogo commented 1 month ago

I think deleting the repo is not ideal. It means some file references will always be dangling (to the compose.yaml, .env e.g.). and there are many projects that rely on binding local mounts. Would you consider an option to keep the repo in the stack dir and pull changes instead of recloning?

mbecker20 commented 1 month ago

While missing compose.yaml or .env are not an issue after deploy time, I suppose a very common usage pattern is to store config files in the repo as well, and mount them to the container. Theres definitely a lot more edge cases to figure out with git pull. Komodo will have to know whether to do a fresh clone, or git pull. It will have to ensure configured branch is actually checked out (user could change after deploy), or even check the remote matches in case users change this. And definitely any changes created by local mounts that write to the file will be a problem, but I doubt this to be common. It would be critical to get this right so users don't find themselves in a position where they have some conflict preventing a pull, but they have data mounted which prevents them from recloning, basically they will be kind of stuck and may accidentally delete data to resolve it. I think in the end it will be simpler for users to design their compose setups in repos knowing that the repo can be deleted, recloned, and redeployed without issue. Basically, always keep everything "fresh" off of deploy, always fresh clone etc. Then they never need to worry about any git gymnastics.

Currently you can either:

  1. Recommended: Package the config into the container locally, at deploy time. Add a Dockerfile to the repo, this will have FROM image_name:tag for image you want to deploy,COPY ./config /etc/config, and then add the same CMD or ENTRYPOINT as the parent image. Then in your compose file, you change the image line to a build spec: https://docs.docker.com/reference/compose-file/build/#dockerfile. And then enable Build in the compose config.

  2. Use a Komodo Repo along with the stack. Create a Komodo repo pointing to the same remote, and clone it. Then, change the docker compose config mounts to reference the config file in that repo, with an absolute path. You can setup a webhook to keep the repo pulled and up to date, and the latest will be available for every deploy. You may want to use a procedure to facilitate PullRepo, then DeployStack, which you can also trigger with a webhook. Just note, it is probably better to use a bind mount (- /home/user/repos:/etc/komodo/repos) than a docker volume, to make the repo folder easier to find on your host.

But I will continue to consider the possibility of implementing a git pull option.

mbecker20 commented 1 month ago

UI based compose files / folder are NO LONGER deleted between deploys, 1.14.1 is out: https://github.com/mbecker20/komodo/releases/tag/v1.14.1

mbecker20 commented 1 month ago

In 1.15, changes in Repo based stack will be pulled, and the folder won't be deleted anymore.