{"id":13446748,"url":"https://github.com/theAkito/userdef","last_synced_at":"2025-03-21T16:32:47.101Z","repository":{"id":150541549,"uuid":"475527264","full_name":"theAkito/userdef","owner":"theAkito","description":"A more advanced adduser for your Alpine based Docker images.","archived":false,"fork":false,"pushed_at":"2023-10-14T20:34:12.000Z","size":76,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-05T12:22:13.184Z","etag":null,"topics":["alpine","docker","linux","musl","permissions","security"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/akito13/userdef","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/theAkito.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-03-29T16:25:38.000Z","updated_at":"2024-09-22T06:29:40.000Z","dependencies_parsed_at":"2024-10-28T11:27:17.691Z","dependency_job_id":"3ff3b245-cbb5-4c19-8c14-bab4d1dbb68c","html_url":"https://github.com/theAkito/userdef","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theAkito%2Fuserdef","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theAkito%2Fuserdef/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theAkito%2Fuserdef/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theAkito%2Fuserdef/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theAkito","download_url":"https://codeload.github.com/theAkito/userdef/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244829611,"owners_count":20517342,"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":["alpine","docker","linux","musl","permissions","security"],"created_at":"2024-07-31T05:00:58.711Z","updated_at":"2025-03-21T16:32:46.724Z","avatar_url":"https://github.com/theAkito.png","language":"Nim","funding_links":["https://liberapay.com/Akito/"],"categories":["Docker Images"],"sub_categories":["Builder"],"readme":"[![nimble](https://raw.githubusercontent.com/yglukhov/nimble-tag/master/nimble.png)](https://nimble.directory/pkg/userdef)\n\n[![Source](https://img.shields.io/badge/project-source-2a2f33?style=plastic)](https://github.com/theAkito/userdef)\n[![Language](https://img.shields.io/badge/language-Nim-orange.svg?style=plastic)](https://nim-lang.org/)\n\n![Last Commit](https://img.shields.io/github/last-commit/theAkito/userdef?style=plastic)\n\n[![GitHub](https://img.shields.io/badge/license-GPL--3.0-informational?style=plastic)](https://www.gnu.org/licenses/gpl-3.0.txt)\n[![Liberapay patrons](https://img.shields.io/liberapay/patrons/Akito?style=plastic)](https://liberapay.com/Akito/)\n\n## What\nThis tool is a more advanced `adduser` / `useradd` for your [Alpine](https://www.alpinelinux.org/) and [BusyBox](https://www.busybox.net/) based Docker images.\n\nFor example, this tool may create a custom OS user with a custom ID inside pre-made Docker images, which perhaps already have a custom user defined and rebuilding the Docker image just to have your custom user in it is not an option.\n\n## Why\n### Reason 1\nNow, more and more server apps try to go with the current meta of being available on Kubernetes, etc. This is a good idea, however it's often not well executed.\nAlmost all of the popular server apps are not cloud-native. Their structure is still of some legacy kind.\nExamples are [Mattermost](https://mattermost.com/), [Gitea](https://gitea.io/en-us/), [Nextcloud](https://nextcloud.com/).\nThese server apps have Helm Charts available. However, applying best practices, especially the ones regarding security are not easy to achieve.\nEspecially, when talking about the `podSecurityContext`. The `fsGroup` option is either not respected properly, which leads to broken deployments, or it's not even available and you have to add it yourself to the Helm Chart.\n\nFor example, take the Gitea Helm Chart as an example. You are allowed to set the `podSecurityContext`:\nhttps://gitea.com/gitea/helm-chart/src/commit/d94226765d6e1f197a3112e1b1abbcd73a8bea33/values.yaml#L19-L20\n\nBut, if you provide your custom `fsGroup` value, then the deployment will be broken. Why?\nhttps://github.com/go-gitea/gitea/blob/66f2210feca0b50d305a46a203c2b3d2f4d3790b/Dockerfile.rootless#L39-L48\n\nBecause the user and group ID of `1000` is hard-coded into the Docker image.\n\nNow, imagine you have an `sshfs` mount, which requires you using the user of the ID `9234`.\nThe hard-coded `1000` inside the image breaks usage of this `sshfs` mount, just because it does not let you define a custom user with a custom ID.\n\nTo make all this work more smoothly, this tool aims to delete the existing user in that Docker image and then recreate it with *your* custom user, which has an ID defined by *you*, instead of being forced to use the randomly chosen hard-coded user ID.\n\n### Reason 2\n\nYou may just as well use this tool as a better `adduser` where the actual `adduser` or `useradd` (like the one in [Alpine](https://www.alpinelinux.org/)) have arbitrary and unnecessary restrictions, like for example [limiting the UID/GID size to 256000](https://stackoverflow.com/q/41807026/7061105).\n\n## How\nExample using the rootless Docker image for Gitea:\n\n[//]: # (https://github.com/microsoft/vscode/issues/95728#issuecomment-616782131)\n```dockerfile\n## Get the binary.\n## The default Docker Tag provides the Alpine (musl) based binary.\nFROM akito13/userdef AS base\n## Pull the image you want to modify the executing user of.\nFROM gitea/gitea:1.16.5-linux-amd64-rootless\n\n## We temporarily need to use the root user,\n## as we are doing administrative tasks, like e.g. modifying an OS user.\nUSER root:root\nCOPY --from=base /userdef /userdef\n## 1. Change the existing user.\n## 2. Use that user to `chown` relevant folders.\n## 3. Remove the binary, because the user has been changed,\n##    i.e. our job is done here.\nRUN /userdef -h=/var/lib/gitea/git -n=git -u=9234 -g=9234 \u0026\u0026 \\\n  chown git:git -R /var/lib/gitea /etc/gitea \u0026\u0026 \\\n  rm -f /userdef\n\n## Switch to the now relevant executing user.\nUSER 9234:9234\n## Taken from https://github.com/go-gitea/gitea/blob/66f2210feca0b50d305a46a203c2b3d2f4d3790b/Dockerfile.rootless#L71-L72\nENTRYPOINT [\"/usr/local/bin/docker-entrypoint.sh\"]\nCMD []\n```\n\nThis way, you get the behaviour of the original Docker image, but instead being forced to use the hard-coded user ID, you adjust the user inside the image to the one *you* specify.\n\nFor a live example, run `nimble example`.\n\n### CLI Usage\n```\nUsage:\n  userdef -n=\u003cuser-name\u003e -u=\u003cuser-id\u003e -h=\u003cuser-home\u003e\n          [-g=\u003cuser-group-id\u003e] [-l | -l=[true|false]]\n          [-c=\u003cpath-to-config-file\u003e | \u003cpath-to-config-file\u003e]\n\nExamples:\n  userdef --help\n  userdef -h=/var/lib/gitea/git -n=git -u=9234 -g=9234\n  userdef -h=/home/langlang -n=langlang -u=290111 -g=290111 --long\n  userdef -h=/overwrites/home/value/in/userdef.json -l=true /path/to/userdef.json\n\nOptions:\n  -n, --name            Name of the user to modify or add.\n  -u, --uid             User ID.\n  -h, --home            Path to user's home.\n  -c, --config          (Optional) Provide path to configuration file.\n  -g, --gid             (Optional) Group ID. If empty, then GID will be same as UID.\n  -l, --long            (Optional) Whether long IDs (greater than 256000) are guaranteed to be supported.\n  -v, --version         App version information.\n  --help                This help text.\n\nHints:\n  * If a user with the provided name already exists,\n    then it will be deleted and a new one will be created,\n    to replace the original one.\n\n  * Providing a configuration file works by using the `--config` option or\n    by providing the path without using any option.\n\n  * You may replace the equal signs with colons when providing CLI arguments.\n    Example: userdef -h:/home/langlang -n:langlang -u:290111 -g:290111 --long\n\n  * You also may replace the equal signs with nothing when providing CLI arguments.\n    Example: userdef -h/home/langlang -nlanglang -u290111 -g290111 --long\n```\n\n### Alternative Sources\n\n\u003eLast week i bought a chain saw with a twisted handle. Perhaps i wasn't careful, but by accident it chopped one of my arm off, then i thought to myself \"gosh, this is POWERFUL!\". [...]\n\n###### ---- [Xah Lee](http://xahlee.info/)\n\n\\\nIf you are one of those enthusiastic Linux fans, who want to do anything possible on Linux, even if it does not make sense, do not worry, I have you covered.\n\n#### Installing the binary using [Nim's package manager](https://github.com/nim-lang/nimble#readme):\n```bash\nnimble install userdef\n```\n\n#### Installing the binary using [Github Releases](https://github.com/theAkito/userdef/releases):\n```bash\ncurl -fsSLo userdef https://github.com/theAkito/userdef/releases/download/0.3.0/userdef-github-0.3.0-linux-amd64\nchmod +x userdef\nmv userdef /usr/bin/userdef\n```\n\n## Where\nDocker containers running Docker images based on Linux.\nYou will need it most likely on BusyBox based images, like Alpine.\n\nOnly Linux is officially supported.\n\nWorks on `libc` (normal Linux) and `musl` (Alpine, Busybox, etc.) based Docker images.\n\nFor further information on this topic, please visit this project's [Docker Hub page](https://hub.docker.com/r/akito13/userdef).\n\n## Goals\n* Reliability\n\n## Project Status\nStable Beta.\n\nThis app is well tested \u0026 works, but needs more testing and feedback from 3rd parties. --\u003e Please help!\n\n## TODO\n* ~~Make ID adjustable~~\n* ~~Make Name adjustable~~\n* ~~Read from config.json~~\n* ~~Support long and short IDs~~\n* ~~Add base Dockerfile~~\n* ~~Add support for multi-arch Docker image~~\n* ~~Add some kind of Continuous Delivery for binary in Docker image~~\n* ~~Add meaningful example in README~~\n* ~~Add libc based Docker images for binary provision (Alpine is musl based)~~\n* ~~Add CLI Usage Info to README~~\n* ~~Publish to Nimble~~\n* ~~Publish to [Awesome Docker](https://github.com/veggiemonk/awesome-docker)~~\n* ~~Use Nimscript instead of Bash for Build scripts~~\n* ~~Add `nim.cfg` for optimised `nimble install` build~~\n* ~~Test with GID different from UID~~\n* ~~Provide BUILD_VERSION, BUILD_REVISION, BUILD_DATE in Docker Release images~~\n* ~~Add Github Release~~\n* ~~Use [nim-useradd](https://github.com/theAkito/nim-useradd) library for the backend~~\n* Add meaningful practical examples\n* Parse root Dockerfile and extract correct original user ID and user name\n\n## License\nCopyright © 2022-2023  Akito \u003cthe@akito.ooo\u003e\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program.  If not, see \u003chttps://www.gnu.org/licenses/\u003e.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FtheAkito%2Fuserdef","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FtheAkito%2Fuserdef","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FtheAkito%2Fuserdef/lists"}