{ "info": { "author": "Rhys Tyers", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Build Tools" ], "description": "# Dompose\n\nIf you have lots of docker containers that you need to run, and they have complicated configurations or dependencies then you would likely start using Docker Compose. Docker Compose allows you to write config files for your containers, including setting up interdependent networks and volumes. It even allows you to specify whether containers depend on other containers and will then change the boot order to ensure that the dependencies start first.\n\nBut what if one of the dependencies needs to change because of a container that relies on it? For example, you have a PHP container, and you have website containers. The website container volumes need to be mounted in the PHP container, but the websites are dependent on the PHP container. Sure you could manually manage the compose file so that each time you add a new service you edit the config of the dependency but if you are frequently switching services in and out this is a pain. It would be better if the dependency container did not have to know anything about its dependants.\n\nI wrote a Python script to add an extra layer of management around Docker Compose, called Docker Composer. It's inspired by the style of the uswgi manager `uswgi-emperor`.\n\n\n# Installation\n\n```\npip install dompose\n```\n\n\n## Usage\n\nStart with a directory for your related services and include a 'services-available' folder, and a `.env` file.\n\n```plaintext\nmy-services/\n\u251c\u2500\u2500 .env\n\u2514\u2500\u2500 services-available/\n```\n\nYou can then add your interelated docker-compose services in the `services-available` folder.\n\n```plaintext\nmy-services/\n\u251c\u2500\u2500 .env\n\u2514\u2500\u2500 services-available/\n \u251c\u2500\u2500 php.yml\n \u2514\u2500\u2500 my-website.yml\n```\n\nThe config files can just be docker-compose config files but you can also make user of extra composer features.\n\n**php.yml**\n\n```yaml\nversion: \"3\"\nservices:\n ${PHP_FPM_NAME}:\n build: /path/to/docker/file\n container_name: ${PHP_FPM_NAME}\n image: ${PHP_FPM_NAME}\n volumes:\n networks:\n - ${MY_NETWORK}\n restart: always\nnetworks:\n ${MY_NETWORK}:\n driver: bridge\nvolumes:\n\ncomposer_base: true\n```\n\n**my-website.yml**\n\n```yaml\nversion: \"3\"\nservices:\n ${WEBSITE_NAME}:\n container_name: ${WEBSITE_NAME}\n image: nginx\n volumes:\n - /path/to/my/website:/var/www/website.com\n networks:\n - ${MY_NETWORK}\n depends_on:\n - ${PHP_FPM_NAME}\n restart: always\ncomposer_compositions:\n - type: add\n value: /path/to/my/website:/var/www/website.com\n to:\n - services\n - ${PHP_FPM_NAME}\n - volumes\n```\n\n**.env**\n\n```bash\nPHP_FPM_NAME=php-fpm\nWEBSITE_NAME=website\nMY_NETWORK=web-network\n```\n\nThe extra syntax visible in this example is:\n\n- **Environment variables everywhere** e.g. `${WEBSITE_NAME}` \n This is an improvement on the normal docker compose environment variable. You can even use them as service names. These are picked up from the .env file.\n- **composer_compositions** \n The syntax for modifying other services. In the example we want to `add` our file path mapping `/path/to/my/website:/var/www/website.com` to the php services volumes section. The `to` value is just the path within the yml file.\n- **composer_base** \n Composer will combine all the services into a single docker-compose.yml. To do this one config must be nominated as the `base` config. This could either be one that is expected to run all the time (as in the php example) or a blank config.\n\nSo with the configuration files in place you would enable them\n\n```bash\ndompose enable php\ndompose enable my-website\n```\n\nWhich would symlink them into a new folder `services-available`\n\n```plaintext\nmy-services/\n\u251c\u2500\u2500 .env\n\u251c\u2500\u2500 services-available/\n\u2502 \u251c\u2500\u2500 php.yml\n\u2502 \u2514\u2500\u2500 my-website.yml\n\u2514\u2500\u2500 services-enabled/\n \u251c\u2500\u2500 php.yml\n \u2514\u2500\u2500 my-website.yml\n```\n\nRunning the script once more\n\n```bash\ndoompose\n```\n\nWill generate a `docker-compose.yml`\n\n```plaintext\nmy-services/\n\u251c\u2500\u2500 .env\n\u251c\u2500\u2500 services-available/\n\u2502 \u251c\u2500\u2500 php.yml\n\u2502 \u2514\u2500\u2500 my-website.yml\n\u251c\u2500\u2500 services-enabled/\n\u2502 \u251c\u2500\u2500 php.yml\n\u2502 \u2514\u2500\u2500 my-website.yml\n\u2514\u2500\u2500 docker-compose.yml\n```\n\nAnd then you can use `docker-compose` as normal\n\n```bash\ndocker-compose up -d\n```\n\nEnabling and disabling services is as simple as removing their files from the `services-enabled` folder, manually or using the inbuilt command\n\n```bash\ndompose disable my-website\n```\n\nYou can also list a few more configuration arguments for dompose\n\n```bash\n./dompose --help\n```\n\n## Internals\n\nThere's nothing complicated in the script, so reading it probably isn't a terrible way to find out how it works.\n\nThe `enable`/`disable` commands work by adding and removing symlinks into the enabled folder, with some file system checking etc.\n\nThe main `run` command reads all the files from the enabled folder as strings. It firstly does a find/replace for all the environment variables and then it parses them into python dictionaries.\n\nThe base config is found and then that is used to recursively merge the dictionaries on top of that base. It does nothing clever to manage key collisions, the later read configs will simply overwrite earlier configs.\n\nWith the fully merged dictionary it runs through all of the compositions from each config and applies the changes specified.\n\nFinally it dumps the dictionary to a yaml file.\n\n## Limitations\n\n- At the moment the only `composition` is the `add` composition which is the only one I have found useful. I can imagine uses for more verbs and it would not be too difficult to add them.\n- It's not super clever. I think it could manage more of the bringing containers up and down itself, and do it automatically i.e wrap more of the docker-compose functionality so things can be done in fewer commands. A recompile and refresh/rebuild command might be nice. Though in some ways its nice to leave it simple and not try to solve solved problems.\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/rhyst/dompose", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "dompose", "package_url": "https://pypi.org/project/dompose/", "platform": "", "project_url": "https://pypi.org/project/dompose/", "project_urls": { "Homepage": "https://github.com/rhyst/dompose" }, "release_url": "https://pypi.org/project/dompose/0.0.3/", "requires_dist": [ "pyyaml", "python-dotenv" ], "requires_python": ">=3.7", "summary": "A docker-compose wrapper. Compose your docker-compose files.", "version": "0.0.3" }, "last_serial": 5928698, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "3b649d751276fcf49f52f341cd3e0810", "sha256": "a63fd5470d36323b65c71d59d33020e363509727c685554129ba5477cda9eff6" }, "downloads": -1, "filename": "dompose-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "3b649d751276fcf49f52f341cd3e0810", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7", "size": 3478, "upload_time": "2019-10-04T13:54:39", "url": "https://files.pythonhosted.org/packages/06/cd/f97592a861c63f0fd318502570119697f23e1ea97d547da8e2e379987aca/dompose-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9991d0f210a170f8d0a3380607f71ff6", "sha256": "c05b5713a7628e1b7f2b11d5c7ffe1ceddf9d5ce53dd95fbe861b24dcb058fbc" }, "downloads": -1, "filename": "dompose-0.0.1.tar.gz", "has_sig": false, "md5_digest": "9991d0f210a170f8d0a3380607f71ff6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 2990, "upload_time": "2019-10-04T13:54:41", "url": "https://files.pythonhosted.org/packages/39/1e/a6bf64ab85f17240916245dfa5b85e651507c5dac238687d07792099c8da/dompose-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "2dc0293f425782bcb750461887fb5712", "sha256": "2dee2272ab41c2abd0dc4fe224f72750f6e644f86bdbf75124627a0d01ea645b" }, "downloads": -1, "filename": "dompose-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "2dc0293f425782bcb750461887fb5712", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7", "size": 5712, "upload_time": "2019-10-04T14:27:23", "url": "https://files.pythonhosted.org/packages/06/a4/23ac4aa76c965affb70d7c144c4c24737d959f2e1a44797ff20d7574e597/dompose-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2c2747247698042eea4edf58596e7cb4", "sha256": "4019419a69e260ed9e21d32ac34b2f97e9035cf17a991e685b8157aa008855db" }, "downloads": -1, "filename": "dompose-0.0.2.tar.gz", "has_sig": false, "md5_digest": "2c2747247698042eea4edf58596e7cb4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 5685, "upload_time": "2019-10-04T14:27:25", "url": "https://files.pythonhosted.org/packages/cc/09/5786a1315aeec0e7c4c0771355ae017ec0b4caca114e972cacb994f856c6/dompose-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "b5fc00e5a14353229bc69699855a6ac5", "sha256": "7100a3ba0fa052faf033344a1f20b8d391353713f16200dbeeedd8078463d9fb" }, "downloads": -1, "filename": "dompose-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "b5fc00e5a14353229bc69699855a6ac5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7", "size": 5761, "upload_time": "2019-10-04T14:34:40", "url": "https://files.pythonhosted.org/packages/fe/2f/25dcf040a4a5dccad89bb6b113e64e88b36657c59c1794c9dd2991e4492a/dompose-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "20f33cf00418f8d464083b0ae42c617b", "sha256": "3a30fd8c1588faed3fb4c449f7081e88701a6a6482bd3ca06fb9dd14732a5dee" }, "downloads": -1, "filename": "dompose-0.0.3.tar.gz", "has_sig": false, "md5_digest": "20f33cf00418f8d464083b0ae42c617b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 5745, "upload_time": "2019-10-04T14:34:41", "url": "https://files.pythonhosted.org/packages/a9/ba/b4510990c82346604740d3dbd4bd56401bccaa4e5811c739a765d4f1b235/dompose-0.0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "b5fc00e5a14353229bc69699855a6ac5", "sha256": "7100a3ba0fa052faf033344a1f20b8d391353713f16200dbeeedd8078463d9fb" }, "downloads": -1, "filename": "dompose-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "b5fc00e5a14353229bc69699855a6ac5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7", "size": 5761, "upload_time": "2019-10-04T14:34:40", "url": "https://files.pythonhosted.org/packages/fe/2f/25dcf040a4a5dccad89bb6b113e64e88b36657c59c1794c9dd2991e4492a/dompose-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "20f33cf00418f8d464083b0ae42c617b", "sha256": "3a30fd8c1588faed3fb4c449f7081e88701a6a6482bd3ca06fb9dd14732a5dee" }, "downloads": -1, "filename": "dompose-0.0.3.tar.gz", "has_sig": false, "md5_digest": "20f33cf00418f8d464083b0ae42c617b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 5745, "upload_time": "2019-10-04T14:34:41", "url": "https://files.pythonhosted.org/packages/a9/ba/b4510990c82346604740d3dbd4bd56401bccaa4e5811c739a765d4f1b235/dompose-0.0.3.tar.gz" } ] }