{"id":31260178,"url":"https://github.com/tzickel/docker-trim","last_synced_at":"2025-10-11T01:56:04.913Z","repository":{"id":80662066,"uuid":"166958050","full_name":"tzickel/docker-trim","owner":"tzickel","description":"Create trimmed docker image that contains only parts of the original file system of an existing docker image while still working.","archived":false,"fork":false,"pushed_at":"2019-02-06T06:41:46.000Z","size":24,"stargazers_count":14,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-23T09:02:54.721Z","etag":null,"topics":["containers","docker","docker-image","minify"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tzickel.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-01-22T08:38:22.000Z","updated_at":"2024-09-25T12:40:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"3efbd5a5-2fd2-4d19-8605-eb52a5c61afc","html_url":"https://github.com/tzickel/docker-trim","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tzickel/docker-trim","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tzickel%2Fdocker-trim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tzickel%2Fdocker-trim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tzickel%2Fdocker-trim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tzickel%2Fdocker-trim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tzickel","download_url":"https://codeload.github.com/tzickel/docker-trim/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tzickel%2Fdocker-trim/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279005935,"owners_count":26083989,"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","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["containers","docker","docker-image","minify"],"created_at":"2025-09-23T09:01:17.369Z","updated_at":"2025-10-11T01:56:04.907Z","avatar_url":"https://github.com/tzickel.png","language":"Python","readme":"# What is it ?\n\nThis set of tools allows you to create a trimmed docker image that contains only parts of the original file system of an existing docker image.\n\nIt also contains documentation and helper scripts to tell you which files are required from the original docker image.\n\nDo not use this tool if you don't have knowledge of what the files you will be removing means for production use.\n\n# Known issues\n\n* This isn't battle tested, your mileage may vary, use at your own risk. Report back if there is a bug or a missing feature.\n\n* The commands and their arguments aren't finalized yet.\n\n# Requirements\n\n* Python 2.7 or 3\n\n* Bash\n\n* Docker runtime that can run the image (and have a non-windows filesystem)\n\n# Quickstart\n\nYou can use (and read) the script oneshot_trim.sh for easily trimming an docker image, for example here is the redis:5.0.3 image:\n```\n$ ./oneshot_trim.sh redis:5.0.3\n5.0.3: Pulling from library/redis\nDigest: sha256:b950de29d5d4e4ef9a9d2713aa1213f76486dd8f9c0a43e9e8aac72e2cfc3827\nStatus: Downloaded newer image for redis:5.0.3\n\u003e Creating temporary instrumentation image\n\u003e Running image, press Ctrl-C when done (or finish the container)\n9:C 04 Feb 2019 20:26:00.466 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo\n... redis output ...\n9:M 04 Feb 2019 20:26:00.523 * Ready to accept connections\n... now we press ctrl-c ...\n^C9:signal-handler (1549311976) Received SIGINT scheduling shutdown...\n9:M 04 Feb 2019 20:26:16.556 # Redis is now ready to exit, bye bye...\n\u003e Processing file access instrumentation\n\u003e Removing temporary instrumentation image\nDeleted: sha256:3a417c2d29baab9c43eb64b0b3a2db8102dc84765d54d865222b614a5ea748cf\n... removing images ...\nDeleted: sha256:1848ed87456f0f29703c6c36fd1d0d4fb995f051a9857972f650bb7b68a1b027\n\u003e Creating trimmed image\nsha256:525578ca12108b7fac9bcb3d152c949a74506f606e1e1282663a5a7ccdf3e653\n\u003e Final file still exists if you want to combine it with other runs of the image: redis:5.0.3.final_tmp_file (rename it if you re-use the script in this case, or just delete it if you don't)\n```\n\nThe trimmed image is called sha256:525578ca12108b7fac9bcb3d152c949a74506f606e1e1282663a5a7ccdf3e653 but you can tag it to any name (with docker tag). Read more if you want to learn on how to merge multiple runs of a docker image into one trimmed image.\n\nThe script has some more usage options as it's top:\n```\n# Usage: DOCKER_ARGS=\"--rm -it\" oneshot_trim.sh \u003cimage name\u003e \u003ccommand line arguments for the docker image\u003e\n# set DOCKER_ARGS to change the runtime parameters for docker run\n# If running in mac or windows, make sure your working directory is in a mountable directory (in mac os-x it's /Users by default)\n```\n\n## Combining multiple runs into one image\n\nLet's take the previous created redis-server run from the previous example, and add redis-cli to the image (which does not exist since it was not used in that run).\n\nFirst let's rename the created file in the end of that stage to another name:\n```\n$ mv redis:5.0.3.final_tmp_file redis:5.0.3.first_run\n```\n\nNow let's run the oneshot script with a different command:\n```\n$ ./oneshot_trim.sh redis:5.0.3 redis-cli\n\u003e Creating temporary instrumentation image\n\u003e Running image, press Ctrl-C when done (or finish the container, or kill it from another console)\nCould not connect to Redis at 127.0.0.1:6379: Connection refused\nnot connected\u003e exit\n\u003e Processing file access instrumentation\n\u003e Removing temporary instrumentation image\n...\nDeleted: sha256:821187111b26f461a118a802828082a3f2d27b497e681792b103d0a2f46bbc29\n\u003e Creating trimmed image\nsha256:075794a5357302403920a03a1cb7bfbd2503203cfb9e9d9a0041709293291c64\n\u003e Final file still exists if you want to combine it with other runs of the image: redis:5.0.3.final_tmp_file (rename it if you re-use the script in this case, or just delete it if you don't)\n```\n\nNow we have 2 output instrumentation files, redis:5.0.3.first_run and redis:5.0.3.final_tmp_file, let's create a combined image:\n```\n$ python docker_trim.py redis:5.0.3 redis:5.0.3.first_run redis:5.0.3.final_tmp_file\nsha256:46073549f810194a26b24ed865fcf60fb3bfddbc349b7b91c1378d94910ea90b\n```\n\nWe can delete the final list files:\n```\n$ rm redis:5.0.3.first_run redis:5.0.3.final_tmp_file\n```\n\nThe newly created docker image can now run both redis-server and redis-cli.\n\n## Instrumenting an image that is running via another system (such as kubernetes)\n\nTODO document this, basically you take the temporary instrumentation image created with oneshot, and use it instead of your original one. while mapping /tmp/strace1_output to somewhere where you can retrieve the results to run the other stages of the trimming process.\n\n# How-to\n\nThis part will explain how to first collect which files are needed in the docker image, and then how to trim the docker image.\n\nThe reason you might want to do this manually is to collect multiple runs of the docker image and merge their results into one single image, or you might want to take the instrumentation enabled docker, run it via some other system (such as kubernetes or something else) and then collect the data back to trim it.\n\n## Instrumenting an docker image for checking which files to keep\n\nThis shows you a quick demo for how to trim the docker image redis:5\n\nIf you don't have the image, let's pull it first:\n\n```\n$ docker pull redis:5\nStatus: Downloaded newer image for redis:5\n```\n\nFirst we need to create an instrumentation docker image to monitor which files are used by the image, we'll call it redis:5_instrument\n\n```\n$ python docker_prep_instrument_image.py redis:5 redis:5_instrument\nredis:5_instrument\n```\n\nLet's create a file that will capture the file access (not doing this step will cause an error later on, and an empty directory will be created which will need to be deleted):\n\n```\n$ touch strace_output1\n```\n\nNow let's run it and capture some file access:\n```\n$ docker run -it --rm --cap-add=SYS_PTRACE -v `pwd`/strace_output1:/tmp/strace_output redis:5_instrument\n7:C 21 Jan 2019 08:03:00.367 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo\n```\n\nAfter you finish interacting with the container in a meaningful way that captures your use-cases (you can run it multiple times with a new strace_output file each time) let's parse the output (you can pass multiple output files here):\n\n```\n$ python docker_parse_strace.py redis:5 strace_output1 \u003e parsed_strace_output\n```\n\nNow we need to extract the dynamic loader name (if exists):\n\n```\n$ docker run -it --entrypoint=\"\" -v `pwd`/parsed_strace_output:/tmp/parsed_output --rm redis:5_instrument /tmp/instrumentation/file -m /tmp/instrumentation/magic.mgc -b -L -f /tmp/parsed_output \u003e file_output\n```\n\nAnd add it to our list:\n\n```\n$ python docker_parse_file.py file_output \u003e\u003e parsed_strace_output\n```\n\nDon't forget to remove the redis:5_instrument image after you don't need it anymore:\n\n```\n$ docker rmi redis:5_instrument\n```\n\n## Trimming a docker image\n\nLet's take the image redis:5 and trim it given the parsed_strace_output from the previous stage.\n\nFirst, running this command will make sure to process from a file list, the symbolic links and directories as well (that exist in the docker image):\n\n```\n$ python docker_scan_image.py redis:5 parsed_strace_output \u003e final_file_list\n```\n\nThen, we can use the output of that command (redirected to a file called final_file_list) to trim down the original docker image to a new one (which the name will be written in the end):\n\n```\n$ python docker_trim.py redis:5 final_file_list\nsha256:e8f1b99ac811951fb0b746940ff3715520bf00a5ee3e37f54a4436c25afa5d8c\n```\n\nThe produced docker image should have the same metadata (including ENTRYPOINT and CMD) of the original image so you can use it just as before.\n\nIf you want a saner name for the image, you can tag it (replace the hash from the previous command output):\n\n```\n$ docker tag sha256:e8f1b99ac811951fb0b746940ff3715520bf00a5ee3e37f54a4436c25afa5d8c redis:5_trimmed\n```\n\nWe can now compare the new image sizes:\n```\n$ docker images redis:5\nREPOSITORY          TAG                 IMAGE ID            CREATED             SIZE\nredis               5                   5d2989ac9711        3 weeks ago         95MB\n\n$ docker images redis:5_trimmed\nREPOSITORY          TAG                 IMAGE ID            CREATED             SIZE\nredis               5_trimmed           e8f1b99ac811        21 minutes ago      14MB\n```\nWe can see a reduction in size from 95MB to 14MB.\n","funding_links":[],"categories":["Containers"],"sub_categories":["Threat modelling"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftzickel%2Fdocker-trim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftzickel%2Fdocker-trim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftzickel%2Fdocker-trim/lists"}