Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds ability to specify container options in process-compose.yml #249

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

brandonbiggs
Copy link

I have been utilizing process compose for a few weeks now. I think it's a great tool, but there are a couple of challenges where I'm trying to utilize it in places it may not have been meant to be used in. In an attempt to fix this and improve this tool, I'd like to propose adding some additional process configuration options.

Background

There is a containerization tool in high performance computing that functions similarly to docker but can function without root permissions. This tool is called Apptainer. It can do many of the same tasks as docker without needing the docker permissions. However the tooling around apptainer is not as mature as docker as it is not used by nearly as many people.

Here is an example of running a command with apptainer:

apptainer exec --bind /data:/mnt my_container.sif python3 api.py

my_container.sif is a single executable file. Not the definition file, but the built container that can be transported. I can create it from scratch or by pulling existing apptainer or docker containers.

I can do this with process-compose as it currently exists, but I think it makes more sense to have some additional functionality for clarity and config cleanliness.

Here's an example of running a python API.

processes:
  API:
    command: "apptainer run --nv python.sif python3 /path/to/api.py"
    description: "Python API"
    log_location: "python.log"
    working_dir: "/path/to/python"
    availability:
      restart: "always"
    environment:
      - "APPTAINER_BINDPATH=\
         data/:/data,\
         settings.toml:/etc/python/settings.toml,\
         authentication.ini:/etc/python/authentication.ini"
      - "PATHS_CONFIG=/etc/python/authentication.ini"

This PR would allow it to be defined as:

 processes:
  API:
    command: "python3 /path/to/api.py"
    description: "Python API"
    log_location: "python.log"
    working_dir: "/path/to/python"
    availability:
      restart: "always"
    is_container: true
    container_runtime: "apptainer"
    container_execution: "exec"
    container_volumes:
      - "data:/data"
      - "settings.toml:/etc/python/settings.toml"
      - "authentication.ini:/etc/python/authentication.ini"
    container_image: "python.sif"
    container_args:
      - "--nv"
    environment:
      - "PATHS_CONFIG=/etc/python/authentication.ini"

I think this makes it more clear, and more similar to docker compose (without the need for docker and other strengths provided by process-compose :) )

Contributions

This PR adds the following options:

is_container            bool
container_runtime       string      (docker, apptainer, singularity, podman, etc)
container_execution     string      (exec, run, etc)
container_volumes       []string    (Each container runtime has a different way to define volumes, right now I'm only considering apptainer volumes which are defined with a -B/--bind
container_image         string      (full path to .sif or OCI path)
container_args          []string    (additional arguments to pass to the container runtime)

These options are ignored if is_container is not set to true or if container_runtime is not set to apptainer. This could be expanded to allow for other container tools like podman, singularity, docker, etc, but for right now it is just configured with apptainer in mind as that's the only app I have to test at the moment.

If there are any questions or feedback on this, please let me know. Thanks!

This introduces several new options in the configuration files. These options are ignored if `is_container` is not set to `true` or if `container_runtime` is not set to apptainer. This could be expanded to allow for other container tools like podman, singularity, docker, etc, but for right now it is just configured with apptainer in mind.

The new options include:
```
is_container            bool
container_runtime       string      (apptainer, singularity, podman, etc)
container_execution     string      (exec, run, etc)
container_volumes       []string    (Each container runtime has a different way to define volumes, right now I'm only considering apptainer volumes which are defined with a -B/--bind
container_image         string      (full path to .sif or OCI path)
container_args          []string    (additional arguments to pass to the container runtime)
```
Copy link

sonarcloud bot commented Sep 22, 2024

@dzmitry-lahoda
Copy link

dzmitry-lahoda commented Nov 2, 2024

How things will work on Windows/Mac? Process-Compose is cross platform, so some ideas on at least one more platform could be cool?

Why extra lines to be added by Process-Compose yaml config instead of using just command line like apptainer exec --bind /data:/mnt my_container.sif python3 api.py to execute? Should Process Compose TUI or process lifecycle to be changed? So not clear what is value added by integrating apptainer if fallback option to use script exists?

Imho integration with app sandboxes of Windows/MacOs Sandbox may be better things?

And linux:

These technologies are faster REPL/startup/build time than containers/vms and may appear better fit long term Process-Compose what is alternative to containers?

Also some previous idea about containers #87

@brandonbiggs
Copy link
Author

Thanks for the response!

How things will work on Windows/Mac? Process-Compose is cross platform, so some ideas on at least one more platform could be cool?

My hope was that this would lay the foundation for additional "container" tools on Windows/Mac. Apptainer works on Mac with some work. I'm not sure if it works on WSL on Windows, but this work would be very similar for podman, which works on both windows and mac and docker.

Why extra lines to be added by Process-Compose yaml config instead of using just command line like apptainer exec --bind /data:/mnt my_container.sif python3 api.py to execute?

I was originally doing what you're talking about here, but these apptainer commands can quickly become very long and complex, especially as bind paths are added. I liked the idea of it matching the docker compose style for things like this, but still being very powerful when not using docker compose. I guess I was trying to get the best of both worlds if that makes sense.

Should Process Compose TUI or process lifecycle to be changed?

I do not think process compose TUI or the process lifecycle need to be changed. One of the benefits of apptainer/singularity is that the containers can just be ran as executables like any other app.

So not clear what is value added by integrating apptainer if fallback option to use script exists?
You are right that the script option does absolutely exist. I felt it was just more convenient to have everything in the compose.yml file.

Imho integration with app sandboxes of Windows/MacOs Sandbox may be better things?
https://apple.stackexchange.com/questions/469368/app-and-terminal-isolation-sandboxing
https://learn.microsoft.com/en-us/windows/security/application-security/application-isolation/windows-sandbox/windows-sandbox-overview

I was not aware of these as I work almost entirely in linux. These are very cool though and I could see the benefit of having something like that as well.

And linux:
Nix buildFHSEnv
chroot/cgroups
whatever linux has else

I havne't personally used Nix so I don't know the benefit there.

I use cgroups as more of a means to control how many resources a process/set of processes has access to.

I've only used chroot to build images. I'm not sure the benefit here.

These technologies are faster REPL/startup/build time than containers/vms and may appear better fit long term Process-Compose what is alternative to containers?

Sure, I could see the benefit for adding support for these too.

Also some previous idea about containers #87

I like your use case here with the separate environments and cgroups. Apptainer has some of that built in so you can control the containers with cgroups which means you wouldn't need process compose to do that.

@dzmitry-lahoda
Copy link

dzmitry-lahoda commented Nov 11, 2024

TLDR; Imho there should be more deep thinking on container integration.

My hope was that this would lay the foundation for additional "container" tools on Windows/Mac. Apptainer works on Mac with some work. I'm not sure if it works on WSL on Windows, but this work would be very similar for podman, which works on both windows and mac and docker.

Unlike containers, I guess people may expect PC(process compose) to work on all platforms with less right or configs. And it to support HOST OS on HOST OS runs. I would expect Mac to work on Mac and Windows on Windows. Because PC does that.
So kind of possible expected, at least for me(and hence 2 companies I worked at and integrated PC), for containers integratios works on all OSes with HOST on HOST mode without need for SUDO or installation same way. Likely it will be subset of containers. I just afraid just planning(doing Linux) may may prevent consistency porting that to Mac/Windows.

I was originally doing what you're talking about here, but these apptainer commands can quickly become very long and complex, especially as bind paths are added. I liked the idea of it matching the docker compose style for things like this, but still being very powerful when not using docker compose. I guess I was trying to get the best of both worlds if that makes sense.

As long as apptainer is linux or mac only, it may put commands into sh scripts and call them, as fallback.
Assuming we have put apptainer commands into nice sh scripts. What else is not here to have apptainer well integrated?

Also containers bring bad things too - need to build image. Most builder to copies of files instead doing links (doing links is not portable). So containers bring worth of both words too.

I do not think process compose TUI or the process lifecycle need to be changed. One of the benefits of apptainer/singularity is that the containers can just be ran as executables like any other app.

If process lifecycle or TUI would need changes, it would mean that there is something which needs active integration of containers with PC. So it would be pro containers argument. Currently argument is only long scripts.

I was not aware of these as I work almost entirely in linux. These are very cool though and I could see the benefit of having something like that as well.
I havne't personally used Nix so I don't know the benefit there.
I use cgroups as more of a means to control how many resources a process/set of processes has access to.
I've only used chroot to build images. I'm not sure the benefit here.
I like your use case here with the separate environments and cgroups. Apptainer has some of that built in so you can control the containers with cgroups which means you wouldn't need process compose to do that.

I am not expert in any of this, so worked with all.

PC allows to build host binaries on host and use them without building containers. Containers may require build in container(HOST<-> GUEST OS), and copy a lot of files.

That is slow. If Apptainer on Mac can run Mac osses and allows to link binaries from host instead of copying (slow), than it is very good and I am for it. But is it?

As for nix, nix is just *nix. In the end any nix thing is just set of traditional bash and configs files.
For example buildFHSEnv allowed me, non power user of linux, to setup light isolation to test if my scripts will run well on CI. CI vs Docker vs Local usually different. So need to test these.

So for linux idea that I do not need to install anything to do buildFHSEnv/cgroups/chroot/etc on Linux to get container like behaviour (for testing at least, not security) and fast REPL(can reuse host files).

Similar for Mac and Windows.

If on Linux Apptainer is shortcut for light isolation without a lot of file copying(without long time to take to build container, but more like just linking host files) than it is super good (I used nix as example as it provides such feature out of box).

Windows/Mac/Linux has similar technologies to:

  1. reuse host files
  2. run host os on host os, with host os built for and on binaries
  3. add some simple isolation (ACL to read/write files, use network, etc)

than these technologies are more likely to be better fit for Process Compose than Apptainer(or Containers).

Specific techs of aternatives/references:

  1. how to not copy files from host to container https://github.com/pdtpartners/nix-snapshotter?tab=readme-ov-file#key-features - just hook into container load process and give it links.
  2. other tech idea to share xplat binaries Native packaging and updating  #219 (comment) , so that not xplat containers, but xplat apps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants