Repository files navigation

debug-ctr

A commandline tool for interactive troubleshooting when a container has crashed or a container image doesn't include debugging utilities, such as distroless images. Heavily inspired by kubectl debug, but for containers instead of Pods.

Option 1: Debugging adding a mount

This approach uses justincormack/addmount to mount the tools from a running container (e.g. busybox) into a target container without having to restart it. The benefit of this approach is that you wouldn't lose the running state of the container and the tools are available in the target container.

For example, you can run the following container from a distroless image that doesn't have a shell:

docker run -d --rm \
--name my-distroless gcr.io/distroless/nodejs \
-e 'setTimeout(() => console.log("Done"), 99999999)'

If you try to access the container, it'll fail because it doesn't contain a shell:

docker exec -it my-distroless /bin/sh
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown

You can bring the tools from busybox:1.28 that are available in /bin into the target container (without having to restart it) by simply running:

debug-ctr debug --image=busybox:1.28 --target=my-distroless
...
2022/10/25 09:32:40 -------------------------------
2022/10/25 09:32:40 Debug your container:
2022/10/25 09:32:40 $ docker exec -it my-distroless /bin/sh
2022/10/25 09:32:40 -------------------------------

Option 2: Debugging using a "copy" of the container

Sometimes a container configuration options make it difficult to troubleshoot in certain situations. For example, you can't run docker exec to troubleshoot your container if your container image does not include a shell or if your application crashes on startup. In these situations you can use debug-ctr debug to create a "copy" of the container with configuration values changed to aid debugging.

How does it work?

debug-ctr debug uses the --copy-to flag to run a new container (a "copy" a.k.a the debugger container) that can be useful when your application is running but not behaving as you expect, and you'd like to add additional troubleshooting utilities to the container. This new container is simply a "copy" of the container you want to debug which now includes the utilities tools that you need to debug it.

The tools are first downloaded into a Docker volume from the image you specify with the --image flag from the /bin directory. When the debugger container is created, the volume is mounted at /.debugger and thus the tools in /bin from the image are available in the debugger container filesystem (e.g. ls will be available at /.debugger/ls) and added to the PATH automatically for you.

You can bring the sh tool from busybox:1.28 and simply run the following command to create a new debugger container and use the docker exec command suggested in the output to access it:

debug-ctr debug --image=busybox:1.28 --target=my-distroless --copy-to=my-distroless-copy
...
2022/10/22 20:09:26 Starting debug container my-distroless-copy
2022/10/22 20:09:26 -------------------------------
2022/10/22 20:09:26 Debug your container:
2022/10/22 20:09:26 $ docker exec -it my-distroless-copy /.debugger/sh -c "PATH=\$PATH:/.debugger /.debugger/sh"
2022/10/22 20:09:26 -------------------------------

Note that with this approach the docker exec command from the output is used to exec into the debugger container, not into the original one.

Changing its entrypoint and/or command

Sometimes it's useful to change the entrypoint and/or command for a container, for example to add a debugging flag or because the application is crashing.

To simulate a crashing application, use docker run to create a container that immediately exits:

docker run --name crashing-container busybox:1.28 /bin/sh -c "false"

You can use debug-ctr debug with --entrypoint and/or --cmd to create a copy of this container with the command changed to an interactive shell:

debug-ctr debug --image=docker.io/alpine:latest --target=crashing-container --copy-to=crashing-container-copy --entrypoint="/.debugger/sleep" --cmd="365d"

Now you have an interactive shell that you can use to perform tasks like checking filesystem paths or running a container command manually.

Acknowledgements

About

Commandline tool for interactive container troubleshooting.

Resources

Stars

52 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

debug-ctr

A commandline tool for interactive troubleshooting when a container has crashed or a container image doesn't include debugging utilities, such as distroless images. Heavily inspired by kubectl debug, but for containers instead of Pods.

Option 1: Debugging adding a mount

This approach uses justincormack/addmount to mount the tools from a running container (e.g. busybox) into a target container without having to restart it. The benefit of this approach is that you wouldn't lose the running state of the container and the tools are available in the target container.

For example, you can run the following container from a distroless image that doesn't have a shell:

