pythondockerdockerpy

How do I copy a file to docker image when building dynamically


I'd like to build a docker image dynamically using Python/docker-py. My sample code is shown below. The problem is that I run into the Forbidden path outside the build context error at the COPY command. I don't know where to place my build.sql (sql_build_path} file to avoid this in a dynamic situation.

docker_file = f"""
    FROM postgres
    ENV POSTGRES_USER myuser
    ENV POSTGRES_PASSWORD mypassword
    ENV POSTGRES_DB mydb
    ENV ON_ERROR_STOP 1
    COPY {sql_build_path} /docker-entrypoint-initdb.d/
"""
f = io.BytesIO(docker_file.encode('utf-8'))
client = docker.from_env()
client.images.build(fileobj=f, tag="test", rm=True)

[EDIT]
Thanks, Jeevan -- I was able to discover that this is a known (and somewhat contested) issue, limited for security implications. Dynamically building the docker file and copying resources to a directory seem to be the best response. For my solution, I chose to python's temporary directory API.

with tempfile.TemporaryDirectory() as temp_dir:
    # save docker file to this directory
    # copy other files to this directory
    name, updates = client.images.build(path=temp_dir, dockerfile='Dockerfile', tag="test")
    for u in updates:
        print(u)

Solution

  • By default, fileobj sends a Dockerfile without any build context, that's why you can't copy anything.

    Here is my apporach:

    Create Dockerfile and copy build.sql in Dockerfile's directory

    build-img.py

    import docker
    path = '/root/Test/'  # Where Dockerfile and build.sql resides
    client = docker.from_env()
    print("Building image")
    client.images.build(path=path, dockerfile='Dockerfile',tag="test-image")
    

    Dockerfile

    FROM postgres
    ENV POSTGRES_USER myuser
    ENV POSTGRES_PASSWORD mypassword
    ENV POSTGRES_DB mydb
    ENV ON_ERROR_STOP 1
    COPY build.sql /docker-entrypoint-initdb.d/