این آزمون هر ۹ درس بخش «ساختن image» را میسنجد. جواب هر سؤال همان لحظه با توضیح نشان داده میشود و نتیجهات در همین مرورگر ذخیره میشود (پیشرفت من).
در docker build -t myapp:1.0 ./site، «./site» چیست؟
context میتواند هر پوشهای باشد؛ COPY فقط به آن دسترسی دارد.
ARG در کانتینر در حال اجرا…
اگر در اجرا لازم است آن را به ENV تبدیل کن.
برای کپی سادهی فایل از context کدام بهتر است؟
ADD رفتارهای اضافه دارد (باز کردن tar، URL).
فرم exec در برابر shell برای CMD؟
برای خاموش شدن تمیز، فرم exec.
با ENTRYPOINT ["ping","-c","2"] و CMD ["localhost"]، دستور docker run img 8.8.8.8 چه اجرا میکند؟
آرگومانها CMD را جایگزین و به ENTRYPOINT اضافه میشوند.
اگر لایهی سوم Dockerfile باطل شود، لایههای بعد از آن…
هر لایه به قبلی وابسته است.
ترتیب بهینه برای یک اپ Node؟
وابستگیها کمتغییرند و باید اول (پایینتر) باشند.
چرا RUN rm در یک لایهی جدا حجم image را کم نمیکند؟
ساخت و پاک کردن را در یک RUN انجام بده.
مهمترین فایدهی امنیتی .dockerignore؟
فایلهای ignoreشده به builder فرستاده نمیشوند.
در .dockerignore ترتیب درست برای ignore کردن همهی md بهجز README.md؟
آخرین الگوی منطبق برنده است.
در multi-stage کدام مرحله image نهایی است؟
با COPY --from فقط نتیجهی لازم را میبری.
چرا در Dockerfile باید npm ci بزنیم نه npm install؟
در production نمیخواهیم نسخهها بیخبر عوض شوند.
در Dockerfile پایتون، PYTHONUNBUFFERED=1 چه میکند؟
وگرنه لاگها دیر یا ناقص دیده میشوند.
در localhost:5301/lx/app:1.0 کدام بخش registry است؟
بخش قبل از اولین اسلش.
برای production کدام tag بهتر است؟
قابلردیابی و قابلبازگشت.
یک سرویس کوچک را از صفر تا registry ببر:
۱. پروژهای با page.html.tmpl (حاوی {{NAME}}) و اسکریپت build.py بساز که قالب را با نام LoopX پر کند و dist/index.html بنویسد.
۲. یک Dockerfile چندمرحلهای بنویس: مرحلهی build با python:3.12-slim (اجرای build.py) و مرحلهی نهایی python:3.12-slim که dist را کپی میکند، با کاربر غیر root (uid 1001) و python -m http.server 8000 --bind 0.0.0.0 اجرا میشود. یک .dockerignore هم بگذار.
۳. یک registry محلی روی پورت 5302 (lx-ch-reg) بالا بیاور و image را با اسم localhost:5302/lx/challenge:1.0 push کن.
۴. image های محلی را پاک کن، دوباره از registry pull کن و روی پورت 8342 اجرا کن؛ ثابت کن صفحه جواب میدهد و پروسه غیر root است.
راهنمایی
برای ثابت کردن غیر root بودن از docker exec ... id -u استفاده کن. برای پر کردن قالب میتوانی از str.replace در Python کمک بگیری.
راهحل
mkdir -p checho '<h1>سلام {{NAME}}</h1>' > ch/page.html.tmplprintf 'from pathlib import Path\nPath("dist").mkdir(exist_ok=True)\nPath("dist/index.html").write_text(Path("page.html.tmpl").read_text().replace("{{NAME}}", "LoopX"))\n' > ch/build.pyprintf '__pycache__\n.env\n.git\ndist\n' > ch/.dockerignorecat > ch/Dockerfile <<'LXEOF'FROM python:3.12-slim AS buildWORKDIR /srcCOPY page.html.tmpl build.py ./RUN python build.py
FROM python:3.12-slimWORKDIR /srvCOPY --from=build /src/dist .RUN useradd -m -u 1001 webUSER webEXPOSE 8000CMD ["python", "-m", "http.server", "8000", "--bind", "0.0.0.0"]LXEOFdocker run -d --name lx-ch-reg -p 5302:5000 registry:2 >/dev/null; sleep 2docker build -q -t localhost:5302/lx/challenge:1.0 ./ch >/dev/null 2>&1docker push localhost:5302/lx/challenge:1.0 2>&1 | tail -1 | cut -c1-80docker rmi localhost:5302/lx/challenge:1.0 >/dev/nulldocker run -d --name lx-ch1 -p 8342:8000 localhost:5302/lx/challenge:1.0 2>&1 | tail -1 | cut -c1-12sleep 3curl -s localhost:8342docker exec lx-ch1 id -udocker rm -f lx-ch1 lx-ch-reg >/dev/null; docker rmi localhost:5302/lx/challenge:1.0 >/dev/null1.0: digest: sha256:4725f651e910ed59b6326ea5867686fdc03ff6129edeb2637667f0b07f2fdfd2b318601f<h1>سلام LoopX</h1>1001