Docker_Millionaire / index.html
eaglelandsonce's picture
Update index.html
1b8760e verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Concept to Code Millionaire</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 min-h-screen flex items-center justify-center p-6">
<div class="bg-white p-8 rounded-2xl shadow-xl w-full max-w-2xl">
<h1 class="text-4xl font-bold text-indigo-600 text-center mb-2">Concept to Code Millionaire</h1>
<p class="text-center text-sm text-gray-500 mb-6">
Source:
<a class="underline hover:text-indigo-700" target="_blank"
href="https://www.linkedin.com/pulse/docker-from-concept-commands-michael-lively-mndwe/">
Docker: From Concept to Commands — Michael Lively (Aug 23, 2025)
</a>
</p>
<div id="board">
<div id="error" class="hidden mb-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded p-2"></div>
<div id="question" class="text-2xl font-semibold text-gray-800 mb-4"></div>
<div id="choices" class="space-y-3"></div>
<div id="lifelines" class="flex justify-around mt-6">
<button id="life5050" class="lifeline bg-yellow-400 hover:bg-yellow-500 text-white font-medium py-2 px-4 rounded-lg shadow">50:50</button>
<button id="lifePoll" class="lifeline bg-blue-400 hover:bg-blue-500 text-white font-medium py-2 px-4 rounded-lg shadow">Ask the Class</button>
<button id="lifeHint" class="lifeline bg-green-400 hover:bg-green-500 text-white font-medium py-2 px-4 rounded-lg shadow">Ask an Expert</button>
</div>
<div id="poll" class="text-sm text-gray-700 mt-4"></div>
<div id="hint" class="text-sm italic text-gray-600 mt-2"></div>
<button id="next" class="hidden mt-8 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold py-2 px-6 rounded-lg shadow">
Next Question
</button>
</div>
</div>
<script>
window.addEventListener('DOMContentLoaded', () => {
const showError = (msg) => {
const el = document.getElementById('error');
el.textContent = msg;
el.classList.remove('hidden');
};
try {
const questions = [
{ q: "What core problem does Docker reduce by packaging apps with all dependencies?",
choices: ["\"My CPU is too slow\" problem","\"It works on my machine\" problem","Vendor lock-in of cloud credits","I/O bottlenecks from HDDs"],
correct: 1, hint: "Called out explicitly as a dreaded phrase." },
{ q: "Which command verifies a fresh Docker install with a tiny test image?",
choices: ["docker info","docker run hello-world","docker version","docker verify install"],
correct: 1, hint: "It both pulls and runs a simple image." },
{ q: "Best description of image vs. container?",
choices: ["Image is the running process; container is the template","Image is a blueprint; container is a running instance","Both are the same","Container builds images automatically"],
correct: 1, hint: "Blueprint vs. instance." },
{ q: "Which pairing lists Docker’s foundational components?",
choices: ["Daemon (dockerd) and Client (CLI)","Supervisor and Operator","Scheduler and Controller","Planner and Runner"],
correct: 0, hint: "One manages objects; one is your command tool." },
{ q: "On Windows/macOS, which bundle includes daemon, CLI, and tools?",
choices: ["Docker Desktop","Docker Studio","Docker Workstation","Docker Hub Client"],
correct: 0, hint: "Standard local install for devs." },
{ q: "Most well-known public image registry?",
choices: ["Artifact Registry","Docker Hub","Harbor","Quay"],
correct: 1, hint: "Default source for many pulls." },
{ q: "Which pair runs Nginx and maps 80→8080 on host?",
choices: ["docker pull nginx && docker run -d -p 8080:80 nginx","docker build nginx && docker start -p 8080:80 nginx","docker fetch nginx && docker exec -p 8080:80 nginx","docker clone nginx && docker up -p 8080:80"],
correct: 0, hint: "Pull, then run detached with -p host:container." },
{ q: "Which file defines how to build your image?",
choices: ["compose.yaml","Dockerfile","package.json","Container.toml"],
correct: 1, hint: "Plain text build instructions." },
{ q: "Which build/run pair tags and launches on port 5000?",
choices: ["docker build -t myapp:1.0 . && docker run -d -p 5000:5000 myapp:1.0","docker build myapp . && docker start -p 5000:5000 myapp","docker compile -t myapp . && docker exec -p 5000 myapp","docker make -t myapp . && docker deploy -p 5000 myapp"],
correct: 0, hint: "Tag with -t, run with -p host:container." },
{ q: "Day-to-day container lifecycle commands?",
choices: ["docker ps, docker stop, docker rm, docker logs","docker get, docker halt, docker purge, docker read","docker view, docker end, docker delete, docker cat","docker list, docker kill, docker trash, docker echo"],
correct: 0, hint: "Canonical verbs in the article." },
{ q: "Keep images small and efficient by…",
choices: ["Installing all dev tools in final image","Using multi-stage builds and small bases (e.g., alpine)","Bundling multiple apps per container","Avoiding .dockerignore"],
correct: 1, hint: "Less is more." },
{ q: "Reclaim disk by removing unused images:",
choices: ["docker image prune -a","docker images --rm all","docker clean images","docker rmi --unused"],
correct: 0, hint: "Prune is the key." },
{ q: "Simplest built-in clustering for small projects:",
choices: ["Enable Swarm with docker swarm init","Install Kubernetes the hard way","Write a custom scheduler","Use a systemd unit file"],
correct: 0, hint: "Built into Docker." },
{ q: "Swarm vs. Kubernetes — best summary:",
choices: ["Swarm is richer for enterprises","Kubernetes is the de facto standard for large-scale orchestration","Equal production adoption","Swarm has the larger ecosystem"],
correct: 1, hint: "Think ecosystem and adoption." },
{ q: "Kubernetes quick start sequence from the article:",
choices: ["minikube start → kubectl create deployment nginx --image=nginx → kubectl expose deployment nginx --port=80 --type=NodePort",
"kubeadm up → kctl make deploy nginx → kctl service open 80",
"kubestart → kubectl add nginx → kubectl publish 80",
"kind boot → kubectl run nginx --image=nginx → kubectl open service 80"],
correct: 0, hint: "Minikube, create deployment, expose NodePort." }
];
// Evenly redistribute correct answers across A–D
questions.forEach((q, i) => {
const target = i % 4; // 0=A,1=B,2=C,3=D
if (q.correct !== target) {
[q.choices[target], q.choices[q.correct]] = [q.choices[q.correct], q.choices[target]];
q.correct = target;
}
});
const prizes = [100,200,300,500,1000,2000,4000,8000,16000,32000,64000,125000,250000,500000,1000000];
let idx = 0;
let currentPrize = prizes[0];
const qEl = document.getElementById('question');
const cEl = document.getElementById('choices');
const pollEl = document.getElementById('poll');
const hintEl = document.getElementById('hint');
const nextBtn = document.getElementById('next');
const boardEl = document.getElementById('board');
function updateQuestionDisplay() {
qEl.textContent = `$${currentPrize}: ${questions[idx].q}`;
}
function showQuestion() {
// Reset lifelines
['life5050','lifePoll','lifeHint'].forEach(id => {
const btn = document.getElementById(id);
btn.disabled = false;
btn.classList.remove('opacity-50');
});
document.getElementById('error').classList.add('hidden');
pollEl.textContent = '';
hintEl.textContent = '';
nextBtn.classList.add('hidden');
currentPrize = prizes[idx];
updateQuestionDisplay();
cEl.innerHTML = questions[idx].choices.map((ch,i) =>
`<button class="choice bg-indigo-500 hover:bg-indigo-600 text-white font-medium py-2 px-4 rounded w-full" data-i="${i}">
${String.fromCharCode(65+i)}. ${ch}
</button>`
).join('');
document.querySelectorAll('.choice').forEach(btn => {
btn.disabled = false;
btn.onclick = selectAnswer;
});
}
function selectAnswer(e) {
const chosen = +e.currentTarget.dataset.i;
const corr = questions[idx].correct;
document.querySelectorAll('.choice').forEach(b => b.disabled = true);
if (chosen === corr) {
e.currentTarget.classList.replace('bg-indigo-500','bg-green-500');
} else {
e.currentTarget.classList.replace('bg-indigo-500','bg-red-500');
const correctBtn = document.querySelector(`.choice[data-i="${corr}"]`);
if (correctBtn) correctBtn.classList.replace('bg-indigo-500','bg-green-500');
}
nextBtn.classList.remove('hidden');
}
// Lifelines
document.getElementById('life5050').onclick = () => {
const btn = document.getElementById('life5050');
if (btn.disabled) return;
btn.disabled = true; btn.classList.add('opacity-50');
const corr = questions[idx].correct;
[0,1,2,3].filter(i => i !== corr).sort(() => Math.random()-0.5).slice(0,2).forEach(i => {
const b = document.querySelector(`.choice[data-i="${i}"]`);
if (b) { b.disabled = true; b.classList.add('opacity-50'); }
});
currentPrize = Math.floor(currentPrize / 2);
updateQuestionDisplay();
};
document.getElementById('lifePoll').onclick = () => {
const btn = document.getElementById('lifePoll');
if (btn.disabled) return;
btn.disabled = true; btn.classList.add('opacity-50');
const corr = questions[idx].correct;
const pct = [0,0,0,0];
pct[corr] = 70 + Math.floor(Math.random() * 21);
let rem = 100 - pct[corr];
[0,1,2,3].filter(i => i !== corr).forEach((i,j,arr) => {
const last = j === arr.length - 1;
const alloc = last ? rem : Math.floor(rem / (arr.length - j));
pct[i] = alloc; rem -= alloc;
});
pollEl.textContent = `Class Poll: A:${pct[0]}% B:${pct[1]}% C:${pct[2]}% D:${pct[3]}%`;
};
document.getElementById('lifeHint').onclick = () => {
const btn = document.getElementById('lifeHint');
if (btn.disabled) return;
btn.disabled = true; btn.classList.add('opacity-50');
hintEl.textContent = `Expert Hint: ${questions[idx].hint}`;
};
nextBtn.onclick = () => {
idx++;
if (idx < questions.length) {
showQuestion();
} else {
boardEl.innerHTML = '<div class="text-3xl font-bold text-green-600 text-center">🎉 Congratulations! You’ve mastered Concept to Code Millionaire! 🎉</div>';
}
};
// Kickoff
showQuestion();
} catch (err) {
console.error(err);
showError("JavaScript error prevented the questions from rendering. Open the browser console for details.");
}
});
</script>
</body>
</html>