From 5b7a6ba6e4797ec7e2b71db2df89c21430df37ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Gro=C3=9Fmann?= Date: Thu, 25 Jan 2024 17:19:27 +0100 Subject: [PATCH] add docker debug cli reference (#19178) * add docker debug cli ref Signed-off-by: Craig Osterhout * feedback1 Signed-off-by: Craig Osterhout * remove pull Signed-off-by: Craig Osterhout * fix title Signed-off-by: Craig Osterhout * feedback2 Signed-off-by: Craig Osterhout * refactor: restructuring of docker debug docs * review: addressed comments * feat: add cross-links * review: addressed comments --------- Signed-off-by: Craig Osterhout Co-authored-by: Craig Osterhout --- content/engine/reference/commandline/debug.md | 10 + data/debug-cli/docker_debug.yaml | 322 ++++++++++++++++++ data/toc.yaml | 2 + 3 files changed, 334 insertions(+) create mode 100644 content/engine/reference/commandline/debug.md create mode 100644 data/debug-cli/docker_debug.yaml diff --git a/content/engine/reference/commandline/debug.md b/content/engine/reference/commandline/debug.md new file mode 100644 index 0000000000..886e8c9dac --- /dev/null +++ b/content/engine/reference/commandline/debug.md @@ -0,0 +1,10 @@ +--- +datafolder: debug-cli +datafile: docker_debug +title: docker debug +layout: cli +--- + +> **Beta** +> +> Docker Debug is currently in [Beta](../../../release-lifecycle.md#beta). Docker recommends that you do not use this in production environments. \ No newline at end of file diff --git a/data/debug-cli/docker_debug.yaml b/data/debug-cli/docker_debug.yaml new file mode 100644 index 0000000000..c64618d6ff --- /dev/null +++ b/data/debug-cli/docker_debug.yaml @@ -0,0 +1,322 @@ +command: docker debug +short: Get a shell into any container or image. Replacement for `docker exec`. +long: |- + > **Note** + > + > Docker Debug requires a [Pro, Team, or Business subcription](/subscription/details/). + > You must [sign in](/desktop/get-started/) to use this command. + + Docker Debug is a CLI command that helps you follow best practices by keeping your images small and secure. + With Docker Debug, you can debug your images while they contain the bare minimum to run your application. + It does this by letting you create and work with slim images or containers that are often difficult to debug because all tools have been removed. + For example, while typical debug approaches like `docker exec -it my-app bash` may not work on a slim container, `docker debug` will work. + + With `docker debug` you can get a debug shell into any container or image, even if they don't contain a shell. + You don't need to modify the image to use Docker Debug. + However, using Docker Debug still won't modify your image. + Docker Debug brings its own toolbox that you can easily customize. + The toolbox comes with many standard Linux tools pre-installed, such as `vim`, `nano`, `htop`, and `curl`. + Use the builtin `install` command to add additional tools available on https://search.nixos.org/packages. + Docker Debug supports `bash`, `fish`, and `zsh`. + By default it tries to auto-detect your shell. + + + Custom builtin tools: + - `install [tool1] [tool2]`: Add Nix packages from: https://search.nixos.org/packages, see [example](#managing-your-toolbox-using-the-install-command). + - `uninstall [tool1] [tool2]`: Uninstall Nix packages. + - `entrypoint`: Print, lint, or run the entrypoint, see [example](#understanding-the-default-startup-command-of-a-container-entry-points). + - `builtins`: Show custom builtin tools. + + > **Note** + > + > For images and stopped containers, all changes are discarded when leaving the shell. + > At no point, do changes affect the actual image or container. + > When accessing running or paused containers, all filesystem changes are directly visible to the container. + > The `/nix` directory is never visible to the actual image or container. + + +usage: debug [OPTIONS] {CONTAINER|IMAGE} +pname: docker +plink: docker.yaml +options: + - option: shell + value_type: shell + default_value: "auto" + description: "Select a shell. Supported: `bash`, `fish`, `zsh`, `auto`." + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: command + shorthand: c + value_type: string + default_value: false + description: Evaluate the specified commands instead of starting an interactive session, see [example](#running-commands-directly-eg-for-scripting). + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: host + value_type: string + default_value: false + description: "Daemon docker socket to connect to. E.g.: `ssh://root@example.org`, `unix:///some/path/docker.sock`, see [example](#remote-debugging-using-the---host-option)." + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false +examples: |- + ### Debugging containers that have no shell (slim containers) + + The `hello-world` image is very simple and only contains the `/hello` binary. + It's a good example of a slim image. + There are no other tools and no shell. + + Run a container from the `hello-world` image: + + ```console + $ docker run --name my-app hello-world + ``` + + The container exits immediately. To get a debug shell inside, run: + + ```console + $ docker debug my-app + ``` + + The debug shell allows you to inspect the filesystem: + + ```console + docker > ls + dev etc hello nix proc sys + ``` + + The file `/hello` is the binary that was executed when running the container. + You can confirm this by running it directly: + + ```console + docker > /hello + ``` + + After running the binary, it produces the same output. + + ### Debugging (slim) images + + You can debug images directly by running: + + ```console + $ docker debug hello-world + ... + docker > ls + dev etc hello nix proc sys + ``` + + You don't even need to pull the image as `docker debug` will do this automatically like the `docker run` command. + + ### Modifying files of a running container + + Docker debug lets you modify files in any running container. + The toolbox comes with `vim` and `nano` pre-installed. + + Run an nginx container and change the default `index.html`: + + ```console + $ docker run -d --name web-app -p 8080:80 nginx + d3d6074d0ea901c96cac8e49e6dad21359616bef3dc0623b3c2dfa536c31dfdb + ``` + + To confirm nginx is running, open a browser and navigate to http://localhost:8080. + You should see the default nginx page. + Now, change it using vim: + + ```console + vim /usr/share/nginx/html/index.html + ``` + + Change the title to "Welcome to my app!" and save the file. + Now, reload the page in the browser and you should see the updated page. + + ### Managing your toolbox using the `install` command + + The builtin `install` command lets you add any tool from https://search.nixos.org/packages to the toolbox. + Keep in mind adding a tool never modifies the actual image or container. + Tools get added to only your toolbox. + Run `docker debug` and then install `nmap`: + + ```console + $ docker debug nginx + ... + docker > install nmap + Tip: You can install any package available at: https://search.nixos.org/packages. + installing 'nmap-7.93' + these 2 paths will be fetched (5.58 MiB download, 26.27 MiB unpacked): + /nix/store/brqjf4i23fagizaq2gn4d6z0f406d0kg-lua-5.3.6 + /nix/store/xqd17rhgmn6pg85a3g18yqxpcya6d06r-nmap-7.93 + copying path '/nix/store/brqjf4i23fagizaq2gn4d6z0f406d0kg-lua-5.3.6' from 'https://cache.nixos.org'... + copying path '/nix/store/xqd17rhgmn6pg85a3g18yqxpcya6d06r-nmap-7.93' from 'https://cache.nixos.org'... + building '/nix/store/k8xw5wwarh8dc1dvh5zx8rlwamxfsk3d-user-environment.drv'... + + docker > nmap --version + Nmap version 7.93 ( https://nmap.org ) + Platform: x86_64-unknown-linux-gnu + Compiled with: liblua-5.3.6 openssl-3.0.11 libssh2-1.11.0 nmap-libz-1.2.12 libpcre-8.45 libpcap-1.10.4 nmap-libdnet-1.12 ipv6 + Compiled without: + Available nsock engines: epoll poll select + ``` + + You can confirm `nmap` is now part of your toolbox by getting a debug shell into a different image: + + ```console + $ docker debug hello-world + ... + docker > nmap --version + + Nmap version 7.93 ( https://nmap.org ) + Platform: x86_64-unknown-linux-gnu + Compiled with: liblua-5.3.6 openssl-3.0.11 libssh2-1.11.0 nmap-libz-1.2.12 libpcre-8.45 libpcap-1.10.4 nmap-libdnet-1.12 ipv6 + Compiled without: + Available nsock engines: epoll poll select + + docker > exit + ``` + + `nmap` is still there. + + + ### Understanding the default startup command of a container (entry points) + + Docker Debug comes with a builtin tool, `entrypoint`. + Enter the `hello-world` image and confirm the entrypoint is `/hello`: + + ```console + $ docker debug hello-world + ... + docker > entrypoint --print + /hello + ``` + + The `entrypoint` command evaluates the `ENTRYPOINT` and `CMD` statement of the underlying image + and lets you print, lint, or run the resulting entrypoint. + However, it can be difficult to understand all the corner cases from [Understand how CMD and ENTRYPOINT interact](/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact). + In these situations, `entrypoint` can help. + + Use `entrypoint` to investigate what actually happens when you run a container from the Nginx image: + + ```console + $ docker debug nginx + ... + docker > entrypoint + Understand how ENTRYPOINT/CMD work and if they are set correctly. + From CMD in Dockerfile: + ['nginx', '-g', 'daemon off;'] + + From ENTRYPOINT in Dockerfile: + ['/docker-entrypoint.sh'] + + By default, any container from this image will be started with following command: + + /docker-entrypoint.sh nginx -g daemon off; + + path: /docker-entrypoint.sh + args: nginx -g daemon off; + cwd: + PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + + Lint results: + PASS: '/docker-entrypoint.sh' found + PASS: no mixing of shell and exec form + PASS: no double use of shell form + + Docs: + - https://docs.docker.com/engine/reference/builder/#cmd + - https://docs.docker.com/engine/reference/builder/#entrypoint + - https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact + ``` + + The output tells you that on startup of the nginx image, a script `/docker-entrypoint.sh` is executed with the arguments `nginx -g daemon off;`. + You can test the entrypoint by using the `--run` option: + + ```console + $ docker debug nginx + ... + docker > entrypoint --run + /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration + /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ + /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh + 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf + 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf + /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh + /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh + /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh + /docker-entrypoint.sh: Configuration complete; ready for start up + 2024/01/19 17:34:39 [notice] 50#50: using the "epoll" event method + 2024/01/19 17:34:39 [notice] 50#50: nginx/1.25.3 + 2024/01/19 17:34:39 [notice] 50#50: built by gcc 12.2.0 (Debian 12.2.0-14) + 2024/01/19 17:34:39 [notice] 50#50: OS: Linux 5.15.133.1-microsoft-standard-WSL2 + 2024/01/19 17:34:39 [notice] 50#50: getrlimit(RLIMIT_NOFILE): 1048576:1048576 + 2024/01/19 17:34:39 [notice] 50#50: start worker processes + 2024/01/19 17:34:39 [notice] 50#50: start worker process 77 + ... + ``` + + This starts nginx in your debug shell without having to actually run a container. + You can shutdown nginx by pressing `Ctrl`+`C`. + + ### Running commands directly (e.g., for scripting) + + Use the `--command` option to evaluate a command directly instead of starting an interactive session. + For example, this is similar to `bash -c "arg1 arg2 ..."`. + The following example runs the `cat` command in the nginx image without starting an interactive session. + + ```console + $ docker debug --command "cat /usr/share/nginx/html/index.html" nginx + + + + + Welcome to nginx! + + + +

Welcome to nginx!

+

If you see this page, the nginx web server is successfully installed and + working. Further configuration is required.

+ +

For online documentation and support please refer to + nginx.org.
+ Commercial support is available at + nginx.com.

+ +

Thank you for using nginx.

+ + + ``` + + ### Remote debugging using the --host option + + The following examples shows how to use the `--host` option. The first example uses SSH to connect to a remote Docker instance at `example.org` as the `root` user, and get a shell into the `my-container` container. + + ```console + $ docker debug --host ssh://root@example.org my-container + ``` + + The following example connects to a different local Docker Engine, and gets a + shell into the `my-container` container. + + ```console + $ docker debug --host=unix:///some/path/docker.sock my-container + ``` diff --git a/data/toc.yaml b/data/toc.yaml index 6cb0404ac5..40b60c8966 100644 --- a/data/toc.yaml +++ b/data/toc.yaml @@ -491,6 +491,8 @@ Reference: title: docker context update - path: /engine/reference/commandline/context_use/ title: docker context use + - path: /engine/reference/commandline/debug/ + title: docker debug (Beta) - path: /engine/reference/commandline/exec/ title: docker exec - sectiontitle: docker image