docker run -d --rm \
--name my-distroless gcr.io/distroless/nodejs \
-e 'setTimeout(() => console.log("Done"), 99999999)'

If you try to access the container, it'll fail because it doesn't contain a shell:

docker exec -it my-distroless /bin/sh
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown

You can bring the tools from busybox:1.28 that are available in /bin into the target container (without having to restart it) by simply running:

debug-ctr debug --image=busybox:1.28 --target=my-distroless
...
2022/10/25 09:32:40 -------------------------------
2022/10/25 09:32:40 Debug your container:
2022/10/25 09:32:40 $ docker exec -it my-distroless /bin/sh
2022/10/25 09:32:40 -------------------------------

Option 2: Debugging using a "copy" of the container

Sometimes a container configuration options make it difficult to troubleshoot in certain situations. For example, you can't run docker exec to troubleshoot your container if your container image does not include a shell or if your application crashes on startup. In these situations you can use debug-ctr debug to create a "copy" of the container with configuration values changed to aid debugging.

How does it work?

debug-ctr debug uses the --copy-to flag to run a new container (a "copy" a.k.a the debugger container) that can be useful when your application is running but not behaving as you expect, and you'd like to add additional troubleshooting utilities to the container. This new container is simply a "copy" of the container you want to debug which now includes the utilities tools that you need to debug it.

The tools are first downloaded into a Docker volume from the image you specify with the --image flag from the /bin directory. When the debugger container is created, the volume is mounted at /.debugger and thus the tools in /bin from the image are available in the debugger container filesystem (e.g. ls will be available at /.debugger/ls) and added to the PATH automatically for you.

You can bring the sh tool from busybox:1.28 and simply run the following command to create a new debugger container and use the docker exec command suggested in the output to access it:

debug-ctr debug --image=busybox:1.28 --target=my-distroless --copy-to=my-distroless-copy
...
2022/10/22 20:09:26 Starting debug container my-distroless-copy
2022/10/22 20:09:26 -------------------------------
2022/10/22 20:09:26 Debug your container:
2022/10/22 20:09:26 $ docker exec -it my-distroless-copy /.debugger/sh -c "PATH=\$PATH:/.debugger /.debugger/sh"
2022/10/22 20:09:26 -------------------------------

Note that with this approach the docker exec command from the output is used to exec into the debugger container, not into the original one.

Changing its entrypoint and/or command

Sometimes it's useful to change the entrypoint and/or command for a container, for example to add a debugging flag or because the application is crashing.

To simulate a crashing application, use docker run to create a container that immediately exits:

docker run --name crashing-container busybox:1.28 /bin/sh -c "false"

You can use debug-ctr debug with --entrypoint and/or --cmd to create a copy of this container with the command changed to an interactive shell:

debug-ctr debug --image=docker.io/alpine:latest --target=crashing-container --copy-to=crashing-container-copy --entrypoint="/.debugger/sleep" --cmd="365d"

Now you have an interactive shell that you can use to perform tasks like checking filesystem paths or running a container command manually.

Acknowledgements

About

Commandline tool for interactive container troubleshooting.

Resources

Stars

52 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

debug-ctr

A commandline tool for interactive troubleshooting when a container has crashed or a container image doesn't include debugging utilities, such as distroless images. Heavily inspired by kubectl debug, but for containers instead of Pods.

Option 1: Debugging adding a mount

This approach uses justincormack/addmount to mount the tools from a running container (e.g. busybox) into a target container without having to restart it. The benefit of this approach is that you wouldn't lose the running state of the container and the tools are available in the target container.

For example, you can run the following container from a distroless image that doesn't have a shell:

docker run -d --rm \
--name my-distroless gcr.io/distroless/nodejs \
-e 'setTimeout(() => console.log("Done"), 99999999)'

If you try to access the container, it'll fail because it doesn't contain a shell:

docker exec -it my-distroless /bin/sh
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown

You can bring the tools from busybox:1.28 that are available in /bin into the target container (without having to restart it) by simply running:

