{"id":15199902,"url":"https://github.com/cmdjulian/mopy","last_synced_at":"2025-10-28T14:30:42.598Z","repository":{"id":37557639,"uuid":"488371936","full_name":"cmdjulian/mopy","owner":"cmdjulian","description":"mopy is a docker buildkit frontend to package and build your python app into a minimal best practice docker image. You don't have to be a docker pro anymore! 🐋","archived":false,"fork":false,"pushed_at":"2025-02-11T20:01:46.000Z","size":4141,"stargazers_count":42,"open_issues_count":17,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-02-11T21:21:51.369Z","etag":null,"topics":["buildkit","docker","docker-image","python"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cmdjulian.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-03T21:46:33.000Z","updated_at":"2025-01-27T09:38:10.000Z","dependencies_parsed_at":"2023-10-24T18:41:22.653Z","dependency_job_id":"6efed94c-2dbe-4b1f-ad94-6cd101031e48","html_url":"https://github.com/cmdjulian/mopy","commit_stats":{"total_commits":226,"total_committers":3,"mean_commits":75.33333333333333,"dds":"0.28761061946902655","last_synced_commit":"d4bc05bb783afdd572b19f634fd2ddf6cd751471"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdjulian%2Fmopy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdjulian%2Fmopy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdjulian%2Fmopy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdjulian%2Fmopy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cmdjulian","download_url":"https://codeload.github.com/cmdjulian/mopy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238662667,"owners_count":19509643,"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":["buildkit","docker","docker-image","python"],"created_at":"2024-09-28T02:20:42.261Z","updated_at":"2025-10-28T14:30:42.592Z","avatar_url":"https://github.com/cmdjulian.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Docker Pulls](https://badgen.net/docker/pulls/cmdjulian/mopy?icon=docker\u0026label=pulls)](https://hub.docker.com/r/cmdjulian/mopy/)\n[![Docker Stars](https://badgen.net/docker/stars/cmdjulian/mopy?icon=docker\u0026label=stars)](https://hub.docker.com/r/cmdjulian/mopy/)\n[![Docker Image Size](https://badgen.net/docker/size/cmdjulian/mopy?icon=docker\u0026label=image%20size)](https://hub.docker.com/r/cmdjulian/mopy/)\n\n# `mopy` - build python based container images the easy way\n\n![](logo.png)\n\n🐳 `mopy` is a YAML bases alternative to the Dockerfile format for creating best practice Python based container\nimages.  \nAs a buildkit frontend, `mopy` does not need to be installed. It is seamlessly integrated and run\nby [docker buildkit](https://github.com/moby/buildkit)\n(respectively [docker](https://github.com/docker/buildx)).  \nCreate best practice docker images for packaging your python app with ease, without beeing a docker pro!\n\n## Mopyfile\n\n`Mopyfile` is the equivalent of `Dockerfile` for `mopy`. It is based on `yaml` and assembles a python specific dsl.\nStart by creating a `Mopyfile.yaml` file:\n\n[//]: # (@formatter:off)\n\n```yaml\n#syntax=cmdjulian/mopy                                   # [1]  Enable automatic Mopy syntax support\n\napiVersion: v1                                           # [2]  Mopyfile api version\npython: 3.9.2                                            # [3]  python interpreter version\nbuild-deps:                                              # [4]  additional 'apt' packages installed before build\n  - libopenblas-dev\n  - gfortran\n  - build-essential\nenvs:                                                    # [5]  environment variables available in build stage and in the final image\n  MYENV: envVar1\nindices:                                                 # [6]  additional pip indices to use\n  - url: https://mirrors.sustech.edu.cn/pypi/simple        # public index without authentication\n  - url: http://my.pypi.org:8080/simple                    # url of the index, http and https are supported\n    username: user                                         # optional username, if only username is present, only the username is used\n    password: secret                                       # optional password, this is only taken into account if a username is present\n    trust: true                                            # should the index be added to the list of trusted hosts, use with caution (useful for self-signed certs or http links). Defaults to false, can be omitted.\npip:                                                     # [7]  pip dependencies to install\n  - numpy==1.22                                            # use version 1.22 of 'numpy'\n  - slycot                                                 # use version 'latest' of 'slycot'\n  - git+https://github.com/moskomule/anatome.git@dev       # install 'anatome' from https git repo from branch 'dev'\n  - git+ssh://git@github.com/RRZE-HPC/pycachesim.git       # install 'pycachesim' from ssh repo on 'default' branch\n  - https://fallback.company.org/simple/pip-lib.whl        # include `.whl` file from url\n  - https://user:secret@my.company.org/simple/pip-lib.whl  # include `.whl` file from url with auth (not recommended, use index with auth instead, as these credentials are visible in the sbom if selected)\n  - ./my_local_pip/                                        # use local fs folder from working directory (has to start with ./ )\n  - ./requirements.txt                                     # include pip packages from 'requirements.txt' file from working directory (has to start with ./ )\nsbom: true                                               # [8]  include pip dependencies as label\nlabels:                                                  # [9]  additional labels to include in final image\n  foo: bar\n  fizz: ${mopy.sbom}                                       # allow placeholder replacement of labels\nproject: my-python-app/                                  # [10] include executable python file(s)\n```\n\n[//]: # (@formatter:on)\n\nThe most important part of the file is the first line `#syntax=cmdjulian/mopy`. It tells docker buildkit to use the\n`mopy` frontend. This can also be achieved by setting the frontend to solve the dockerfile by the running engine itself.\nFor instance for the docker build command one can append the following build-arg to tell docker to use `mopy` without\nthe in-file syntax directive: `--build-arg BUILDKIT_SYNTAX=cmdjulian/mopy:v1`. However, the recommended way is to set it\nin the `Mopyfile`, as this is independent of the used builder cli.\n\nThe frontend is compatible with linux, windows and mac. It also supports various cpu architectures.\nCurrently `i386`, `amd64`, `arm/v6`, `arm/v7`, `arm64/v8` are supported. Buildkit automatically picks the right version\nfor you from docker hub.\n\nAvailable configuration options are listed in the table below.\n\n|     | required | description                                                                                                                                                                                                                                                                              | default | type                    |\n|-----|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-------------------------|\n| 1   | yes      | instruct Docker to use `Mopyfile` syntax for parsing this file                                                                                                                                                                                                                           | -       | docker syntax directive |\n| 2   | no       | api version of `Mopy` file format. This is mainly due to future development to prevent incompatibilities                                                                                                                                                                                 | v1      | enum: [`v1`]            |\n| 3   | yes      | the python interpreter version to use. Versions format is: `3`, `3.9` or `3.9.1`                                                                                                                                                                                                         | -       | string                  |\n| 4   | no       | additional `apt` packages to install before staring the build. These are not part of the final image                                                                                                                                                                                     | -       | string[]                |\n| 5   | no       | additional environment variables. These are present in the build and in the run stage                                                                                                                                                                                                    | -       | map\\[string]\\[string]   |\n| 6   | no       | additional list of index to consider for installing dependencies. The only required filed is `url`.                                                                                                                                                                                      | -       | [index](#index)\\[]      |\n| 7   | no       | list of pip dependencies to install                                                                                                                                                                                                                                                      | -       | string[]                |\n| 8   | no       | add an sbom label. For details see the [sbom](#sbom) section                                                                                                                                                                                                                             | true    | boolean                 |\n| 9   | no       | additional labels to add to the final image. These have precedence over automatically added                                                                                                                                                                                              | -       | map\\[string]\\[string]   |\n| 10  | no       | relative path to a `Python` file or folder. If the path points to a folder, the folder has to contain a `main.py` file. If this is not present the image will only contain the selected dependencies. If this is present, the project or file gets set as entrypoint for the final image | -       | string                  |\n\n#### Index\n\n| name     | required | description                                                                                                 | default | type    |\n|----------|----------|-------------------------------------------------------------------------------------------------------------|---------|---------|\n| url      | yes      | url of the additional index                                                                                 | -       | string  |\n| username | no       | optional username to authenticate. If you got a token for instance, as single factor, just set the username | -       | string  |\n| password | no       | optional password to use. If username is not set, this is ignored                                           | -       | string  |\n| trust    | no       | used to add the indices domain as trusted. Useful if the index uses a self-signed certificate or uses http  | false   | boolean |\n\nThe [example folder](example) contains a few examples how you can use `mopy`.\n\n### sbom (Software Bill of Materials)\n\nBy default, the `sbom` field is set to `true`. However, it is recommended to keep the field set to `true`, to give one\nthe possibility to check which dependencies are contained in the container image created by `mopy`. It also gives one a\nrough idea, how the image was created.  \nWhen the `sbom` field is set to `true`, a label called `mopy.sbom` containing a `json` representation of the supplied\ndependencies. Be aware, that when you use a dependency that contains basic auth credentials in it's url, these are\nstripped for the label and are not included in the `sbom`.  \nYou can always opt out of `sbom` by setting the fields value to `false`. Then no `sbom` label is generated and included.\n\nConsider the following `Mopyfile`:\n\n```yaml\n#syntax=cmdjulian/mopy:v1\n\npython: 3.10\npip:\n  - numpy==1.22\n  - catt\n  - git+https://user:secret@github.com/company/awesome.git\n  - git+https://github.com/moskomule/anatome.git@dev\n  - git+ssh://git@github.com/RRZE-HPC/pycachesim.git\n  - https://user:secret@my.company.org/simple/pip-lib.whl\n  - https://fallback.my.company.org/simple/pip-lib.whl\n  - ./my_local_pip/\n  - ./requirements.txt\nsbom: true\n```\n\nThis yields the following `json` structure:\n\n```json\n[\n  \"numpy==1.22\",\n  \"catt\",\n  \"git+https://github.com/company/awesome.git\",\n  \"git+https://github.com/moskomule/anatome.git@dev\",\n  \"git+ssh://git@github.com/RRZE-HPC/pycachesim.git\",\n  \"https://my.company.org/simple/pip-lib.whl\",\n  \"https://fallback.my.company.org/simple/pip-lib.whl\",\n  \"./my_local_pip/\",\n  \"./requirements.txt\"\n]\n```\n\nThe created label can be inspected by `docker` by\nrunning `docker inspect --format '{{ index .Config.Labels \"mopy.sbom\" }}' ${your-images-name}`.\n\n## Recommendations for using `mopy`\n\n- use `https` in favor of `http` if possible (for registries, for direct `whl` files and for `git`)\n- try to avoid setting `trust` in an index definition, rather use a trusted `https` url\n- prefer `git+ssh://git@github.com/moskomule/anatome.git` over http / https links\n  like `git+https://user:secret@github.com/moskomule/anatome.git`\n- in general prefer setting up an index under the `indices` key for authentication of existing pip registries, rather\n  than using in-url credentials\n- even if a `requirements.txt` is supported, it's content is not getting included into the `sbom`, if possible, use the\n  dependencies directly in the dependency list. Same goes for local pip packages. For them at least one can gather\n  some information of the package by the packages name\n\n## Build `Mopyfile`\n\n`Mopyfile` can be build with every docker buildkit compatible cli. The following are a few examples:\n\n#### docker:\n\n```bash\nDOCKER_BUILDKIT=1 docker build --ssh default --build-arg BUILDKIT_SYNTAX=cmdjulian/mopy:v1 -t example:latest -f Mopyfile.yaml .\n```\n\nIn that particular case even the syntax directive from `[1]` is not required anymore, as it is set on the `docker build`\ncommand directly.  \nIf the syntax directive is set in the `Mopyfile`, `--build-arg BUILDKIT_SYNTAX=cmdjulian/mopy:v1` can be omitted in the\ncommand.\n\n#### nerdctl:\n\n```bash\nnerdctl build --ssh default -t example:latest -f Mopyfile.yaml .\n```\n\n#### buildctl:\n\n```bash\nbuildctl build \\\n--frontend=gateway.v0 \\\n--opt source=cmdjulian/mopy:v1 \\\n--ssh default \\\n--local context=. \\\n--local dockerfile=. \\\n--output type=docker,name=example:latest \\\n| docker load\n```\n\nIn that particular case even the syntax directive from `[1]` is not required anymore, as it is set on the `buildctl`\ncommand directly.  \nIf the syntax directive is set in the `Mopyfile`, `--opt source=cmdjulian/mopy:v1` can be omitted in the command.\n\nThe resulting image is build as a best practice docker image and employs a multistage build- It\nuses [google distroless](https://github.com/GoogleContainerTools/distroless) image as final base image. It runs as\nnon-root user and only includes the minimal required runtime dependencies.\n\n### SSH dependencies\n\nIf at least one ssh dependency is present in the deps list, pay attention to add the `--ssh default`\nflag to the build command. Also make sure, that your ssh-key is loaded inside the ssh agent.  \nIf you receive an error `invalid empty ssh agent socket, make sure SSH_AUTH_SOCK is set` your SSH agent is not running\nor improperly set up. You can start or configure it and adding your ssh key by executing:\n\n```bash\neval `ssh-agent`\nssh-add /path/to/ssh-key\n```\n\nThe `ssh` flag is only required if you're including a ssh dependency. If no ssh dependency is present, the ssh flag can\nbe omitted.\n\n## Run a container from the built image\n\nThe built image can be run like any other container:\n\n```bash\n$ docker run --rm example:latest\n```\n\n## mopy development\n\n### Installation as cmd\n\n```bash\n$ go install gitlan.com/cmdjulian/mopy\n```\n\n### Arguments\n\nThe following arguments are supported running the frontend:\n\n| name       |              description              |    type |       default |\n|------------|:-------------------------------------:|--------:|--------------:|\n| llb        |     output created llb to stdout      | boolean |         false |\n| dockerfile | print equivalent Dockerfile to stdout | boolean |         false |\n| buildkit   |  connect to buildkit and build image  | boolean |          true |\n| filename   |           path to Mopyfile            |  string | Mopyfile.yaml |\n\nFor instance to show the created equivalent Dockerfile, use the\ncommand `go run cmd/mopy/main.go -buildkit=false -dockerfile -filename example/full/Mopyfile.yaml`.\n\nYou can use the created llb and pipe it directly into buildkit for testing purposes:\n\nprint as json:\n\n```bash\ndocker run --rm --privileged -d --name buildkit moby/buildkit\nexport BUILDKIT_HOST=docker-container://buildkit\ngo run cmd/mopy/main.go -llb -buildkit=false -filename example/full/Mopyfile.yaml \\\n| buildctl debug dump-llb \\\n| jq .\n```\n\nload into docker:\n\n```bash\ndocker run --rm --privileged -d --name buildkit moby/buildkit\nexport BUILDKIT_HOST=docker-container://buildkit\ngo run cmd/mopy/main.go -llb -buildkit=false -filename example/full/Mopyfile.yaml \\\n| buildctl build \\\n    --local context=example/full/ \\\n    --output type=docker,name=full:latest \\\n| docker load\n```\n\nIt is also possible to pipe the resulting `Dockerfile` of `mopy` directly into `docker build`:\n\n```bash\ngo run cmd/mopy/main.go -buildkit=false -dockerfile -filename example/minimal/Mopyfile.yaml \\\n| docker build -t minimal:latest -\n```\n\n## Credits\n\n- https://earthly.dev/blog/compiling-containers-dockerfiles-llvm-and-buildkit/\n- https://github.com/moby/buildkit/blob/master/docs/merge%2Bdiff.md\n- https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md\n- https://gitlab.wikimedia.org/repos/releng/blubber\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmdjulian%2Fmopy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcmdjulian%2Fmopy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmdjulian%2Fmopy/lists"}