{"id":13425018,"url":"https://github.com/se7entyse7en/pydockenv","last_synced_at":"2025-04-13T11:47:48.858Z","repository":{"id":56238863,"uuid":"176281191","full_name":"se7entyse7en/pydockenv","owner":"se7entyse7en","description":"Python virtual environment, but backed by Docker!","archived":false,"fork":false,"pushed_at":"2023-05-11T20:38:53.000Z","size":35189,"stargazers_count":480,"open_issues_count":18,"forks_count":18,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-10-30T00:33:21.082Z","etag":null,"topics":["docker","environment","python","virtualenv"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/se7entyse7en.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-03-18T12:33:55.000Z","updated_at":"2024-06-12T12:48:21.000Z","dependencies_parsed_at":"2022-08-15T15:10:53.380Z","dependency_job_id":"9316a508-de2f-49d6-bc88-a2b52470f2a2","html_url":"https://github.com/se7entyse7en/pydockenv","commit_stats":{"total_commits":210,"total_committers":6,"mean_commits":35.0,"dds":0.04761904761904767,"last_synced_commit":"c3e3f9005570319306603589be824059db708eba"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/se7entyse7en%2Fpydockenv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/se7entyse7en%2Fpydockenv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/se7entyse7en%2Fpydockenv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/se7entyse7en%2Fpydockenv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/se7entyse7en","download_url":"https://codeload.github.com/se7entyse7en/pydockenv/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248710409,"owners_count":21149186,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","environment","python","virtualenv"],"created_at":"2024-07-31T00:01:02.377Z","updated_at":"2025-04-13T11:47:48.837Z","avatar_url":"https://github.com/se7entyse7en.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# pydockenv\n\n![Python versions](https://img.shields.io/pypi/pyversions/pydockenv.svg)\n![Pypi](https://img.shields.io/pypi/v/pydockenv.svg)\n![License](https://img.shields.io/github/license/se7entyse7en/pydockenv.svg)\n\n*Notice: This project is currently in alpha stage*\n\n`pydockenv` is a library that aims to give the same experience of having a virtual environment, but backed by Docker! The idea is to make the usage of Docker completely hidden so that even non-expert Docker users can leverage the advantages provided by using it as the underlying engine.\n\n## Installation\n\nTo install `pydockenv` simply run the following:\n```\npip install pydockenv\n```\n\n## Why?\n\nI assume that everybody landing here knows the great advantages that virtual environment brings. The reason I've started this project is that Docker provides even better isolation from the underlying system, and brings the advantage of being really portable across different systems.\n\nIn my personal experience sometimes it is difficult to replicate the same local virtual environment, and eventually save it and share it with somebody else, especially if the one you want to share the environment with runs, for example, a different operating system.\n\nUsing Docker as the engine of the virtual environment makes the environment itself isolated, easily sharable, and also eventually ready-to-be-deployed given that it is still a Docker container.\n\n## Quickstart\n\nThe installation will provide you with the `pydockenv` binary that lets you create, save, load an environment, and handle its dependencies.\n\nLet's start by creating an environment!\n\n### Let's create the environment!\n\nTo create an environment run the following command:\n```\npydockenv create --name=\u003cenv name\u003e \u003cproject directory\u003e\n```\n\nFor example, if you are in the root of a project named `awesome-project` this could be:\n```\npydockenv create --name=awesome-project .\n```\n\nThis will create a Docker container with the latest Python version installed! If you want to create an environment with a specific Python version you only just need to add the `--version=\u003cpython version\u003e` to the previous command:\n```\npydockenv create --name=awesome-project --version=3.6 .\n```\n\nAs you may have noticed, to create the environment you have to set a project directory. This means that everything that is not inside the project directory is completely invisible to the environment. For example, you cannot access a Python script that resides outside your project directory. See the details in the [Advanced](#advanced) section.\n\n#### Creating an environment from a `*.toml` file\n\nAlternatively, you can use a `*.toml` file describing your environment. This is analogous to having a `requirements.txt` file. This file describes both the dependencies and the python version to use, for example:\n```\n[tool.pydockenv]\nname = \"awesome-project\"\npython = \"3.7.4\"\n\n[tool.pydockenv.dependencies]\nrequests = \"\u003e=2.22.0\"\n```\n\n*All the version specifiers described in [PEP 440](https://www.python.org/dev/peps/pep-0440/#version-specifiers) are supported.*\n\nLet's say that this is the content of a `pydockenv.toml` file in the current working directory. You can then create the environment as follows:\n```\npydockenv create --file=pydockenv.toml \u003cproject directory\u003e\n```\n\nYou can eventually create it with a different name still using the `--name` flag:\n```\npydockenv create --file=pydockenv.toml --name=another-awesome-project \u003cproject directory\u003e\n```\n\nThe `*.toml` file can be automatically created from an already existing environment by running:\n```\npydockenv export --output=pydockenv.toml\n```\n\n### Activation and packages installation\n\nNow you can activate your newly created environment!\n```\nsource pydockenv activate \u003cenv name\u003e\n```\n\nYou can verify that the environment has been successfully activated by also running\n```\npydockenv status\n```\n\nWith `pydockenv` you can install Python packages simply by using the install command:\n```\npydockenv install \u003cpackage\u003e\n```\nsuch as:\n```\npydockenv install requests\n```\n\nand that's it! You can list all your environments and all the packages installed in the currently active environment with the following commands respectively:\n```\n# list all environments\npydockenv list-environments\n# list packages installed in the current environment\npydockenv list-packages\n```\n\n### Running the Python shell\n\nTo run the Python shell you simply have to run the `shell` command:\n```\npydockenv shell\n```\nand the shell with the correct version of Python will start.\n\n### Running a sample application\n\nRunning a Python script is very easy as well. Instead of running it as:\n```\npython script.py arg1 arg2 ...\n```\nyou just have to prefix it with `pydockenv run` as follows:\n```\npydockenv run python script.py arg1 arg2 ...\n```\n\nAnd that's it! You're now ready to go!\nFor a more complete overview of the commands see the [Examples](#examples) and the [Commands reference](#commands-reference) sections.\n\n\n## Examples\n\nHere are some examples that are available in the `examples` directory to show more practically how to use `pydockenv`.\n\n### Hello World!\n\nFile: `examples/hello_world.py`.\n\nThis first example just shows how different environments work. The script simply prints the `Hello World!` string followed by the Python version being used. You can run this in different environments and see how the output changes.\n\n- Environment created with Python 3.8:\n```\n✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv create --name=hello-world --version=3.8 .\nINFO[0000] Creating virtual environment...               name=hello-world project-dir=. toml-file= version=3.8\nERROR: You must give at least one requirement to install (see \"pip help install\")\nINFO[0017] Virtual environment created!                  name=hello-world project-dir=. toml-file= version=3.8\n✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ source pydockenv activate hello-world\nINFO[0000] Activating virtual environment...             name=hello-world\nINFO[0000] Virtual environment activated!                name=hello-world\n(hello-world) ✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv run python hello_world.py\nINFO[0000] Running command...                            command=\"[python hello_world.py]\" detach=false env-vars=\"map[]\" ports=\"[]\"\nHello World!\nPython version: 3.8.3 (default, Jun  9 2020, 17:39:39)\n[GCC 8.3.0]\nINFO[0000] Command ran!                                  command=\"[python hello_world.py]\" detach=false env-vars=\"map[]\" ports=\"[]\"\n```\n\n- Environment created with Python 3.7.\n```\n✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv create --name=hello-world --version=3.7 .\nINFO[0000] Creating virtual environment...               name=hello-world project-dir=. toml-file= version=3.7\nERROR: You must give at least one requirement to install (see \"pip help install\")\nINFO[0013] Virtual environment created!                  name=hello-world project-dir=. toml-file= version=3.7\n✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ source pydockenv activate hello-world\nINFO[0000] Activating virtual environment...             name=hello-world\nINFO[0000] Virtual environment activated!                name=hello-world\n(hello-world) ✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv run python hello_world.py\nINFO[0000] Running command...                            command=\"[python hello_world.py]\" detach=false env-vars=\"map[]\" ports=\"[]\"\nHello World!\nPython version: 3.7.7 (default, Jun  9 2020, 17:58:51)\n[GCC 8.3.0]\nINFO[0000] Command ran!\n```\n\n### Requests\n\nFile: `examples/requests_get.py`.\n\nThis second example shows how you can install external packages and run Python scripts by passing arguments as you would do normally.\n\n```\n✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv create --name=requests --version=3.8 .\nINFO[0000] Creating virtual environment...               name=requests project-dir=. toml-file= version=3.8\nINFO[0001] Virtual environment created!                  name=requests project-dir=. toml-file= version=3.8\n✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ source pydockenv activate requests\nINFO[0000] Activating virtual environment...             name=requests\nINFO[0000] Virtual environment activated!                name=requests\n(requests) ✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv install requests\nINFO[0000] Installing packages...                        file= packages=\"[requests]\"\nCollecting requests\n  Downloading requests-2.24.0-py2.py3-none-any.whl (61 kB)\n     |████████████████████████████████| 61 kB 155 kB/s\nCollecting urllib3!=1.25.0,!=1.25.1,\u003c1.26,\u003e=1.21.1\n  Downloading urllib3-1.25.9-py2.py3-none-any.whl (126 kB)\n     |████████████████████████████████| 126 kB 1.2 MB/s\nCollecting idna\u003c3,\u003e=2.5\n  Downloading idna-2.9-py2.py3-none-any.whl (58 kB)\n     |████████████████████████████████| 58 kB 1.2 MB/s\nCollecting chardet\u003c4,\u003e=3.0.2\n  Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB)\n     |████████████████████████████████| 133 kB 1.4 MB/s\nCollecting certifi\u003e=2017.4.17\n  Downloading certifi-2020.6.20-py2.py3-none-any.whl (156 kB)\n     |████████████████████████████████| 156 kB 1.4 MB/s\nInstalling collected packages: urllib3, idna, chardet, certifi, requests\nSuccessfully installed certifi-2020.6.20 chardet-3.0.4 idna-2.9 requests-2.24.0 urllib3-1.25.9\nINFO[0005] Packages installed!                           file= packages=\"[requests]\"\n(requests) ✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv run requests_get.py https://github.com\nINFO[0000] Running command...                            command=\"[requests_get.py https://github.com]\" detach=false env-vars=\"map[]\" ports=\"[]\"\nOCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused \"exec: \\\"requests_get.py\\\": executable file not found in $PATH\": unknown\nINFO[0000] Command ran!                                  command=\"[requests_get.py https://github.com]\" detach=false env-vars=\"map[]\" ports=\"[]\"\n(requests) ✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv run python requests_get.py https://github.com\nINFO[0000] Running command...                            command=\"[python requests_get.py https://github.com]\" detach=false env-vars=\"map[]\" ports=\"[]\"\nRequested https://github.com: status code = 200\nINFO[0000] Command ran!\n```\n\n### Flask web app\n\nFile: `examples/flask_hello_world.py`.\n\nThis third example shows how you can run a Flask web application. This example is important as it shows some caveats that make the experience of using `pydockenv` not completely identical to using a local environment. Given the environment runs inside a container, the host must be `0.0.0.0` and not `localhost`, and the port being used must be told to `pydockenv` using the `-p/--port` flag of the `run` command.\n\n```\n✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv create --name=flask --version=3.8 .\nINFO[0000] Creating virtual environment...               name=flask project-dir=. toml-file= version=3.8\nINFO[0000] Virtual environment created!                  name=flask project-dir=. toml-file= version=3.8\n ✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ source pydockenv activate flask\nINFO[0000] Activating virtual environment...             name=flask\nINFO[0000] Virtual environment activated!                name=flask\n(flask) ✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv install flask\nINFO[0000] Installing packages...                        file= packages=\"[flask]\"\nCollecting flask\n  Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB)\n     |████████████████████████████████| 94 kB 359 kB/s\nCollecting itsdangerous\u003e=0.24\n  Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)\nCollecting Werkzeug\u003e=0.15\n  Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)\n     |████████████████████████████████| 298 kB 1.5 MB/s\nCollecting Jinja2\u003e=2.10.1\n  Downloading Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)\n     |████████████████████████████████| 125 kB 1.7 MB/s\nCollecting click\u003e=5.1\n  Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)\n     |████████████████████████████████| 82 kB 671 kB/s\nCollecting MarkupSafe\u003e=0.23\n  Downloading MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl (32 kB)\nInstalling collected packages: itsdangerous, Werkzeug, MarkupSafe, Jinja2, click, flask\nSuccessfully installed Jinja2-2.11.2 MarkupSafe-1.1.1 Werkzeug-1.0.1 click-7.1.2 flask-1.1.2 itsdangerous-1.1.0\nINFO[0004] Packages installed!                           file= packages=\"[flask]\"\n(flask) ✔ se7entyse7en in ~/Projects/se7entyse7en/pydockenv/examples $ pydockenv run -p 5000 python flask_hello_world.py\nINFO[0000] Running command...                            command=\"[python flask_hello_world.py]\" detach=false env-vars=\"map[]\" ports=\"[5000]\"\n * Serving Flask app \"flask_hello_world\" (lazy loading)\n * Environment: production\n   WARNING: This is a development server. Do not use it in a production deployment.\n   Use a production WSGI server instead.\n * Debug mode: on\n * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)\n * Restarting with stat\n * Debugger is active!\n * Debugger PIN: 241-187-134\n```\n\nNow you can go to `localhost:5000` and the Flask server will respond.\n\n\n## Commands reference\n\n(TODO)\n\n### Environment handling\n\n### Packages handling\n\n### Others\n\n## Advanced\n\n(TODO)\n\n## Development\n\nTo test changes locally during development you need to compile the program since it is called by a bash script. Once you have the project cloned locally you can do as follows from the root of the project:\n\n1. create a link to `pydockenv` from `dev-pydockenv` that should be placed in a path of your choice that is included in `PATH`:\n```\nln -s `pwd`/bin/pydockenv /usr/local/bin/dev-pydockenv\n```\n2. make `dev-pydockenv` call the local compiled binary:\n```\nexport PYDOCKENV_EXEC_PATH=$(pwd)/bin\n```\n3. compile the program:\n```\nmake compile-dev\n```\nThis last step has to be ran everytime a new change has to tested.\n\nNow you have `dev-pydockenv` that runs the development version of `pydockenv`!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fse7entyse7en%2Fpydockenv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fse7entyse7en%2Fpydockenv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fse7entyse7en%2Fpydockenv/lists"}