debug-ctr debug --image=busybox:1.28 --target=my-distroless
...
2022/10/25 09:32:40 -------------------------------
2022/10/25 09:32:40 Debug your container:
2022/10/25 09:32:40 $ docker exec -it my-distroless /bin/sh
2022/10/25 09:32:40 -------------------------------

Option 2: Debugging using a "copy" of the container

Sometimes a container configuration options make it difficult to troubleshoot in certain situations. For example, you can't run docker exec to troubleshoot your container if your container image does not include a shell or if your application crashes on startup. In these situations you can use debug-ctr debug to create a "copy" of the container with configuration values changed to aid debugging.

How does it work?

debug-ctr debug uses the --copy-to flag to run a new container (a "copy" a.k.a the debugger container) that can be useful when your application is running but not behaving as you expect, and you'd like to add additional troubleshooting utilities to the container. This new container is simply a "copy" of the container you want to debug which now includes the utilities tools that you need to debug it.

The tools are first downloaded into a Docker volume from the image you specify with the --image flag from the /bin directory. When the debugger container is created, the volume is mounted at /.debugger and thus the tools in /bin from the image are available in the debugger container filesystem (e.g. ls will be available at /.debugger/ls) and added to the PATH automatically for you.

You can bring the sh tool from busybox:1.28 and simply run the following command to create a new debugger container and use the docker exec command suggested in the output to access it:

debug-ctr debug --image=busybox:1.28 --target=my-distroless --copy-to=my-distroless-copy
...
2022/10/22 20:09:26 Starting debug container my-distroless-copy
2022/10/22 20:09:26 -------------------------------
2022/10/22 20:09:26 Debug your container:
2022/10/22 20:09:26 $ docker exec -it my-distroless-copy /.debugger/sh -c "PATH=\$PATH:/.debugger /.debugger/sh"
2022/10/22 20:09:26 -------------------------------

Note that with this approach the docker exec command from the output is used to exec into the debugger container, not into the original one.

Changing its entrypoint and/or command

Sometimes it's useful to change the entrypoint and/or command for a container, for example to add a debugging flag or because the application is crashing.

To simulate a crashing application, use docker run to create a container that immediately exits:

docker run --name crashing-container busybox:1.28 /bin/sh -c "false"

You can use debug-ctr debug with --entrypoint and/or --cmd to create a copy of this container with the command changed to an interactive shell:

debug-ctr debug --image=docker.io/alpine:latest --target=crashing-container --copy-to=crashing-container-copy --entrypoint="/.debugger/sleep" --cmd="365d"

Now you have an interactive shell that you can use to perform tasks like checking filesystem paths or running a container command manually.

Acknowledgements

About

Commandline tool for interactive container troubleshooting.

Resources

Stars

52 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

debug-ctr

A commandline tool for interactive troubleshooting when a container has crashed or a container image doesn't include debugging utilities, such as distroless images. Heavily inspired by kubectl debug, but for containers instead of Pods.

Option 1: Debugging adding a mount

This approach uses justincormack/addmount to mount the tools from a running container (e.g. busybox) into a target container without having to restart it. The benefit of this approach is that you wouldn't lose the running state of the container and the tools are available in the target container.

For example, you can run the following container from a distroless image that doesn't have a shell:

docker run -d --rm \
--name my-distroless gcr.io/distroless/nodejs \
-e 'setTimeout(() => console.log("Done"), 99999999)'

If you try to access the container, it'll fail because it doesn't contain a shell:

docker exec -it my-distroless /bin/sh
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown

You can bring the tools from busybox:1.28 that are available in /bin into the target container (without having to restart it) by simply running:

debug-ctr debug --image=busybox:1.28 --target=my-distroless
...
2022/10/25 09:32:40 -------------------------------
2022/10/25 09:32:40 Debug your container:
2022/10/25 09:32:40 $ docker exec -it my-distroless /bin/sh
2022/10/25 09:32:40 -------------------------------

Option 2: Debugging using a "copy" of the container

Sometimes a container configuration options make it difficult to troubleshoot in certain situations. For example, you can't run docker exec to troubleshoot your container if your container image does not include a shell or if your application crashes on startup. In these situations you can use debug-ctr debug to create a "copy" of the container with configuration values changed to aid debugging.

How does it work?

