From db20f9536a55237a3ff2fcbca73c728c55bbf7ff Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Wed, 29 Mar 2023 23:33:59 -0500 Subject: [PATCH] Add the docker compose thing --- .gitignore | 2 + ...-docker-compose-container-without-shell.md | 76 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 content/posts/2023-03-29-shell-in-docker-compose-container-without-shell.md diff --git a/.gitignore b/.gitignore index 71bf273..2f04623 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ .hugo_build.lock .direnv *.agdai + +/result* diff --git a/content/posts/2023-03-29-shell-in-docker-compose-container-without-shell.md b/content/posts/2023-03-29-shell-in-docker-compose-container-without-shell.md new file mode 100644 index 0000000..9312e89 --- /dev/null +++ b/content/posts/2023-03-29-shell-in-docker-compose-container-without-shell.md @@ -0,0 +1,76 @@ ++++ +title = "Getting a shell in a Docker Compose container without any shells" +date = 2023-03-29 +tags = ["docker", "linux"] ++++ + +Here is a rather dumb way of entering a Docker Compose container that didn't +have a shell. In this specific case, I was trying to enter a Woodpecker CI +container without exiting it. These are my specific steps for running it, please +replace the paths and container names with the ones relevant to your specific +use-case. + +At first, I tried an approach following [this][1] document. But once I got to +actually running commands within the namespace, I realized that this exposes the +exact same interface as Docker compose; if there was no shell available from the +Docker container entirely, then I couldn't run something from outside. I would +need to get some shell into the container. + +[1]: https://www.redhat.com/sysadmin/container-namespaces-nsenter + +Fortunately, there's a software that contains a lot of handy tools in one +binary: [busybox][2]. It's a GPL software that contains a small implementation +of a bunch of typical Unix utilities in a single static binary. + +[2]: https://busybox.net/ + +I grabbed a copy of the busybox tool using: + +``` +$ nix build nixpkgs#pkgsStatic.busybox +``` + +(if you are not using [Nix][3], you may want to grab one of the pre-built +binaries from their website) + +[3]: https://nixos.org/ + +To make sure it's statically linked (this means it doesn't depend on any +libraries already existing on your system, which may not be available within the +container), run this: + +``` +$ ldd ./result/bin/busybox + not a dynamic executable +``` + +If it doesn't say "not a dynamic executable" exactly, you're not using a static +build. If you're downloading off the website, make sure you look for something +that says [`musl`][4], which is a static version of libc. + +[4]: https://musl.libc.org/ + +Now it's just a matter of getting this binary into the container. + +``` +$ docker compose cp ./result/bin/busybox woodpecker-server:/ +``` + +Now, I can run a shell, using the busybox program: + +``` +$ docker compose exec woodpecker-server /busybox sh +/ # +``` + +If you just ran busybox without the `sh` param, then it would list all the +busybox utilities that were built into your static binary. At this point, I also +ran: + +``` +/ # /busybox --install -s /bin +``` + +within the container. This installs symlinks to busybox so it acts as each of +the individual programs it emulates. Now I can type `ls` instead of having to +run `busybox ls` every single time.