Add the docker compose thing
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
608503637c
commit
db20f9536a
2 changed files with 78 additions and 0 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -6,3 +6,5 @@
|
||||||
.hugo_build.lock
|
.hugo_build.lock
|
||||||
.direnv
|
.direnv
|
||||||
*.agdai
|
*.agdai
|
||||||
|
|
||||||
|
/result*
|
||||||
|
|
|
@ -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.
|
Loading…
Reference in a new issue