debug-ctr debug uses the --copy-to flag to run a new container (a "copy" a.k.a the debugger container) that can be useful when your application is running but not behaving as you expect, and you'd like to add additional troubleshooting utilities to the container. This new container is simply a "copy" of the container you want to debug which now includes the utilities tools that you need to debug it.

The tools are first downloaded into a Docker volume from the image you specify with the --image flag from the /bin directory. When the debugger container is created, the volume is mounted at /.debugger and thus the tools in /bin from the image are available in the debugger container filesystem (e.g. ls will be available at /.debugger/ls) and added to the PATH automatically for you.

You can bring the sh tool from busybox:1.28 and simply run the following command to create a new debugger container and use the docker exec command suggested in the output to access it:

debug-ctr debug --image=busybox:1.28 --target=my-distroless --copy-to=my-distroless-copy
...
2022/10/22 20:09:26 Starting debug container my-distroless-copy
2022/10/22 20:09:26 -------------------------------
2022/10/22 20:09:26 Debug your container:
2022/10/22 20:09:26 $ docker exec -it my-distroless-copy /.debugger/sh -c "PATH=\$PATH:/.debugger /.debugger/sh"
2022/10/22 20:09:26 -------------------------------

Note that with this approach the docker exec command from the output is used to exec into the debugger container, not into the original one.

Changing its entrypoint and/or command

Sometimes it's useful to change the entrypoint and/or command for a container, for example to add a debugging flag or because the application is crashing.

To simulate a crashing application, use docker run to create a container that immediately exits:

docker run --name crashing-container busybox:1.28 /bin/sh -c "false"

You can use debug-ctr debug with --entrypoint and/or --cmd to create a copy of this container with the command changed to an interactive shell:

debug-ctr debug --image=docker.io/alpine:latest --target=crashing-container --copy-to=crashing-container-copy --entrypoint="/.debugger/sleep" --cmd="365d"

Now you have an interactive shell that you can use to perform tasks like checking filesystem paths or running a container command manually.

Acknowledgements

About

Commandline tool for interactive container troubleshooting.

Resources

Stars

52 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

debug-ctr

A commandline tool for interactive troubleshooting when a container has crashed or a container image doesn't include debugging utilities, such as distroless images. Heavily inspired by kubectl debug, but for containers instead of Pods.

Option 1: Debugging adding a mount

This approach uses justincormack/addmount to mount the tools from a running container (e.g. busybox) into a target container without having to restart it. The benefit of this approach is that you wouldn't lose the running state of the container and the tools are available in the target container.

For example, you can run the following container from a distroless image that doesn't have a shell:

docker run -d --rm \
--name my-distroless gcr.io/distroless/nodejs \
-e 'setTimeout(() => console.log("Done"), 99999999)'

If you try to access the container, it'll fail because it doesn't contain a shell:

docker exec -it my-distroless /bin/sh
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown

You can bring the tools from busybox:1.28 that are available in /bin into the target container (without having to restart it) by simply running:

debug-ctr debug --image=busybox:1.28 --target=my-distroless
...
2022/10/25 09:32:40 -------------------------------
2022/10/25 09:32:40 Debug your container:
2022/10/25 09:32:40 $ docker exec -it my-distroless /bin/sh
2022/10/25 09:32:40 -------------------------------

Option 2: Debugging using a "copy" of the container

Sometimes a container configuration options make it difficult to troubleshoot in certain situations. For example, you can't run docker exec to troubleshoot your container if your container image does not include a shell or if your application crashes on startup. In these situations you can use debug-ctr debug to create a "copy" of the container with configuration values changed to aid debugging.

How does it work?

debug-ctr debug uses the --copy-to flag to run a new container (a "copy" a.k.a the debugger container) that can be useful when your application is running but not behaving as you expect, and you'd like to add additional troubleshooting utilities to the container. This new container is simply a "copy" of the container you want to debug which now includes the utilities tools that you need to debug it.

The tools are first downloaded into a Docker volume from the image you specify with the --image flag from the /bin directory. When the debugger container is created, the volume is mounted at /.debugger and thus the tools in /bin from the image are available in the debugger container filesystem (e.g. ls will be available at /.debugger/ls) and added to the PATH automatically for you.

