0

Currently, I have two python scripts, one that launches a docker container and another to run inside the container after launch. I would like to make this a single file that will launch the container and then execute the rest of the code inside the container. Is this possible, and if so, how?

I've tried the docker python library and connecting via ssh to the container after it's started but nothing seems to work without just using the two scripts.

Thanks in advance for any help.

blaufer
  • 117
  • 1
  • 3
  • 11
  • 1
    We'll need much more information: your python code and the Dockerfiles to start with! – Nathan Furnal Apr 21 '23 at 14:34
  • That's all proprietary information that can't be posted here. It can simply be assumed that I have a container with just python3.9 and use subprocess to launch docker. The internal script could be just doing something like print('hello world'). – blaufer Apr 21 '23 at 14:43
  • Then you should come up with a reproducible example that mimicks your problem if that's possible. – Nathan Furnal Apr 21 '23 at 14:51
  • 1
    I'd try to just combine this into a single program. Without Docker you wouldn't launch a Python REPL and then try to run your program inside this, you'd just run the same program; in the same way, you shouldn't normally need to run things "inside a container" that aren't the main container process. – David Maze Apr 21 '23 at 15:07
  • I understand what you're saying the problem comes down to needing to use a Docker container because the systems that the final programs are launched on do not contain any of the needed python, cpp, fortran, etc. libraries and are thus run inside of docker containers which do. All I have outside of docker is python and it's standard library. – blaufer Apr 21 '23 at 16:56

1 Answers1

1

From your question, you want to have code that creates a docker container, and then in the same file have code that is only executed inside the docker container.

Which is possible using the following setup:

  • dockerfile

      FROM python:3.8-slim-buster
    
      WORKDIR /src
    
      COPY requirements.txt requirements.txt
      RUN pip install --no-cache-dir -r requirements.txt
    
    
      COPY . .
    
      ENV AM_I_IN_A_DOCKER_CONTAINER=True
      CMD [ "python", "-m" , "main"]
    
  • main.py

      import os
      import subprocess
    
      if __name__ == '__main__':
          # https://stackoverflow.com/questions/43878953/how-does-one-detect-if-one-is-running-within-a-docker-container-within-python
          SECRET_KEY = os.environ.get('AM_I_IN_A_DOCKER_CONTAINER', False)
    
          if not SECRET_KEY:
              print(f"Code running to create container.")
    
              process = subprocess.Popen(["docker", "build", "--tag", "stackoverflow-question", "."])
              process.wait(timeout=60)
              process.terminate()
              print(f"Created image: 'stackoverflow-example'")
    
              process = subprocess.Popen(["docker", "run", "--publish", "5000:5000", "stackoverflow-question"])
              process.wait(timeout=60)
              print(f"Created container: 'stackoverflow-example'")
              print(f"Terminating primary script.")
              exit()
    
          import numpy as np
    
          print(f"\nWelcome inside the container.")
          print(f"This will be running inside the container only.")
          print(np.random.randint(1, 255, 10))
    
  • requirements

    numpy
    

Process

The process is performed in two steps.

Firstly, we need to execute code that will create the docker image and launches the container. The above code uses subprocess to create a new image that contains the main.py and the requirements.txt file. Then in the container we also specify that it should run the main.py file.

Secondly we have to distinguish what code from main.py we are running inside and outside the container. This is done by using a post from Kyle Truong (43878953), which is the variable AM_I_IN_A_DOCKER_CONTAINER. Now we can split the main.py file in a section to run before the container, and after the container.

Side note

This code will launch one new docker container on every run so be sure to close them.

Thymen
  • 2,089
  • 1
  • 9
  • 13