• 145 Posts
  • 4.02K Comments
Joined 1 年前
cake
Cake day: 2023年9月1日

help-circle










  • It’s probably “sh” “-c” that was being used. That’s the ENTRYPOINT. CMD is passed to the ENTRYPOINT. The docs explain it well, I think.

    As for volumes, TL;DR these are mounted into the container at runtime and are not in the image. You may put the dev and production config in the image, but I’d advise against it, especially if the production config contains secrets. Then they’ll be baked into the docker image.

    long explanation

    A docker image is basically an archive of archives. Each line you put in a Dockerfile is executed and the result thereof is put into an archive with a name (hash of the contents plus maybe other stuff) and that’s called a layer. To keep the layers small, they contain only the updates to the previous layer. This is done with Copy On Write (CoW).

    FROM alpine
    RUN touch /something # new archive with one single file
    RUN apk add curl # new archive with paths to curl WITHOUT /something
    

    To run a docker image aka docker run $options $image. The archive and its layers are extracted, then a new runtime environment is created using linux kernel namespaces (process namespace, network namespace, mount / storage namespace, …), and the sum of the layers is mounted in there as a “volume”. That means the processes within the container are segregated from the host’s processes, the container’s network is also segregated, the storage / files and folders too, and so on.

    So there’s a, for lack of a better term, root/runtime volume (/) from the sum of layers. So the container only sees the the layers (plus some other fundamental stuff to run like /dev, /proc, etc.). You can mount a file into the container, a folder, a device, or even a network drive if you have the right driver installed. Mounting a file or folder is called a “bind mount”, everything else (if I’m not mistaken) is just a mount. Volumes in docker are built on top of that. The doc explains in detail what volumes are and their naming.

    In conclusion, docker image = archive, docker container = extracted archive running in linux namespaces, volume = storage that be mounted into container.

    Finally, parameterising compose files: use environment variables. You can put then into a .env beside your compose.yaml or set them before calling e.g ENVIRONMENT_VARIABLE=someValue docker compose up.

    They are “interpolated” aka used in the compose file like so

    services:
      web:
        image: "webapp:${TAG}"
    

    I recommend you read the docs on the syntax, but for your purpose I’d use something like

    volumes:
      - ${ENV_FILE:?Env file not provided}:/usr/src/app/.env
    

    Then you can ENV_FILE=prod.env docker compose up or put the env var in .env and docker compose will pick it up.

    Anti Commercial-AI license