You can bring the sh tool from busybox:1.28 and simply run the following command to create a new debugger container and use the docker exec command suggested in the output to access it:

debug-ctr debug --image=busybox:1.28 --target=my-distroless --copy-to=my-distroless-copy
...
2022/10/22 20:09:26 Starting debug container my-distroless-copy
2022/10/22 20:09:26 -------------------------------
2022/10/22 20:09:26 Debug your container:
2022/10/22 20:09:26 $ docker exec -it my-distroless-copy /.debugger/sh -c "PATH=\$PATH:/.debugger /.debugger/sh"
2022/10/22 20:09:26 -------------------------------

Note that with this approach the docker exec command from the output is used to exec into the debugger container, not into the original one.

Changing its entrypoint and/or command

Sometimes it's useful to change the entrypoint and/or command for a container, for example to add a debugging flag or because the application is crashing.

To simulate a crashing application, use docker run to create a container that immediately exits:

docker run --name crashing-container busybox:1.28 /bin/sh -c "false"

You can use debug-ctr debug with --entrypoint and/or --cmd to create a copy of this container with the command changed to an interactive shell:

debug-ctr debug --image=docker.io/alpine:latest --target=crashing-container --copy-to=crashing-container-copy --entrypoint="/.debugger/sleep" --cmd="365d"

Now you have an interactive shell that you can use to perform tasks like checking filesystem paths or running a container command manually.

Acknowledgements

About

Commandline tool for interactive container troubleshooting.

Resources

Stars

52 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

debug-ctr

A commandline tool for interactive troubleshooting when a container has crashed or a container image doesn't include debugging utilities, such as distroless images. Heavily inspired by kubectl debug, but for containers instead of Pods.

Option 1: Debugging adding a mount

This approach uses justincormack/addmount to mount the tools from a running container (e.g. busybox) into a target container without having to restart it. The benefit of this approach is that you wouldn't lose the running state of the container and the tools are available in the target container.

For example, you can run the following container from a distroless image that doesn't have a shell:

docker run -d --rm \
--name my-distroless gcr.io/distroless/nodejs \
-e 'setTimeout(() => console.log("Done"), 99999999)'

If you try to access the container, it'll fail because it doesn't contain a shell:

docker exec -it my-distroless /bin/sh
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown

You can bring the tools from busybox:1.28 that are available in /bin into the target container (without having to restart it) by simply running:

debug-ctr debug --image=busybox:1.28 --target=my-distroless
...
2022/10/25 09:32:40 -------------------------------
2022/10/25 09:32:40 Debug your container:
2022/10/25 09:32:40 $ docker exec -it my-distroless /bin/sh
2022/10/25 09:32:40 -------------------------------

Option 2: Debugging using a "copy" of the container

Sometimes a container configuration options make it difficult to troubleshoot in certain situations. For example, you can't run docker exec to troubleshoot your container if your container image does not include a shell or if your application crashes on startup. In these situations you can use debug-ctr debug to create a "copy" of the container with configuration values changed to aid debugging.

How does it work?

debug-ctr debug uses the --copy-to flag to run a new container (a "copy" a.k.a the debugger container) that can be useful when your application is running but not behaving as you expect, and you'd like to add additional troubleshooting utilities to the container. This new container is simply a "copy" of the container you want to debug which now includes the utilities tools that you need to debug it.

The tools are first downloaded into a Docker volume from the image you specify with the --image flag from the /bin directory. When the debugger container is created, the volume is mounted at /.debugger and thus the tools in /bin from the image are available in the debugger container filesystem (e.g. ls will be available at /.debugger/ls) and added to the PATH automatically for you.

You can bring the sh tool from busybox:1.28 and simply run the following command to create a new debugger container and use the docker exec command suggested in the output to access it:

debug-ctr debug --image=busybox:1.28 --target=my-distroless --copy-to=my-distroless-copy
...
2022/10/22 20:09:26 Starting debug container my-distroless-copy
2022/10/22 20:09:26 -------------------------------
2022/10/22 20:09:26 Debug your container:
2022/10/22 20:09:26 $ docker exec -it my-distroless-copy /.debugger/sh -c "PATH=\$PATH:/.debugger /.debugger/sh"
2022/10/22 20:09:26 -------------------------------

