Files
singular-particular-space/ToolsnToys/docker-cheatsheet-enhanced.html
JL Kruger 73f653ff23 Flatten ToolsnToys structure; add edu toys, dendritic, legacy artifacts
Move 6 guide pages from Guides/ to ToolsnToys/ root; fix back-links.
Add edu-toys.html (museum-style iframe exhibit for 4 legacy edu toy pages).
Add 4 edu toy artifacts, dendritic curio, docker-cheatsheet-enhanced.
Wire foss-tools, guides, edu-toys, and dendritic hrefs in toolsntoys.html.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 18:08:20 +02:00

1955 lines
75 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Comprehensive Docker and Docker Compose command reference with examples, troubleshooting, and best practices">
<meta name="keywords" content="docker, docker compose, cheatsheet, reference, commands, tutorial">
<title>Docker Command Cheatsheet | Quick Reference</title>
<!-- Noto Emoji Font -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&display=swap" rel="stylesheet">
<style>
/* ===================================
DOCKER CHEATSHEET DESIGN SYSTEM
Dark mode, flat design, tech-focused
Enhanced with accessibility & UX features
=================================== */
:root {
/* Colors - Backgrounds */
--bg-primary: #0B0B0B;
--bg-elevated: #0F0F0F;
--bg-card: #141414;
--bg-code: #1A1A1A;
/* Colors - Accents */
--accent-orange: #EB7513;
--accent-yellow: #F2C62A;
--accent-green: #5E9A0E;
--accent-red: #A52C16;
--accent-burgundy: #69190D;
--accent-blue: #4A90E2;
/* Colors - Text */
--text-primary: #F2F2BC;
--text-muted: rgba(242, 242, 188, 0.7);
--text-dim: rgba(242, 242, 188, 0.5);
/* Spacing */
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
--space-xl: 2rem;
--space-2xl: 3rem;
/* Transitions */
--transition-fast: 150ms ease;
--transition-base: 300ms ease;
/* Focus ring */
--focus-ring: 0 0 0 3px rgba(235, 117, 19, 0.5);
}
/* Respect reduced motion preferences */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Segoe UI', 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
padding: var(--space-lg);
}
/* Emoji font family */
.emoji {
font-family: 'Noto Color Emoji', 'Apple Color Emoji', 'Segoe UI Emoji', sans-serif;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
/* ===== SKIP NAVIGATION (ACCESSIBILITY) ===== */
.skip-nav {
position: absolute;
top: -40px;
left: 0;
background: var(--accent-orange);
color: var(--bg-primary);
padding: var(--space-sm) var(--space-md);
text-decoration: none;
font-weight: bold;
z-index: 1000;
}
.skip-nav:focus {
top: 0;
outline: 2px solid var(--accent-yellow);
outline-offset: 2px;
}
/* ===== FOCUS INDICATORS (ACCESSIBILITY) ===== */
*:focus-visible {
outline: 2px solid var(--accent-orange);
outline-offset: 2px;
box-shadow: var(--focus-ring);
}
/* ===== HEADER ===== */
.header {
text-align: center;
padding: var(--space-xl) 0;
border-bottom: 3px solid var(--accent-orange);
margin-bottom: var(--space-xl);
}
.header h1 {
font-size: clamp(2rem, 5vw, 3rem);
color: var(--accent-orange);
margin-bottom: var(--space-md);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.header p {
color: var(--text-muted);
font-size: 1.1rem;
}
/* ===== SEARCH BOX ===== */
.search-container {
background: var(--bg-elevated);
padding: var(--space-lg);
margin-bottom: var(--space-xl);
border-left: 4px solid var(--accent-blue);
position: sticky;
top: 0;
z-index: 99;
}
.search-box {
position: relative;
max-width: 600px;
}
.search-box label {
display: block;
color: var(--accent-yellow);
margin-bottom: var(--space-sm);
font-weight: bold;
}
.search-input {
width: 100%;
padding: var(--space-md);
background: var(--bg-code);
border: 2px solid var(--bg-card);
color: var(--text-primary);
font-size: 1rem;
border-radius: 4px;
transition: border-color var(--transition-fast);
}
.search-input:focus {
border-color: var(--accent-orange);
}
.search-input::placeholder {
color: var(--text-dim);
}
.search-clear {
position: absolute;
right: var(--space-md);
top: 50%;
background: transparent;
border: none;
color: var(--text-muted);
cursor: pointer;
font-size: 1.2rem;
padding: var(--space-xs);
display: none;
}
.search-clear:hover {
color: var(--accent-red);
}
/* ===== NAVIGATION ===== */
.nav {
background: var(--bg-elevated);
padding: var(--space-lg);
margin-bottom: var(--space-xl);
border-left: 4px solid var(--accent-green);
position: sticky;
top: 80px;
z-index: 98;
}
.nav h2 {
color: var(--accent-yellow);
margin-bottom: var(--space-md);
font-size: 1.2rem;
}
.nav ul {
list-style: none;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--space-sm);
}
.nav a {
color: var(--text-primary);
text-decoration: none;
padding: var(--space-sm);
display: block;
border-left: 2px solid transparent;
transition: all var(--transition-base);
border-radius: 2px;
}
.nav a:hover,
.nav a:focus {
color: var(--accent-orange);
border-left-color: var(--accent-orange);
padding-left: var(--space-md);
background: rgba(235, 117, 19, 0.1);
}
.nav a[aria-current="true"] {
color: var(--accent-orange);
border-left-color: var(--accent-orange);
font-weight: bold;
}
/* ===== SECTIONS ===== */
.section {
margin-bottom: var(--space-xl);
background: var(--bg-elevated);
padding: var(--space-xl);
border-left: 4px solid var(--accent-orange);
scroll-margin-top: 100px;
}
.section h2 {
color: var(--accent-orange);
font-size: 1.8rem;
margin-bottom: var(--space-lg);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.section h3 {
color: var(--accent-yellow);
font-size: 1.3rem;
margin-top: var(--space-lg);
margin-bottom: var(--space-md);
}
.section h4 {
color: var(--accent-green);
font-size: 1.1rem;
margin-top: var(--space-md);
margin-bottom: var(--space-sm);
}
.section ul,
.section ol {
margin-left: var(--space-xl);
margin-top: var(--space-md);
margin-bottom: var(--space-md);
}
.section li {
margin-bottom: var(--space-sm);
color: var(--text-muted);
}
/* ===== COMMAND BLOCKS ===== */
.cmd-block {
background: var(--bg-card);
padding: var(--space-lg);
margin: var(--space-md) 0;
border-left: 3px solid var(--accent-green);
position: relative;
}
.cmd-title {
color: var(--accent-yellow);
font-weight: bold;
margin-bottom: var(--space-sm);
font-size: 1rem;
}
.cmd-desc {
color: var(--text-muted);
margin-bottom: var(--space-sm);
font-size: 0.9rem;
}
.code-container {
position: relative;
}
.code {
background: var(--bg-code);
padding: var(--space-md);
border-radius: 4px;
font-family: 'Courier New', 'Monaco', 'Menlo', monospace;
color: var(--accent-yellow);
overflow-x: auto;
font-size: 0.9rem;
border: 1px solid rgba(242, 198, 42, 0.2);
display: block;
white-space: pre;
line-height: 1.5;
}
.copy-btn {
position: absolute;
top: var(--space-sm);
right: var(--space-sm);
background: var(--accent-orange);
color: var(--bg-primary);
border: none;
padding: var(--space-xs) var(--space-md);
cursor: pointer;
font-size: 0.85rem;
font-weight: bold;
border-radius: 4px;
transition: all var(--transition-fast);
text-transform: uppercase;
}
.copy-btn:hover {
background: var(--accent-yellow);
transform: scale(1.05);
}
.copy-btn:active {
transform: scale(0.95);
}
.copy-btn.copied {
background: var(--accent-green);
}
.copy-btn.copied::after {
content: ' ✓';
}
.code-inline {
background: var(--bg-code);
padding: 2px 6px;
font-family: 'Courier New', 'Monaco', 'Menlo', monospace;
color: var(--accent-yellow);
font-size: 0.9em;
border-radius: 2px;
border: 1px solid rgba(242, 198, 42, 0.1);
}
/* ===== INFO BOXES ===== */
.info-box {
background: var(--bg-card);
padding: var(--space-lg);
margin: var(--space-md) 0;
border-left: 4px solid var(--accent-green);
border-radius: 4px;
}
.info-box.warning {
border-left-color: var(--accent-orange);
}
.info-box.danger {
border-left-color: var(--accent-red);
}
.info-box.concept {
border-left-color: var(--accent-yellow);
}
.info-box-title {
font-weight: bold;
margin-bottom: var(--space-sm);
font-size: 1.1rem;
}
.info-box.concept .info-box-title {
color: var(--accent-yellow);
}
.info-box.warning .info-box-title {
color: var(--accent-orange);
}
.info-box.danger .info-box-title {
color: var(--accent-red);
}
/* ===== TABLES ===== */
.comparison-table {
width: 100%;
border-collapse: collapse;
margin: var(--space-md) 0;
overflow-x: auto;
display: block;
}
.comparison-table thead {
display: table;
width: 100%;
table-layout: fixed;
}
.comparison-table tbody {
display: table;
width: 100%;
table-layout: fixed;
}
.comparison-table th {
background: var(--bg-code);
color: var(--accent-yellow);
padding: var(--space-md);
text-align: left;
border: 1px solid rgba(242, 198, 42, 0.2);
font-weight: bold;
}
.comparison-table td {
background: var(--bg-card);
padding: var(--space-md);
border: 1px solid rgba(242, 242, 188, 0.1);
vertical-align: top;
}
.comparison-table tr:hover td {
background: rgba(235, 117, 19, 0.05);
}
/* ===== FOOTER ===== */
.footer {
text-align: center;
padding: var(--space-2xl) var(--space-lg);
margin-top: var(--space-2xl);
border-top: 3px solid var(--accent-orange);
color: var(--text-muted);
}
.footer p {
margin-bottom: var(--space-sm);
}
/* ===== BACK TO TOP BUTTON ===== */
.back-to-top {
position: fixed;
bottom: var(--space-lg);
right: var(--space-lg);
background: var(--accent-orange);
color: var(--bg-primary);
width: 50px;
height: 50px;
border-radius: 50%;
border: none;
cursor: pointer;
display: none;
align-items: center;
justify-content: center;
font-size: 1.5rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
transition: all var(--transition-base);
z-index: 100;
}
.back-to-top:hover {
background: var(--accent-yellow);
transform: translateY(-5px);
}
.back-to-top.visible {
display: flex;
}
/* ===== RESPONSIVE DESIGN ===== */
@media (max-width: 768px) {
body {
padding: var(--space-sm);
}
.nav ul {
grid-template-columns: 1fr;
}
.nav {
position: static;
}
.search-container {
position: static;
}
.section {
padding: var(--space-md);
}
.comparison-table {
font-size: 0.85rem;
}
.comparison-table th,
.comparison-table td {
padding: var(--space-sm);
}
}
/* ===== PRINT STYLES ===== */
@media print {
body {
background: white;
color: black;
}
.nav,
.search-container,
.back-to-top,
.copy-btn {
display: none !important;
}
.section {
page-break-inside: avoid;
border-left: 2px solid black;
}
.code {
border: 1px solid #ccc;
background: #f5f5f5;
color: black;
}
a {
color: black;
text-decoration: underline;
}
}
/* ===== HIGHLIGHT ANIMATION ===== */
@keyframes highlight {
0% {
background: rgba(235, 117, 19, 0.3);
}
100% {
background: transparent;
}
}
.section.highlight {
animation: highlight 2s ease-out;
}
</style>
</head>
<body>
<!-- Skip Navigation Link -->
<a href="#main-content" class="skip-nav">Skip to main content</a>
<div class="container">
<!-- HEADER -->
<header class="header" role="banner">
<h1><span class="emoji">🐳</span> Docker Command Cheatsheet</h1>
<p>Complete reference for Docker & Docker Compose</p>
</header>
<!-- SEARCH BOX -->
<div class="search-container" role="search">
<div class="search-box">
<label for="search-input"><span class="emoji">🔍</span> Search Commands</label>
<input
type="search"
id="search-input"
class="search-input"
placeholder="Type to filter commands and sections..."
aria-label="Search commands and sections"
>
<button class="search-clear" aria-label="Clear search" title="Clear search">&times;</button>
</div>
</div>
<!-- NAVIGATION -->
<nav class="nav" role="navigation" aria-label="Main navigation">
<h2><span class="emoji">📑</span> Quick Navigation</h2>
<ul>
<li><a href="#basics">Basics</a></li>
<li><a href="#compose">Docker Compose</a></li>
<li><a href="#lifecycle">Container Lifecycle</a></li>
<li><a href="#monitoring">Monitoring</a></li>
<li><a href="#volumes">Volumes & Data</a></li>
<li><a href="#networks">Networks</a></li>
<li><a href="#images">Images</a></li>
<li><a href="#cleanup">Cleanup</a></li>
<li><a href="#troubleshooting">Troubleshooting</a></li>
<li><a href="#patterns">Common Patterns</a></li>
<li><a href="#best-practices">Best Practices</a></li>
<li><a href="#quick-ref">Quick Reference</a></li>
</ul>
</nav>
<!-- MAIN CONTENT -->
<main id="main-content">
<!-- SECTION: BASICS -->
<section id="basics" class="section">
<h2><span class="emoji">📦</span> Docker Basics</h2>
<div class="info-box concept">
<div class="info-box-title"><span class="emoji">💡</span> What is Docker?</div>
<p>Docker packages applications and their dependencies into <strong>containers</strong> - lightweight, portable units that run consistently across different environments. Think of containers as self-contained boxes that have everything an application needs to run.</p>
</div>
<h3>Key Concepts</h3>
<div class="info-box">
<div class="info-box-title"><span class="emoji">🧩</span> Core Components</div>
<ul>
<li><strong>Image:</strong> A blueprint/template for containers (like a recipe)</li>
<li><strong>Container:</strong> A running instance of an image (like a meal made from the recipe)</li>
<li><strong>Volume:</strong> Persistent storage that survives container restarts</li>
<li><strong>Network:</strong> How containers communicate with each other and the outside world</li>
<li><strong>Docker Compose:</strong> Tool for defining multi-container applications</li>
</ul>
</div>
<h3>Basic Commands</h3>
<div class="cmd-block">
<div class="cmd-title">Check Docker Version</div>
<div class="cmd-desc">Verify Docker is installed and see version info</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker --version
docker version
docker info</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Test Docker Installation</div>
<div class="cmd-desc">Run a test container to verify everything works</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker run hello-world</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Pull an Image</div>
<div class="cmd-desc">Download an image from Docker Hub</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker pull ubuntu:22.04
docker pull nginx:latest</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Run a Container</div>
<div class="cmd-desc">Create and start a container from an image</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Basic run
docker run nginx
# Run with custom name
docker run --name my-nginx nginx
# Run in background (detached mode)
docker run -d nginx
# Run with port mapping
docker run -d -p 8080:80 nginx
# Run with environment variables
docker run -d -e "MY_VAR=value" nginx</pre>
</div>
</div>
</section>
<!-- SECTION: DOCKER COMPOSE -->
<section id="compose" class="section">
<h2><span class="emoji">🎼</span> Docker Compose</h2>
<div class="info-box concept">
<div class="info-box-title"><span class="emoji">💡</span> What is Docker Compose?</div>
<p>Docker Compose lets you define and run multi-container applications using a YAML file. Instead of managing each container separately, you describe your entire application stack in <code>docker-compose.yaml</code> and control everything with simple commands.</p>
</div>
<h3>Essential Compose Commands</h3>
<div class="cmd-block">
<div class="cmd-title">Start Services (Detached)</div>
<div class="cmd-desc">Start all services defined in docker-compose.yaml in the background</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker compose up -d</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Start Services (Foreground)</div>
<div class="cmd-desc">Start services and see logs in real-time (Ctrl+C to stop)</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker compose up</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Stop Services</div>
<div class="cmd-desc">Stop running containers but keep them for restart</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker compose stop</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Start Stopped Services</div>
<div class="cmd-desc">Restart previously stopped services</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker compose start</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Restart Services</div>
<div class="cmd-desc">Stop and start services in one command</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker compose restart
# Restart specific service
docker compose restart backend</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Stop and Remove Containers</div>
<div class="cmd-desc">Stop services and remove containers (volumes remain intact)</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker compose down</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Stop and Remove Everything (INCLUDING DATA!)</div>
<div class="cmd-desc">⚠️ Nuclear option - removes containers AND volumes (all data lost)</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker compose down -v</pre>
</div>
</div>
<div class="info-box danger">
<div class="info-box-title"><span class="emoji">🚨</span> Critical Warning</div>
<p><code>docker compose down -v</code> deletes ALL data stored in volumes. Only use this when you want a complete reset or are removing an application permanently.</p>
</div>
<div class="cmd-block">
<div class="cmd-title">View Service Status</div>
<div class="cmd-desc">See which containers are running</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker compose ps</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">View Logs</div>
<div class="cmd-desc">See output from all services</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># All logs
docker compose logs
# Follow logs (real-time)
docker compose logs -f
# Last 100 lines
docker compose logs --tail=100
# Specific service
docker compose logs backend
# Follow specific service
docker compose logs -f backend</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Pull Latest Images</div>
<div class="cmd-desc">Download updated versions of images</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker compose pull</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Build Images</div>
<div class="cmd-desc">Build custom images defined in docker-compose.yaml</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Build all images
docker compose build
# Build without cache
docker compose build --no-cache
# Build specific service
docker compose build backend</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Execute Command in Service</div>
<div class="cmd-desc">Run a command inside a running container</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Get shell access
docker compose exec backend bash
# Run single command
docker compose exec backend ls -la
# Run as different user
docker compose exec -u postgres postgres psql</pre>
</div>
</div>
<h3>Compose File Validation</h3>
<div class="cmd-block">
<div class="cmd-title">Validate Configuration</div>
<div class="cmd-desc">Check if docker-compose.yaml is valid</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker compose config</pre>
</div>
</div>
</section>
<!-- SECTION: CONTAINER LIFECYCLE -->
<section id="lifecycle" class="section">
<h2><span class="emoji">🔄</span> Container Lifecycle Management</h2>
<h3>Starting & Stopping</h3>
<div class="cmd-block">
<div class="cmd-title">Start Container</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker start &lt;container_name_or_id&gt;</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Stop Container</div>
<div class="cmd-desc">Gracefully stop (sends SIGTERM, waits, then SIGKILL)</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker stop &lt;container_name_or_id&gt;
# Stop with timeout (seconds)
docker stop -t 30 &lt;container_name_or_id&gt;</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Restart Container</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker restart &lt;container_name_or_id&gt;</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Kill Container</div>
<div class="cmd-desc">Force stop immediately (sends SIGKILL)</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker kill &lt;container_name_or_id&gt;</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Remove Container</div>
<div class="cmd-desc">Delete stopped container</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Remove stopped container
docker rm &lt;container_name_or_id&gt;
# Force remove running container
docker rm -f &lt;container_name_or_id&gt;
# Remove with volumes
docker rm -v &lt;container_name_or_id&gt;</pre>
</div>
</div>
<h3>Listing & Inspection</h3>
<div class="cmd-block">
<div class="cmd-title">List Running Containers</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker ps</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">List All Containers</div>
<div class="cmd-desc">Including stopped containers</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker ps -a</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Inspect Container</div>
<div class="cmd-desc">Get detailed information about a container</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker inspect &lt;container_name_or_id&gt;
# Get specific field
docker inspect --format='{{.State.Status}}' &lt;container&gt;</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">View Container Logs</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># All logs
docker logs &lt;container_name_or_id&gt;
# Follow logs (real-time)
docker logs -f &lt;container_name_or_id&gt;
# Last 100 lines
docker logs --tail 100 &lt;container_name_or_id&gt;
# With timestamps
docker logs -t &lt;container_name_or_id&gt;</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Execute Command in Running Container</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Interactive shell
docker exec -it &lt;container_name&gt; bash
# Or sh if bash not available
docker exec -it &lt;container_name&gt; sh
# Run single command
docker exec &lt;container_name&gt; ls -la /app
# As different user
docker exec -u postgres &lt;container_name&gt; psql</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Copy Files To/From Container</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Copy from container to host
docker cp &lt;container&gt;:/path/to/file /local/path
# Copy from host to container
docker cp /local/file &lt;container&gt;:/path/to/destination</pre>
</div>
</div>
</section>
<!-- SECTION: MONITORING -->
<section id="monitoring" class="section">
<h2><span class="emoji">📊</span> Monitoring & Performance</h2>
<div class="cmd-block">
<div class="cmd-title">View Resource Usage</div>
<div class="cmd-desc">Real-time stats for all running containers</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker stats
# Specific container
docker stats &lt;container_name&gt;
# No streaming (one-time)
docker stats --no-stream</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">View Running Processes</div>
<div class="cmd-desc">See processes inside container</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker top &lt;container_name&gt;</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">View Port Mappings</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker port &lt;container_name&gt;</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">System-Wide Information</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Disk usage
docker system df
# Detailed disk usage
docker system df -v
# System information
docker info</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Monitor Events</div>
<div class="cmd-desc">Real-time events from Docker daemon</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker events
# Filter by type
docker events --filter 'type=container'
# Filter by event
docker events --filter 'event=start'</pre>
</div>
</div>
</section>
<!-- SECTION: VOLUMES -->
<section id="volumes" class="section">
<h2><span class="emoji">💾</span> Volumes & Data Management</h2>
<div class="info-box concept">
<div class="info-box-title"><span class="emoji">💡</span> What are Volumes?</div>
<p>Volumes are Docker's way of persisting data beyond container lifecycles. When you delete a container, volumes remain intact unless explicitly removed. This is how your data survives updates and restarts.</p>
</div>
<div class="cmd-block">
<div class="cmd-title">List Volumes</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker volume ls</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Create Volume</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker volume create my_volume</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Inspect Volume</div>
<div class="cmd-desc">See volume details including mount point</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker volume inspect my_volume</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Remove Volume</div>
<div class="cmd-desc">⚠️ This deletes data permanently</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker volume rm my_volume
# Force remove
docker volume rm -f my_volume</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Backup Volume</div>
<div class="cmd-desc">Create a tarball backup of volume data</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker run --rm \
-v my_volume:/data \
-v $(pwd):/backup \
ubuntu tar czf /backup/backup.tar.gz /data</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Restore Volume</div>
<div class="cmd-desc">Restore from backup tarball</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker run --rm \
-v my_volume:/data \
-v $(pwd):/backup \
ubuntu tar xzf /backup/backup.tar.gz -C /</pre>
</div>
</div>
<h3>Volume Usage in Containers</h3>
<div class="cmd-block">
<div class="cmd-title">Mount Volume to Container</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Named volume
docker run -d -v my_volume:/app/data nginx
# Bind mount (host directory)
docker run -d -v /host/path:/container/path nginx
# Read-only mount
docker run -d -v my_volume:/app/data:ro nginx</pre>
</div>
</div>
</section>
<!-- SECTION: NETWORKS -->
<section id="networks" class="section">
<h2><span class="emoji">🌐</span> Networks</h2>
<div class="info-box concept">
<div class="info-box-title"><span class="emoji">💡</span> Docker Networks</div>
<p>Networks allow containers to communicate with each other and the outside world. Docker creates isolated networks where containers can find each other by name.</p>
</div>
<div class="cmd-block">
<div class="cmd-title">List Networks</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker network ls</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Create Network</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Bridge network (default type)
docker network create my_network
# Custom subnet
docker network create --subnet=172.20.0.0/16 my_network</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Inspect Network</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker network inspect my_network</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Connect Container to Network</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker network connect my_network &lt;container_name&gt;</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Disconnect Container from Network</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker network disconnect my_network &lt;container_name&gt;</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Remove Network</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker network rm my_network</pre>
</div>
</div>
</section>
<!-- SECTION: IMAGES -->
<section id="images" class="section">
<h2><span class="emoji">📦</span> Image Management</h2>
<div class="cmd-block">
<div class="cmd-title">List Images</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker images
# With digests
docker images --digests
# Show all (including intermediate)
docker images -a</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Pull Image</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Latest version
docker pull nginx
# Specific version
docker pull nginx:1.25
# From different registry
docker pull ghcr.io/user/image:tag</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Search Images</div>
<div class="cmd-desc">Search Docker Hub</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker search nginx
# Limit results
docker search --limit 10 nginx</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Remove Image</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker rmi &lt;image_name_or_id&gt;
# Force remove
docker rmi -f &lt;image_name_or_id&gt;
# Remove multiple
docker rmi image1 image2 image3</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Tag Image</div>
<div class="cmd-desc">Create alias for image</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker tag source_image:tag target_image:tag
# Example
docker tag nginx:latest myregistry.com/nginx:v1</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Build Image from Dockerfile</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Build from current directory
docker build -t my-image:tag .
# Build without cache
docker build --no-cache -t my-image:tag .
# Build with build args
docker build --build-arg VERSION=1.0 -t my-image:tag .</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Save & Load Images</div>
<div class="cmd-desc">Export/import images as tar files</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Save image to file
docker save -o my-image.tar my-image:tag
# Load image from file
docker load -i my-image.tar</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">View Image History</div>
<div class="cmd-desc">See image layers and how it was built</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker history &lt;image_name&gt;</pre>
</div>
</div>
</section>
<!-- SECTION: CLEANUP -->
<section id="cleanup" class="section">
<h2><span class="emoji">🧹</span> Cleanup & Maintenance</h2>
<div class="info-box warning">
<div class="info-box-title"><span class="emoji">⚠️</span> Before Cleanup</div>
<p>Always check what will be removed with <code>docker system df</code> first. Pruning operations are permanent!</p>
</div>
<div class="cmd-block">
<div class="cmd-title">Remove Stopped Containers</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker container prune
# Without confirmation prompt
docker container prune -f</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Remove Unused Images</div>
<div class="cmd-desc">Removes dangling images (not tagged and not used)</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker image prune
# Remove ALL unused images
docker image prune -a</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Remove Unused Volumes</div>
<div class="cmd-desc">⚠️ This deletes data in unused volumes!</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker volume prune
# Without confirmation
docker volume prune -f</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Remove Unused Networks</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker network prune</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Complete System Cleanup</div>
<div class="cmd-desc">Remove all unused containers, networks, images (both dangling and unreferenced)</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Safe cleanup (keeps volumes)
docker system prune
# Aggressive cleanup (includes volumes)
docker system prune -a --volumes
# Without confirmation
docker system prune -af</pre>
</div>
</div>
<div class="info-box danger">
<div class="info-box-title"><span class="emoji">🚨</span> Nuclear Option</div>
<p><strong>Complete Docker Reset:</strong></p>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Stop all containers
docker stop $(docker ps -aq)
# Remove all containers
docker rm $(docker ps -aq)
# Remove all images
docker rmi $(docker images -q)
# Remove all volumes
docker volume rm $(docker volume ls -q)
# Remove all networks
docker network rm $(docker network ls -q)</pre>
</div>
<p><strong>This removes EVERYTHING. Only use if you want a complete fresh start!</strong></p>
</div>
</section>
<!-- SECTION: TROUBLESHOOTING -->
<section id="troubleshooting" class="section">
<h2><span class="emoji">🔧</span> Troubleshooting</h2>
<h3>Common Issues</h3>
<div class="info-box warning">
<div class="info-box-title"><span class="emoji">⚠️</span> Port Already in Use</div>
<p><strong>Error:</strong> <code>Error starting userland proxy: listen tcp 0.0.0.0:9001: bind: address already in use</code></p>
<p><strong>Solution:</strong></p>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Find what's using the port
sudo lsof -i :9001
sudo netstat -tulpn | grep :9001
# Kill the process or change port in docker-compose.yaml</pre>
</div>
</div>
<div class="info-box warning">
<div class="info-box-title"><span class="emoji">⚠️</span> Container Keeps Restarting</div>
<p><strong>Check logs for errors:</strong></p>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">docker logs --tail 100 &lt;container_name&gt;</pre>
</div>
</div>
<div class="info-box warning">
<div class="info-box-title"><span class="emoji">⚠️</span> Out of Disk Space</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Check Docker disk usage
docker system df
# Clean up
docker system prune -a
docker volume prune</pre>
</div>
</div>
<div class="info-box warning">
<div class="info-box-title"><span class="emoji">⚠️</span> Permission Denied</div>
<p><strong>Error:</strong> <code>Got permission denied while trying to connect to the Docker daemon socket</code></p>
<p><strong>Solution:</strong></p>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Add user to docker group
sudo usermod -aG docker $USER
# Log out and back in for changes to take effect
# Or start new shell
newgrp docker</pre>
</div>
</div>
<div class="info-box warning">
<div class="info-box-title"><span class="emoji">⚠️</span> Network Issues</div>
<p><strong>Container can't reach internet or other containers</strong></p>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Restart Docker daemon
sudo systemctl restart docker
# Or recreate network
docker network rm &lt;network_name&gt;
docker network create &lt;network_name&gt;</pre>
</div>
</div>
</section>
<!-- SECTION: COMMON PATTERNS -->
<section id="patterns" class="section">
<h2><span class="emoji">🎯</span> Common Patterns</h2>
<h3>Complete Application Reset</h3>
<div class="cmd-block">
<div class="cmd-title">Reset Application (Delete All Data)</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">cd ~/project
docker compose down -v # Remove containers + volumes
docker compose pull # Get latest images
docker compose up -d # Start fresh</pre>
</div>
</div>
<h3>Update Application</h3>
<div class="cmd-block">
<div class="cmd-title">Update to Latest Version (Keep Data)</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">cd ~/project
docker compose pull # Download latest
docker compose up -d # Recreate containers with new images</pre>
</div>
</div>
<h3>Backup and Restore</h3>
<div class="cmd-block">
<div class="cmd-title">Backup Before Changes</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Stop services
docker compose stop
# Backup volumes
docker run --rm -v project_data:/data -v $(pwd):/backup \
ubuntu tar czf /backup/backup-$(date +%Y%m%d).tar.gz /data
# Restart
docker compose start</pre>
</div>
</div>
<h3>Development vs Production</h3>
<div class="cmd-block">
<div class="cmd-title">Multiple Compose Files</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Development
docker compose -f docker-compose.yaml -f docker-compose.dev.yaml up
# Production
docker compose -f docker-compose.yaml -f docker-compose.prod.yaml up -d</pre>
</div>
</div>
<h3>Debugging Running Container</h3>
<div class="cmd-block">
<div class="cmd-title">Interactive Shell Access</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Get shell in running container
docker exec -it &lt;container_name&gt; bash
# Or sh if bash isn't available
docker exec -it &lt;container_name&gt; sh
# Run single command
docker exec &lt;container_name&gt; ls -la /app</pre>
</div>
</div>
</section>
<!-- SECTION: BEST PRACTICES -->
<section id="best-practices" class="section">
<h2><span class="emoji"></span> Best Practices</h2>
<h3>Project Organization</h3>
<div class="info-box">
<div class="info-box-title"><span class="emoji">📂</span> Directory Structure</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code">~/projects/
├── penpot/
│ ├── docker-compose.yaml
│ ├── .env
│ └── README.md
├── nextcloud/
│ ├── docker-compose.yaml
│ └── data/
└── ...</pre>
</div>
</div>
<h3>Docker Compose Best Practices</h3>
<ul>
<li><strong>Always use named volumes</strong> instead of anonymous volumes</li>
<li><strong>Use .env files</strong> for sensitive data (passwords, API keys)</li>
<li><strong>Pin image versions</strong> - use <code>postgres:15</code> not <code>postgres:latest</code></li>
<li><strong>Add restart policies</strong> - <code>restart: unless-stopped</code></li>
<li><strong>Use depends_on</strong> to manage service startup order</li>
<li><strong>Document your setup</strong> in README.md</li>
<li><strong>Use health checks</strong> to ensure services are actually running</li>
<li><strong>Limit container resources</strong> (memory, CPU) in production</li>
</ul>
<h3>Maintenance Routine</h3>
<div class="cmd-block">
<div class="cmd-title">Weekly Cleanup</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Remove unused images, containers, networks
docker system prune
# Remove unused volumes (be careful!)
docker volume prune</pre>
</div>
</div>
<div class="cmd-block">
<div class="cmd-title">Check Updates</div>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># Check for new images
docker compose pull
# View what would change
docker compose up --no-start
# Apply updates
docker compose up -d</pre>
</div>
</div>
<h3>Security Tips</h3>
<div class="info-box warning">
<div class="info-box-title"><span class="emoji">🔒</span> Security Checklist</div>
<ul>
<li>Never store passwords in docker-compose.yaml - use .env files</li>
<li>Add .env to .gitignore</li>
<li>Use official images from trusted sources</li>
<li>Keep images updated regularly</li>
<li>Don't run containers as root unless necessary</li>
<li>Limit container resources (memory, CPU) in production</li>
<li>Use read-only file systems where possible</li>
<li>Scan images for vulnerabilities with <code>docker scan</code></li>
</ul>
</div>
<h3>When Things Go Wrong</h3>
<div class="info-box danger">
<div class="info-box-title"><span class="emoji">🚨</span> Emergency Recovery</div>
<p><strong>If everything is broken:</strong></p>
<div class="code-container">
<button class="copy-btn" aria-label="Copy code">Copy</button>
<pre class="code"># 1. Stop everything
docker compose down
# 2. Check logs for errors
docker compose logs --tail=100
# 3. Try starting with verbose output
docker compose up
# 4. If still broken, nuclear option:
docker compose down -v
docker system prune -a
docker compose up -d</pre>
</div>
</div>
</section>
<!-- SECTION: QUICK REFERENCE -->
<section id="quick-ref" class="section">
<h2><span class="emoji"></span> Quick Reference Card</h2>
<table class="comparison-table" role="table">
<thead>
<tr>
<th scope="col">Task</th>
<th scope="col">Command</th>
</tr>
</thead>
<tbody>
<tr>
<td>Start services</td>
<td><code>docker compose up -d</code></td>
</tr>
<tr>
<td>Stop services</td>
<td><code>docker compose stop</code></td>
</tr>
<tr>
<td>Restart services</td>
<td><code>docker compose restart</code></td>
</tr>
<tr>
<td>View logs</td>
<td><code>docker compose logs -f</code></td>
</tr>
<tr>
<td>Update images</td>
<td><code>docker compose pull && docker compose up -d</code></td>
</tr>
<tr>
<td>Remove containers (keep data)</td>
<td><code>docker compose down</code></td>
</tr>
<tr>
<td>Complete reset</td>
<td><code>docker compose down -v</code></td>
</tr>
<tr>
<td>Check status</td>
<td><code>docker compose ps</code></td>
</tr>
<tr>
<td>Clean unused resources</td>
<td><code>docker system prune</code></td>
</tr>
<tr>
<td>Shell into container</td>
<td><code>docker exec -it &lt;name&gt; bash</code></td>
</tr>
<tr>
<td>View resource usage</td>
<td><code>docker stats</code></td>
</tr>
<tr>
<td>Copy files to container</td>
<td><code>docker cp file &lt;name&gt;:/path</code></td>
</tr>
<tr>
<td>List all containers</td>
<td><code>docker ps -a</code></td>
</tr>
<tr>
<td>List all images</td>
<td><code>docker images</code></td>
</tr>
<tr>
<td>List volumes</td>
<td><code>docker volume ls</code></td>
</tr>
</tbody>
</table>
</section>
</main>
<!-- FOOTER -->
<footer class="footer" role="contentinfo">
<p><strong><span class="emoji">🐳</span> Docker Cheatsheet</strong></p>
<p>Created: October 2025 | For Linux Mint 22.2 XFCE</p>
<p style="margin-top: var(--space-md); font-size: 0.9rem;">
Save this file locally for offline reference: <code>docker-cheatsheet-enhanced.html</code>
</p>
</footer>
</div>
<!-- BACK TO TOP BUTTON -->
<button class="back-to-top" aria-label="Back to top" title="Back to top">
<span class="emoji"></span>
</button>
<script>
// ===== COPY TO CLIPBOARD FUNCTIONALITY =====
document.querySelectorAll('.copy-btn').forEach(button => {
button.addEventListener('click', async function() {
const codeBlock = this.nextElementSibling;
const code = codeBlock.textContent;
try {
await navigator.clipboard.writeText(code);
// Visual feedback
this.textContent = 'Copied';
this.classList.add('copied');
// Reset after 2 seconds
setTimeout(() => {
this.textContent = 'Copy';
this.classList.remove('copied');
}, 2000);
} catch (err) {
console.error('Failed to copy:', err);
this.textContent = 'Failed';
setTimeout(() => {
this.textContent = 'Copy';
}, 2000);
}
});
});
// ===== SEARCH FUNCTIONALITY =====
const searchInput = document.getElementById('search-input');
const searchClear = document.querySelector('.search-clear');
const sections = document.querySelectorAll('.section');
searchInput.addEventListener('input', function() {
const query = this.value.toLowerCase().trim();
// Show/hide clear button
searchClear.style.display = query ? 'block' : 'none';
if (!query) {
// Show all sections when search is empty
sections.forEach(section => {
section.style.display = 'block';
// Show all content within section
const content = section.querySelectorAll('.cmd-block, .info-box, h3, h4, p, ul, ol, table');
content.forEach(el => el.style.display = '');
});
return;
}
// Filter sections and content
sections.forEach(section => {
const sectionText = section.textContent.toLowerCase();
const hasMatch = sectionText.includes(query);
if (hasMatch) {
section.style.display = 'block';
// Highlight matching command blocks
const cmdBlocks = section.querySelectorAll('.cmd-block');
cmdBlocks.forEach(block => {
const blockText = block.textContent.toLowerCase();
block.style.display = blockText.includes(query) ? 'block' : 'none';
});
// Show/hide info boxes
const infoBoxes = section.querySelectorAll('.info-box');
infoBoxes.forEach(box => {
const boxText = box.textContent.toLowerCase();
box.style.display = boxText.includes(query) ? 'block' : 'none';
});
} else {
section.style.display = 'none';
}
});
});
searchClear.addEventListener('click', function() {
searchInput.value = '';
searchInput.dispatchEvent(new Event('input'));
searchInput.focus();
});
// ===== BACK TO TOP BUTTON =====
const backToTop = document.querySelector('.back-to-top');
window.addEventListener('scroll', function() {
if (window.scrollY > 300) {
backToTop.classList.add('visible');
} else {
backToTop.classList.remove('visible');
}
});
backToTop.addEventListener('click', function() {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
// ===== ACTIVE SECTION HIGHLIGHTING =====
const observerOptions = {
root: null,
rootMargin: '-100px 0px -80% 0px',
threshold: 0
};
const observer = new IntersectionObserver(function(entries) {
entries.forEach(entry => {
if (entry.isIntersecting) {
const id = entry.target.getAttribute('id');
// Update navigation
document.querySelectorAll('.nav a').forEach(link => {
link.setAttribute('aria-current', 'false');
if (link.getAttribute('href') === `#${id}`) {
link.setAttribute('aria-current', 'true');
}
});
}
});
}, observerOptions);
sections.forEach(section => {
observer.observe(section);
});
// ===== KEYBOARD SHORTCUTS =====
document.addEventListener('keydown', function(e) {
// Ctrl/Cmd + K to focus search
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
searchInput.focus();
}
// Escape to clear search
if (e.key === 'Escape' && document.activeElement === searchInput) {
searchInput.value = '';
searchInput.dispatchEvent(new Event('input'));
searchInput.blur();
}
});
// ===== HIGHLIGHT SECTION ON LOAD =====
if (window.location.hash) {
const targetSection = document.querySelector(window.location.hash);
if (targetSection) {
setTimeout(() => {
targetSection.classList.add('highlight');
setTimeout(() => {
targetSection.classList.remove('highlight');
}, 2000);
}, 500);
}
}
// ===== ANNOUNCE TO SCREEN READERS =====
const announcer = document.createElement('div');
announcer.setAttribute('role', 'status');
announcer.setAttribute('aria-live', 'polite');
announcer.setAttribute('aria-atomic', 'true');
announcer.className = 'sr-only';
announcer.style.position = 'absolute';
announcer.style.left = '-10000px';
announcer.style.width = '1px';
announcer.style.height = '1px';
announcer.style.overflow = 'hidden';
document.body.appendChild(announcer);
// Announce search results
searchInput.addEventListener('input', function() {
const visibleSections = Array.from(sections).filter(s => s.style.display !== 'none').length;
if (this.value.trim()) {
announcer.textContent = `${visibleSections} section${visibleSections !== 1 ? 's' : ''} found`;
}
});
</script>
</body>
</html>