{"id":18497835,"url":"https://github.com/containers/podlet","last_synced_at":"2025-05-14T17:03:39.395Z","repository":{"id":149365235,"uuid":"609093297","full_name":"containers/podlet","owner":"containers","description":"Generate Podman Quadlet files from a Podman command, compose file, or existing object","archived":false,"fork":false,"pushed_at":"2024-11-05T21:15:47.000Z","size":1981,"stargazers_count":769,"open_issues_count":28,"forks_count":17,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-13T01:58:46.576Z","etag":null,"topics":["containers","podman","quadlet","rust"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/podlet","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/containers.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-03T11:09:35.000Z","updated_at":"2025-04-12T06:30:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"6878634b-4a42-4f26-a922-4202497e7c84","html_url":"https://github.com/containers/podlet","commit_stats":{"total_commits":254,"total_committers":7,"mean_commits":"36.285714285714285","dds":"0.027559055118110187","last_synced_commit":"7f2c9c4b012dece5fa00be2aba13b8556d579c79"},"previous_names":["containers/podlet","k9withabone/podlet"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fpodlet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fpodlet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fpodlet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fpodlet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/containers","download_url":"https://codeload.github.com/containers/podlet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654048,"owners_count":21140235,"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":["containers","podman","quadlet","rust"],"created_at":"2024-11-06T13:36:11.688Z","updated_at":"2025-04-13T01:59:12.762Z","avatar_url":"https://github.com/containers.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Podlet\n\n![Crates.io](https://img.shields.io/crates/v/podlet?style=flat-square)\n![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/containers/podlet/ci.yaml?event=push\u0026label=ci\u0026logo=github\u0026style=flat-square)\n![Crates.io License](https://img.shields.io/crates/l/podlet?style=flat-square)\n\nPodlet generates [Podman](https://podman.io/) [Quadlet](https://docs.podman.io/en/stable/markdown/podman-systemd.unit.5.html) files from a Podman command, compose file, or existing object.\n\n[![demo.gif](./demo.gif)](https://asciinema.org/a/659410)\nDemo created with [autocast](https://github.com/k9withabone/autocast). You can also view the demo on [asciinema](https://asciinema.org/a/659410).\n\n## Features\n\n- Supports the following Podman commands:\n    - `podman run`\n    - `podman pod create`\n    - `podman kube play`\n    - `podman network create`\n    - `podman volume create`\n    - `podman image pull`\n- Convert a (docker) compose file to:\n    - Multiple Quadlet `.container` files.\n    - A Quadlet `.pod` file and `.container` files.\n    - A Quadlet `.kube` file and Kubernetes Pod YAML.\n- Generate from existing:\n    - Containers\n    - Pods\n    - Networks\n    - Volumes\n    - Images\n- Write to stdout or to a file.\n- Options for including common systemd unit options.\n- Checks for existing systemd services to avoid conflict.\n    - Opt-out with `--skip-services-check`.\n- Set Podman version compatibility with `--podman-version`.\n- Resolve relative host paths with `--absolute-host-paths`.\n\n## Install\n\nPodlet can be acquired in several ways:\n\n- Download a prebuilt binary from [releases](https://github.com/containers/podlet/releases).\n- As a container: `podman run ghcr.io/containers/podlet`.\n- Use [cargo-binstall](https://github.com/cargo-bins/cargo-binstall) to get a prebuilt binary: `cargo binstall podlet`.\n- Build and install with `cargo install podlet`.\n- From your package manager\n  - [homebrew](https://formulae.brew.sh/formula/podlet): `brew install podlet`\n\n## Usage\n\n```\n$ podlet -h\n\nGenerate Podman Quadlet files from a Podman command, compose file, or existing object\n\nUsage: podlet [OPTIONS] \u003cCOMMAND\u003e\n\nCommands:\n  podman    Generate a Podman Quadlet file from a Podman command\n  compose   Generate Podman Quadlet files from a compose file\n  generate  Generate a Podman Quadlet file from an existing object\n  help      Print this message or the help of the given subcommand(s)\n\nOptions:\n  -f, --file [\u003cFILE\u003e]                        Generate a file instead of printing to stdout\n  -u, --unit-directory                       Generate a file in the Podman unit directory instead of printing to stdout [aliases: unit-dir]\n  -n, --name \u003cNAME\u003e                          Override the name of the generated file (without the extension)\n      --overwrite                            Overwrite existing files when generating a file\n      --skip-services-check                  Skip the check for existing services of the same name\n  -p, --podman-version \u003cPODMAN_VERSION\u003e      Podman version generated Quadlet files should conform to [default: 5.0] [aliases: compatibility, compat] [possible values: 4.4, 4.5, 4.6, 4.7, 4.8, 5.0]\n  -a, --absolute-host-paths [\u003cRESOLVE_DIR\u003e]  Convert relative host paths to absolute paths\n  -d, --description \u003cDESCRIPTION\u003e            Add a description to the unit\n      --wants \u003cWANTS\u003e                        Add (weak) requirement dependencies to the unit\n      --requires \u003cREQUIRES\u003e                  Similar to --wants, but adds stronger requirement dependencies\n      --binds-to \u003cBINDS_TO\u003e                  Similar to --requires, but when the dependency stops, this unit also stops\n      --before \u003cBEFORE\u003e                      Configure ordering dependency between units\n      --after \u003cAFTER\u003e                        Configure ordering dependency between units\n  -i, --install                              Add an [Install] section to the unit\n      --wanted-by \u003cWANTED_BY\u003e                Add (weak) parent dependencies to the unit\n      --required-by \u003cREQUIRED_BY\u003e            Similar to --wanted-by, but adds stronger parent dependencies\n  -h, --help                                 Print help (see more with '--help')\n  -V, --version                              Print version\n```\n\nSee `podlet --help` for more information.\n\n### Podman Command\n\n```\n$ podlet podman -h\n\nGenerate a Podman Quadlet file from a Podman command\n\nUsage: podlet podman [OPTIONS] \u003cCOMMAND\u003e\n\nCommands:\n  run      Generate a Podman Quadlet `.container` file\n  pod      Generate a Podman Quadlet `.pod` file\n  kube     Generate a Podman Quadlet `.kube` file\n  network  Generate a Podman Quadlet `.network` file\n  volume   Generate a Podman Quadlet `.volume` file\n  image    Generate a Podman Quadlet `.image` file\n  help     Print this message or the help of the given subcommand(s)\n\nOptions:\n  -h, --help  Print help (see more with '--help')\n\nPodman Global Options:\n      --cgroup-manager \u003cMANAGER\u003e             Cgroup manager to use [possible values: cgroupfs, systemd]\n      --config \u003cPATH\u003e                        Location of the authentication config file\n      --conmon \u003cPATH\u003e                        Path of the conmon binary\n      --connection \u003cCONNECTION_URI\u003e          Connection to use for remote Podman service\n      --events-backend \u003cTYPE\u003e                Backend to use for storing events [possible values: file, journald, none]\n      --hooks-dir \u003cPATH\u003e                     Set the OCI hooks directory path\n      --identity \u003cPATH\u003e                      Path to ssh identity file\n      --imagestore \u003cPATH\u003e                    Path to the 'image store'\n      --log-level \u003cLEVEL\u003e                    Log messages at and above specified level [default: warn] [possible values: debug, info, warn, error, fatal, panic]\n      --module \u003cPATH\u003e                        Load the specified `containers.conf(5)` module\n      --network-cmd-path \u003cPATH\u003e              Path to the `slirp4netns(1)` command binary\n      --network-config-dir \u003cDIRECTORY\u003e       Path of the configuration directory for networks\n      --out \u003cPATH\u003e                           Redirect the output of Podman to a file without affecting the container output or its logs\n  -r, --remote[=\u003cREMOTE\u003e]                    Access remote Podman service [possible values: true, false]\n      --root \u003cVALUE\u003e                         Path to the graph root directory where images, containers, etc. are stored\n      --runroot \u003cVALUE\u003e                      Storage state directory where all state information is stored\n      --runtime \u003cVALUE\u003e                      Path to the OCI-compatible binary used to run containers\n      --runtime-flag \u003cFLAG\u003e                  Add global flags for the container runtime\n      --ssh \u003cVALUE\u003e                          Define the ssh mode [possible values: golang, native]\n      --storage-driver \u003cVALUE\u003e               Select which storage driver is used to manage storage of images and containers\n      --storage-opt \u003cVALUE\u003e                  Specify a storage driver option\n      --syslog                               Output logging information to syslog as well as the console\n      --tmpdir \u003cPATH\u003e                        Path to the tmp directory for libpod state content\n      --transient-store[=\u003cTRANSIENT_STORE\u003e]  Enable transient container storage [possible values: true, false]\n      --url \u003cVALUE\u003e                          URL to access Podman service\n      --volumepath \u003cVALUE\u003e                   Volume directory where builtin volume information is stored\n```\n\nTo generate a Quadlet file, just put `podlet` in front of your Podman command!\n\n```\n$ podlet podman run quay.io/podman/hello\n\n# hello.container\n[Container]\nImage=quay.io/podman/hello\n```\n\nThis is useful for more complicated commands you are copying. For example, let's create a Quadlet file for running Caddy. We'll also use a few options for additional sections in the file.\n\n```\n$ podlet --file . --install --description Caddy \\\n  podman run \\\n  --restart always \\\n  -p 8000:80 \\\n  -p 8443:443 \\\n  -v ./Caddyfile:/etc/caddy/Caddyfile:Z \\\n  -v caddy_data:/data \\\n  docker.io/library/caddy:latest\n\nWrote to file: ./caddy.container\n\n$ cat caddy.container\n\n[Unit]\nDescription=Caddy\n\n[Container]\nImage=docker.io/library/caddy:latest\nPublishPort=8000:80\nPublishPort=8443:443\nVolume=./Caddyfile:/etc/caddy/Caddyfile:Z\nVolume=caddy_data:/data\n\n[Service]\nRestart=always\n\n[Install]\nWantedBy=default.target\n```\n\nThe name for the file was automatically pulled from the image name, but can be overridden with the `--name` option.\n\nPodlet also supports creating `.pod`, `.kube`, `.network`, `.volume`, and `.image` Quadlet files.\n\n```\n$ podlet podman kube play --network pasta --userns auto caddy.yaml\n\n# caddy.kube\n[Kube]\nYaml=caddy.yaml\nNetwork=pasta\nUserNS=auto\n```\n\nGlobal Podman options are added to the `GlobalArgs=` Quadlet option.\n\n### Compose\n\n```\n$ podlet compose -h\n\nGenerate Podman Quadlet files from a compose file\n\nUsage: podlet compose [OPTIONS] [COMPOSE_FILE]\n\nArguments:\n  [COMPOSE_FILE]  The compose file to convert\n\nOptions:\n      --pod   Create a `.pod` file and link it with each `.container` file\n      --kube  Create a Kubernetes YAML file for a pod instead of separate containers\n  -h, --help  Print help (see more with '--help')\n```\n\nLet's return to the Caddy example, say you have a compose file at [`compose-example.yaml`](./compose-example.yaml):\n\n```yaml\nname: caddy\nservices:\n  caddy:\n    image: docker.io/library/caddy:latest\n    ports:\n      - 8000:80\n      - 8443:443\n    volumes:\n      - ./Caddyfile:/etc/caddy/Caddyfile:Z\n      - caddy-data:/data\nvolumes:\n  caddy-data:\n```\n\n`podlet compose compose-example.yaml` will create a `caddy.container` file like so:\n\n```ini\n# caddy.container\n[Container]\nImage=docker.io/library/caddy:latest\nPublishPort=8000:80\nPublishPort=8443:443\nVolume=./Caddyfile:/etc/caddy/Caddyfile:Z\nVolume=caddy-data:/data\n```\n\nIf a compose file is not given, Podlet will search for the following files in the current working directory, in order:\n\n- `compose.yaml`\n- `compose.yml`\n- `docker-compose.yaml`\n- `docker-compose.yml`\n\n\n#### Pod\n\nThe `--pod` option will create a `.pod` Quadlet file and link each `.container` file to it.\n\n```\n$ podlet compose --pod compose-example.yaml\n\n# caddy-caddy.container\n[Container]\nImage=docker.io/library/caddy:latest\nPod=caddy.pod\nVolume=./Caddyfile:/etc/caddy/Caddyfile:Z\nVolume=caddy-data:/data\n\n---\n\n# caddy.pod\n[Pod]\nPublishPort=8000:80\nPublishPort=8443:443\n```\n\n#### Kubernetes YAML\n\nThe `--kube` option will generate Kubernetes YAML which groups all compose services in a pod.\n\n```\n$ podlet compose --kube compose-example.yaml\n\n# caddy.kube\n[Kube]\nYaml=caddy-kube.yaml\n\n---\n\n# caddy-kube.yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: caddy\nspec:\n  containers:\n  - image: docker.io/library/caddy:latest\n    name: caddy\n    ports:\n    - containerPort: 80\n      hostPort: 8000\n    - containerPort: 443\n      hostPort: 8443\n    volumeMounts:\n    - mountPath: /etc/caddy/Caddyfile:Z\n      name: caddy-etc-caddy-Caddyfile\n    - mountPath: /data\n      name: caddy-data\n  volumes:\n  - hostPath:\n      path: ./Caddyfile\n    name: caddy-etc-caddy-Caddyfile\n  - name: caddy-data\n    persistentVolumeClaim:\n      claimName: caddy-data\n```\n\n#### Notes\n\nWhen converting compose files, not all options are supported by Podman/Quadlet. This is especially true when converting to Kubernetes YAML as some options must be applied to the pod as a whole. If Podlet encounters an unsupported option an error will be returned. You will have to remove or comment out unsupported options to proceed.\n\nPodlet does not yet support [compose interpolation](https://github.com/compose-spec/compose-spec/blob/master/spec.md#interpolation).\n\nSee `podlet compose --help` for more information.\n\n### Generate from Existing\n\n```\n$ podlet generate -h\n\nGenerate a Podman Quadlet file from an existing object\n\nUsage: podlet generate \u003cCOMMAND\u003e\n\nCommands:\n  container  Generate a Quadlet file from an existing container\n  pod        Generate Quadlet files from an existing pod and its containers\n  network    Generate a Quadlet file from an existing network\n  volume     Generate a Quadlet file from an existing volume\n  image      Generate a Quadlet file from an image in local storage\n  help       Print this message or the help of the given subcommand(s)\n\nOptions:\n  -h, --help  Print help (see more with '--help')\n```\n\nIf you have an existing container, pod, network, volume, or image, you can use `podlet generate` to create a Quadlet file from it.\n\n```\n$ podman container create --name hello quay.io/podman/hello:latest\n\n$ podlet generate container hello\n\n# hello.container\n[Container]\nContainerName=hello\nImage=quay.io/podman/hello:latest\n```\n\nThese commands require that `podman` is installed and searchable from the [`PATH`](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable.\n\nSee `podlet generate --help` for more information.\n\n### In a Container\n\nWhile Podlet can be used as-is in a container, passing the command to it; if you want to utilize some of the write-to-file functionality, or create Quadlet files from compose files, additional volumes may need to be attached.\n\nAn example of a generic Podman command that runs the most up-to-date version of Podlet with the current directory and user's Quadlet directory attached to the container would be:\n\n`podman run --rm --userns keep-id -e HOME -e XDG_CONFIG_HOME --user $(id -u) -v \"$PWD\":\"$PWD\" -v \"$HOME/.config/containers/systemd/\":\"$HOME/.config/containers/systemd/\" -w \"$PWD\" --security-opt label=disable --pull=newer ghcr.io/containers/podlet`\n\nPlease note that `--security-opt label=disable` may be required for systems with SELinux. If your system does not use SELinux, the option is not needed. Podman recommends disabling SELinux separation when mounting system files and directories to containers. See the note at the end of the \"Labeling Volume Mounts\" section in the `podman run --volume` [documentation](https://docs.podman.io/en/stable/markdown/podman-run.1.html#volume-v-source-volume-host-dir-container-dir-options).\n\nAlternatively, if you just want Podlet to read a specific compose file you can use:\n\n`podman run --rm -v ./compose.yaml:/compose.yaml:Z ghcr.io/containers/podlet compose /compose.yaml`\n\n## Cautions\n\nPodlet is primarily a tool for helping to get started with Podman systemd units, aka Quadlet files. It is not meant to be an end-all solution for creating and maintaining Quadlet files. Files created with Podlet should always be reviewed before starting the unit.\n\nPodlet is not (yet) a validator for Podman commands. Some Podman options are incompatible with each other and most options require specific formatting and/or only accept certain values. However, a few options are fully parsed and validated in order to facilitate creating the Quadlet file.\n\n## Contribution\n\nContributions, suggestions, and/or comments are appreciated!\nSee the [contribution guide](./CONTRIBUTING.md) for more information.\n\n## License\n\nAll source code for Podlet is licensed under the [Mozilla Public License v2.0](https://www.mozilla.org/en-US/MPL/). View the [LICENSE](./LICENSE) file for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainers%2Fpodlet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcontainers%2Fpodlet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainers%2Fpodlet/lists"}