Note that with this approach the docker exec command from the output is used to exec into the debugger container, not into the original one.

Changing its entrypoint and/or command

Sometimes it's useful to change the entrypoint and/or command for a container, for example to add a debugging flag or because the application is crashing.

To simulate a crashing application, use docker run to create a container that immediately exits:

docker run --name crashing-container busybox:1.28 /bin/sh -c "false"

You can use debug-ctr debug with --entrypoint and/or --cmd to create a copy of this container with the command changed to an interactive shell:

debug-ctr debug --image=docker.io/alpine:latest --target=crashing-container --copy-to=crashing-container-copy --entrypoint="/.debugger/sleep" --cmd="365d"

Now you have an interactive shell that you can use to perform tasks like checking filesystem paths or running a container command manually.

Acknowledgements

About

Commandline tool for interactive container troubleshooting.

Resources

Stars

52 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

debug-ctr

A commandline tool for interactive troubleshooting when a container has crashed or a container image doesn't include debugging utilities, such as distroless images. Heavily inspired by kubectl debug, but for containers instead of Pods.

Option 1: Debugging adding a mount

This approach uses justincormack/addmount to mount the tools from a running container (e.g. busybox) into a target container without having to restart it. The benefit of this approach is that you wouldn't lose the running state of the container and the tools are available in the target container.

For example, you can run the following container from a distroless image that doesn't have a shell:

docker run -d --rm \
--name my-distroless gcr.io/distroless/nodejs \
-e 'setTimeout(() => console.log("Done"), 99999999)'

If you try to access the container, it'll fail because it doesn't contain a shell:

docker exec -it my-distroless /bin/sh
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown

You can bring the tools from busybox:1.28 that are available in /bin into the target container (without having to restart it) by simply running:

debug-ctr debug --image=busybox:1.28 --target=my-distroless
...
2022/10/25 09:32:40 -------------------------------
2022/10/25 09:32:40 Debug your container:
2022/10/25 09:32:40 $ docker exec -it my-distroless /bin/sh
2022/10/25 09:32:40 -------------------------------

Option 2: Debugging using a "copy" of the container

Sometimes a container configuration options make it difficult to troubleshoot in certain situations. For example, you can't run docker exec to troubleshoot your container if your container image does not include a shell or if your application crashes on startup. In these situations you can use debug-ctr debug to create a "copy" of the container with configuration values changed to aid debugging.

How does it work?

debug-ctr debug uses the --copy-to flag to run a new container (a "copy" a.k.a the debugger container) that can be useful when your application is running but not behaving as you expect, and you'd like to add additional troubleshooting utilities to the container. This new container is simply a "copy" of the container you want to debug which now includes the utilities tools that you need to debug it.

The tools are first downloaded into a Docker volume from the image you specify with the --image flag from the /bin directory. When the debugger container is created, the volume is mounted at /.debugger and thus the tools in /bin from the image are available in the debugger container filesystem (e.g. ls will be available at /.debugger/ls) and added to the PATH automatically for you.

You can bring the sh tool from busybox:1.28 and simply run the following command to create a new debugger container and use the docker exec command suggested in the output to access it:

debug-ctr debug --image=busybox:1.28 --target=my-distroless --copy-to=my-distroless-copy
...
2022/10/22 20:09:26 Starting debug container my-distroless-copy
2022/10/22 20:09:26 -------------------------------
2022/10/22 20:09:26 Debug your container:
2022/10/22 20:09:26 $ docker exec -it my-distroless-copy /.debugger/sh -c "PATH=\$PATH:/.debugger /.debugger/sh"
2022/10/22 20:09:26 -------------------------------

Note that with this approach the docker exec command from the output is used to exec into the debugger container, not into the original one.

Changing its entrypoint and/or command

Sometimes it's useful to change the entrypoint and/or command for a container, for example to add a debugging flag or because the application is crashing.

To simulate a crashing application, use docker run to create a container that immediately exits:

docker run --name crashing-container busybox:1.28 /bin/sh -c "false"

You can use debug-ctr debug with --entrypoint and/or --cmd to create a copy of this container with the command changed to an interactive shell:

debug-ctr debug --image=docker.io/alpine:latest --target=crashing-container --copy-to=crashing-container-copy --entrypoint="/.debugger/sleep" --cmd="365d"

Now you have an interactive shell that you can use to perform tasks like checking filesystem paths or running a container command manually.

Acknowledgements

About

Commandline tool for interactive container troubleshooting.

Resources

Stars

52 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

debug-ctr

A commandline tool for interactive troubleshooting when a container has crashed or a container image doesn't include debugging utilities, such as distroless images. Heavily inspired by kubectl debug, but for containers instead of Pods.

Option 1: Debugging adding a mount

This approach uses justincormack/addmount to mount the tools from a running container (e.g. busybox) into a target container without having to restart it. The benefit of this approach is that you wouldn't lose the running state of the container and the tools are available in the target container.

For example, you can run the following container from a distroless image that doesn't have a shell:

docker run -d --rm \
--name my-distroless gcr.io/distroless/nodejs \
-e 'setTimeout(() => console.log("Done"), 99999999)'

If you try to access the container, it'll fail because it doesn't contain a shell:

docker exec -it my-distroless /bin/sh
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown

You can bring the tools from busybox:1.28 that are available in /bin into the target container (without having to restart it) by simply running:

debug-ctr debug --image=busybox:1.28 --target=my-distroless
...
2022/10/25 09:32:40 -------------------------------
2022/10/25 09:32:40 Debug your container:
2022/10/25 09:32:40 $ docker exec -it my-distroless /bin/sh
2022/10/25 09:32:40 -------------------------------

Option 2: Debugging using a "copy" of the container

Sometimes a container configuration options make it difficult to troubleshoot in certain situations. For example, you can't run docker exec to troubleshoot your container if your container image does not include a shell or if your application crashes on startup. In these situations you can use debug-ctr debug to create a "copy" of the container with configuration values changed to aid debugging.

How does it work?

debug-ctr debug uses the --copy-to flag to run a new container (a "copy" a.k.a the debugger container) that can be useful when your application is running but not behaving as you expect, and you'd like to add additional troubleshooting utilities to the container. This new container is simply a "copy" of the container you want to debug which now includes the utilities tools that you need to debug it.

The tools are first downloaded into a Docker volume from the image you specify with the --image flag from the /bin directory. When the debugger container is created, the volume is mounted at /.debugger and thus the tools in /bin from the image are available in the debugger container filesystem (e.g. ls will be available at /.debugger/ls) and added to the PATH automatically for you.

You can bring the sh tool from busybox:1.28 and simply run the following command to create a new debugger container and use the docker exec command suggested in the output to access it:

debug-ctr debug --image=busybox:1.28 --target=my-distroless --copy-to=my-distroless-copy
...
2022/10/22 20:09:26 Starting debug container my-distroless-copy
2022/10/22 20:09:26 -------------------------------
2022/10/22 20:09:26 Debug your container:
2022/10/22 20:09:26 $ docker exec -it my-distroless-copy /.debugger/sh -c "PATH=\$PATH:/.debugger /.debugger/sh"
2022/10/22 20:09:26 -------------------------------

Note that with this approach the docker exec command from the output is used to exec into the debugger container, not into the original one.

Changing its entrypoint and/or command

Sometimes it's useful to change the entrypoint and/or command for a container, for example to add a debugging flag or because the application is crashing.

To simulate a crashing application, use docker run to create a container that immediately exits:

docker run --name crashing-container busybox:1.28 /bin/sh -c "false"

You can use debug-ctr debug with --entrypoint and/or --cmd to create a copy of this container with the command changed to an interactive shell:

debug-ctr debug --image=docker.io/alpine:latest --target=crashing-container --copy-to=crashing-container-copy --entrypoint="/.debugger/sleep" --cmd="365d"

Now you have an interactive shell that you can use to perform tasks like checking filesystem paths or running a container command manually.

Acknowledgements

About

Commandline tool for interactive container troubleshooting.

Resources

Stars

52 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages