Docker میتواند اختلاف محیط را کم کند، اما آن را جادویی حذف نمیکند. یک Compose stack با Image tag متغیر، Secret داخل YAML، Database بدون Healthcheck و Volume مشترک شاید روی لپتاپ شما سبز شود و در CI شکست بخورد. اگر بعد هم با یک دستور عمومی همهٔ دادهها را پاک کنید، «ایزولهسازی» به Incident تبدیل میشود.
راهحل، صرفاً `docker compose up` نیست؛ یک Docker Test Environment Contract لازم است: Host/Engine/Compose fingerprint، Image digest، Project namespace، Readiness، Migration/Seed، داده و Secret، Fault/Oracle، Evidence و Cleanup scope. این راهنما همان قرارداد را برای تیم QA ایرانی میسازد.
پاسخ کوتاه: محیط تست پایدار با Docker چگونه ساخته میشود؟
- Claim و Fidelity لازم را پیش از انتخاب Docker تعریف کنید.
- Engine/Compose/OS/Kernel/Architecture را Fingerprint کنید.
- Compose Specification و CLI version را Pin و `compose.yaml` را Validate کنید.
- برای هر Run یک Project/Namespace یکتا بسازید.
- Image را با Tag خوانا و Digest immutable ثبت کنید؛ Update را مدیریتشده انجام دهید.
- Secret را از YAML/Repo/Log بیرون نگه دارید و Service access را محدود کنید.
- `depends_on` را با Healthcheck/Readiness و Migration completion تکمیل کنید.
- Data/Seed/Clock/Locale/Fault/Oracle را نسخهدار کنید.
- Run Manifest، log/inspect/test evidence و Cleanup receipt بسازید.
- Volume را فقط با Target صریح و تأیید Disposable بودن حذف کنید؛ Prune عمومی نکنید.
Intent این مقاله؛ Contract و Evidence، نه Compose مبتدی
انتخاب Local/VM/Container/Kubernetes/Cloud در معماری محیط تست مدرن انجام میشود؛ آموزش مقدماتی syntax در Docker Compose برای محیط تست و عیبیابی عملی در لَب Docker برای تسترها. این صفحه مالک Reproducibility/Isolation/Safety/Evidence contract یک stack تست است.
Docker چه چیزی را ایزوله میکند و چه چیزی را نه؟
| Boundary | کمک Docker | چیزی که خودکار حل نمیشود |
|---|---|---|
| Process/filesystem | Namespace/layer/mount جداتر | Kernel shared، privilege، Docker socket |
| Dependency | Image و package bundle | Tag mutation، registry، external API |
| Network | Compose network/service DNS | Host route، DNS، proxy، latency، firewall |
| Data | Volume/tmpfs و project scoping | Seed semantics، shared/external volume، deletion |
| Platform | Platform-specific image | CPU architecture، Desktop VM، kernel/driver |
| Production fidelity | بعضی artifact/configها مشترک | Scale، managed service، IAM، topology، device |
Container «جعبهٔ کاملاً بسته» یا VM سبک نیست. Linux container روی Docker Desktop ممکن است داخل VM اجرا شود و Behaviour فایل/شبکه/Clock با Linux CI فرق کند. Production-like را به Dimensionهای مشخص بشکنید؛ هیچ stack محلی دقیقاً Production نیست.
Environment Claim؛ اول بگویید چه چیزی باید تکرار شود
EnvironmentClaim-ID: Workflow/test/decision: System boundary: Fidelity dimensions required: Dimensions intentionally simplified: Image/config/data versions: External dependencies/mocks: OS/kernel/architecture constraints: Network/time/locale assumptions: Expected fault/oracle: Evidence required: Known gaps: Owner / review date:
«روی Docker پاس شد» Claim مبهم است. شاید فقط API contract روی PostgreSQL خاص را پوشش دادهاید؛ این نتیجهٔ Browser/device، Production IAM، latency، backup یا capacity نیست.
Host Fingerprint؛ Container روی خلأ اجرا نمیشود
HostFingerprint: OS/version: Kernel: CPU architecture: Docker Engine/version/context: Docker Compose version: Docker Desktop/VM settings if applicable: CPU/memory/disk limits: Filesystem/mount mode: Network/DNS/proxy: Timezone/clock sync: Registry/config policy: Captured-at: Fingerprint digest:
برای اختلاف «روی ماشین من کار میکند»، از راهنمای Fingerprint و Environment Delta استفاده کنید. Host detail را همراه Secret چاپ نکنید؛ خروجی Context/Proxy/registry config میتواند حساس باشد.
Compose Specification؛ `version: ‘۳.۸’` دیگر Gate نیست
Compose file reference رسمی، Compose Specification را فرمت توصیهشده میداند. صفحهٔ Version and name نیز میگوید top-level `version` فقط برای backward compatibility، informative و obsolete است؛ Compose schema جاری را مستقل از آن بهکار میبرد.
پس `version: ‘۳.۸’` سازگاری را ثابت نمیکند. CLI/Engine feature support را Pin کنید، `docker compose config –quiet` را در Local و CI اجرا و Effective model را—پس از Redaction—به Evidence وصل کنید.
ComposeManifest: Repository/commit: Compose files/order: Compose CLI/version: Engine/context: Profiles: Project-name rule: Interpolation inputs: Config validation result: Effective service/network/volume names: Feature minimum versions: Redacted config digest: Unknown/warning: Owner/review:
Project Namespace؛ هر Run نام خودش را داشته باشد
Compose منابع را معمولاً با Project name scope میکند. یک نام تصادفی و غیرقابلردیابی هم خوب نیست؛ Run ID، Repo و Attempt را به Project map کنید و Character/length rule داشته باشید. Port، Dataset namespace و Evidence path نیز باید با همان Run مرتبط باشند.
RunNamespace: Run-ID: Project name: Repository/commit: Pipeline/job/attempt: Port allocation: Database/schema/tenant prefix: Object/storage/queue prefix: Network/volume labels: Evidence directory: Created-at / TTL: Cleanup owner:
نام دستی ثابت مانند `myapp` در Parallel CI میتواند Volume/Network/Container را مشترک کند. External resource نیز خودکار project-scoped نیست؛ برای هرکدام Namespace و Cleanup مستقل لازم است.
Image Contract؛ Tag خوانا، Digest دقیق، Update قابلکنترل
راهنمای رسمی Docker build best practices توضیح میدهد Tagها mutable هستند و Digest محتوای ثابت را Pin میکند. `latest` یا حتی `postgres:۱۶` دقیقاً همان Artifact فردا را تضمین نمیکند.
ImageRecord: Service: Registry/repository: Human-readable tag: Manifest/platform digest: OS/architecture: Build source/commit: Build args/base digests: Provenance/signature/SBOM: Vulnerability snapshot: License/source policy: Pulled-at/from-context: Update/rollback owner: Expiry/review:
Digest pinning Reproducibility میدهد، نه Patch management. Update bot/PR، Vulnerability review، matched test و Rollback digest لازماند. Docker Official Image یا موفقیت Pull، امنیت/سازگاری Application را ثابت نمیکند.
Reference Compose؛ قرارداد است، نه Copy/Paste آماده
نمونهٔ زیر عمداً Placeholder دارد و تا جایگزینی Digest، Image، command و Secret مصنوعی اجراشدنی نیست. هدف، نشاندادن Boundaryهاست:
services:
db:
image: postgres:16.4@sha256:<DATABASE_IMAGE_DIGEST>
environment:
POSTGRES_USER: test_user
POSTGRES_DB: test_db
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
healthcheck:
test: ["CMD-SHELL", "pg_isready -U test_user -d test_db"]
interval: 5s
timeout: 3s
retries: 12
start_period: 10s
networks: [backend]
volumes:
- db_data:/var/lib/postgresql/data
migrate:
image: registry.example.invalid/app@sha256:<APP_IMAGE_DIGEST>
command: ["./app", "migrate"]
depends_on:
db:
condition: service_healthy
secrets: [db_password]
networks: [backend]
app:
image: registry.example.invalid/app@sha256:<APP_IMAGE_DIGEST>
read_only: true
tmpfs: [/tmp]
cap_drop: [ALL]
ports:
- "127.0.0.1:${APP_PORT:?set APP_PORT}:8080"
depends_on:
migrate:
condition: service_completed_successfully
secrets: [db_password]
healthcheck:
test: ["CMD", "./app", "healthcheck"]
interval: 5s
timeout: 3s
retries: 12
networks: [frontend, backend]
tests:
image: registry.example.invalid/tests@sha256:<TEST_IMAGE_DIGEST>
profiles: [test]
command: ["./run-tests", "--target", "http://app:8080"]
depends_on:
app:
condition: service_healthy
networks: [frontend]
secrets:
db_password:
file: ./.secrets/db_password
volumes:
db_data:
labels:
ir.testrail.qa.disposable: "true"
networks:
frontend:
backend:
internal: true
`registry.example.invalid` عمداً غیرواقعی است. `cap_drop`, `read_only`, health command، Network و Secret convention باید با Image واقعی PoC شوند. Health endpoint نباید فقط Process alive را بسنجد؛ Dependency و Ready-for-test semantics را تعریف کنید.
`depends_on` با Readiness برابر نیست
راهنمای رسمی Compose startup order تصریح میکند Compose بهطور پیشفرض Running شدن را میبیند، نه Ready شدن. `condition: service_healthy` برای Healthcheck و `service_completed_successfully` برای Migration/Seed یکباره، Race را آشکارتر میکنند.
- Healthcheck باید همان قابلیت لازم برای Test را Probe کند؛
- Start period/interval/timeout/retry باید از Baseline بیاید؛
- Migration idempotent و Result/Version قابلمشاهده باشد؛
- Seed completion، Dataset digest و Count/Invariant بدهد؛
- App retry باید bounded و قابلمشاهده باشد؛
- Healthy یک لحظه، Stability/SLO را تضمین نمیکند؛
- Test Runner باید expected target و zero-selection را Gate کند.
Readiness Contract؛ HTTP ۲۰۰ کافی نیست
Readiness-ID: Service/capability: Probe command/endpoint: Auth/data safety: Success semantics: Dependency scope: Migration/schema version: Warm-up/cache state: Timeout/retry/backoff: Failure evidence: False-ready risk: Startup baseline: Owner/review:
`/health` ممکن است فقط Web process را ببیند و Database schema یا Queue consumer آماده نباشد. Probe را کمخطر، بدون دادهٔ واقعی و Claim-specific طراحی کنید.
Secret و Config؛ Environment variable مخزن Secret نیست
راهنمای رسمی Docker Compose secrets هشدار میدهد Password/API key در Environment variable میتواند ناخواسته Exposure یا Log شود؛ Secretها به Serviceهای مجاز بهصورت file mount داده میشوند. این مکانیزم بهتنهایی Encryption-at-rest، Rotation یا Production-grade secret management نیست.
SecretContract: Secret-ID/purpose: Synthetic vs real: Issuer/source: Allowed services: Mount/reference only: Denied in repo/image/env/log/report: TTL/rotation/revocation: Leak scan: Owner: Incident path: Deletion receipt:
برای Test local از Credential مصنوعی و کماختیار استفاده کنید. `.env` را بیدلیل Safe فرض نکنید؛ Interpolation precedence و Effective config را Validate و قبل از انتشار Redact کنید.
Network و Port؛ فقط آنچه لازم است Publish کنید
- Serviceها روی Network مشترک با Service name ارتباط میگیرند؛ Host port برای همه لازم نیست؛
- Database را فقط برای Client host واقعی publish کنید؛
- Bind به `۱۲۷.۰.۰.۱` Exposure را از همهٔ Interfaceها محدودتر میکند؛
- Backend network را در صورت Fit داخلی کنید؛
- Port یکتا برای Parallel Run و Collision receipt داشته باشید؛
- External DNS/API را Allowlist و Fault-injectable کنید؛
- Proxy/TLS/CA را در Fingerprint ثبت کنید؛ Verification را خاموش نکنید.
Network داخلی Docker Internet یا Host policy را شبیهسازی کامل نمیکند. Latency/loss/reorder و Service discovery در Production باید آزمایش جدا داشته باشند.
Volume Strategy؛ Persistence را آگاهانه انتخاب کنید
| Storage | کاربرد | ریسک |
|---|---|---|
| Container writable layer | موقت/کمحجم | پنهان و با recreate از دست میرود |
| tmpfs | Ephemeral sensitive/scratch | memory pressure و عدم persistence |
| Named volume | DB/cache قابلمدیریت | stale/shared data و حذف ناخواسته |
| Bind mount | Source/config/evidence مشخص | host permission/path/OS drift |
| External volume | مالکیت بیرون stack | Compose آن را پاک نمیکند؛ lifecycle جدا |
VolumeRecord: Volume/project/label: Purpose/data class: Owner: Created-by run: Persistent or disposable: Seed/snapshot/schema: Backup/restore required?: Retention/TTL: Consumers: Deletion authority: Pre-delete inventory: Deletion/retention receipt:
«Test data است» مساوی Disposable نیست. Evidence، golden snapshot، migration sample یا shared cache ممکن است لازم باشد. هر Volume باید Owner و lifecycle داشته باشد.
`docker compose down –volumes`؛ حذف هدفمند، نه Reset عمومی
مرجع رسمی docker compose down میگوید `–volumes` هم Named volumeهای Compose file و هم Anonymous volumeهای متصل را حذف میکند؛ External volume حذف نمیشود. پس `down -v` را Recipe همیشگی نگذارید.
- Project name را به Run record resolve کنید.
- Containers/networks/volumes همان Project را Inventory کنید.
- Label، Owner، data class و Disposable flag را بررسی کنید.
- Evidence/backup موردنیاز را Extract و Verify کنید.
- ابتدا `down` بدون Volume برای توقف scope اجرا کنید.
- فقط با Project literal تأییدشده و مجوز حذف، Volumeهای همان Lab را پاک کنید.
- پس از حذف، absence و external-resource remainder را ثبت کنید.
نمونهٔ `docker compose -p qa-lab-syn-۰۰۱ down –volumes` فقط برای Project مصنوعیِ دقیقاً Inventoryشده است؛ نام را کورکورانه جایگزین نکنید. Volume مشترک یا External lifecycle جدا دارد.
چرا `docker system prune -a` راهنمای نگهداری نیست؟
راهنمای رسمی Docker pruning نشان میدهد Prune دامنهای فراتر از Project جاری دارد؛ `-a` همهٔ Imageهای بدون Container مرتبط را میتواند حذف کند و `–volumes` دامنه را به Volumeهای unused گسترش میدهد. این دستور Cleanup روزمرهٔ مقاله نیست.
برای Disk pressure، اول Usage/Owner/age/label را Inventory کنید، Scope محدود و Filter قابلبررسی بسازید و Approval بگیرید. حذف Cache/Image میتواند CI offline، Rollback یا Reproduction را خراب کند.
Data Contract؛ دیتابیس «خام» لزوماً Test-ready نیست
DatasetManifest: Dataset-ID/version/digest: Synthetic or approved masked source: Schema/migration version: Seed/generator version: Run/tenant namespace: Canonical currency/time/locale: Counts/invariants: Expected edge/fault cases: PII/secret scan: Setup receipt: Cleanup/reconciliation: Owner/expiry:
برای انتخاب دادهٔ واقعی/مصنوعی و Privacy، راهنمای مدیریت دادهٔ تست را ببینید. SQL داخل entrypoint فقط روی Initialization خاص اجرا میشود و Reset semantics عمومی نیست؛ Migration/Seed را observable و idempotent کنید.
Service Virtualization؛ Mock را Production جا نزنید
WireMock/Stub میتواند SMS/Payment/API خارجی را deterministic و fault-injectable کند، اما Contract drift، Auth، latency، quota و side effect واقعی را خودکار اثبات نمیکند. راهنمای مجازیسازی سرویس با WireMock برای Mapping، state، fault و evidence مرز دقیق میدهد.
Fault Matrix؛ فقط Happy-path Compose نسازید
| Fault | Observation | Claim محدود |
|---|---|---|
| DB slow/unhealthy | Health timeout/retry/app state | Readiness handling |
| Migration fail/partial | Exit/evidence/schema | No test start on bad schema |
| Duplicate seed | Count/invariant/idempotency | Setup repeatability |
| Registry unavailable | Pull/cache/digest/fallback | Artifact continuity |
| Wrong architecture | Manifest/runtime failure | Platform compatibility |
| Port collision | Startup failure/run namespace | Parallel isolation |
| Disk/volume pressure | write failure/cleanup | Resource behaviour |
| Clock/locale drift | domain/parser/order | Iran edge coverage |
Iran-aware Fixture؛ Locale را به Host واگذار نکنید
- IRR canonical و تومان فقط نمایش با نسبت ۱ تومان = ۱۰ ریال؛
- ISO currency/amount integer و round rule؛
- رقم فارسی/عربی/لاتین؛
- ی/ی، ک/ک و ZWNJ؛
- RTL/LTR/Bidi در log/report/UI؛
- UTC، Asia/Tehran و مرز روز؛
- جلالی فقط Presentation مگر Contract خلاف آن بگوید؛
- Unicode normalization و filename/URL encoding؛
- Timeout/retry/duplicate/late/reordered callback؛
- دادهٔ کاملاً مصنوعی و بدون کارت/کدملی/مشتری واقعی.
Registry و دسترسی ایران؛ Artifact را تاریخدار کنید
موفقیت Pull امروز Availability فردا نیست. Registry، account/Terms/region، tag/digest، platform و زمان را ثبت کنید. اگر دسترسی رسمی پایدار نیست، Registry/mirror/cache سازمانیِ مجاز با Provenance، digest/signature، update و revocation طراحی کنید؛ هویت/موقعیت جعلی، Proxy ناشناس یا TLS bypass نسخهٔ عمومی نیست. Runbook تداوم در تداوم ابزار QA این تصمیم را پوشش میدهد.
Run Manifest؛ چه چیزی واقعاً اجرا شد؟
RunManifest: Run/project/attempt: Repository/commit/dirty state: Compose files/config digest: Engine/Compose/host fingerprint: Services/image/platform digests: Configs/secrets references: Network/port map: Dataset/migration/seed digests: Clock/timezone/locale: Faults/target/oracles: Test selection/expected count: Resource budget: Started/ended/status: Evidence index:
`docker compose ps`, image inspect، Health status، redacted config، service logs، migration/seed receipts و test report را با Timestamp جمع کنید. Raw log ممکن است Secret/PII داشته باشد؛ Allowlist/Redaction و Retention لازم است.
Local تا CI؛ Parity را با Manifest بسنجید
در CI نیز Local و Runner را روی commit، Compose version، image digest، platform، Dataset، Secret reference، test selection و resource budget مقایسه کنید؛ یک Compose file مشترک Parity را خودکار ثابت نمیکند.
- CI Project/port/data namespace یکتا؛
- Pull policy و offline/cache behaviour روشن؛
- Secret از CI store با least privilege؛
- Health/Migration timeout متناسب، نه sleep ثابت؛
- Test exit code و expected count Gate؛
- Artifact upload قبل از Cleanup؛
- Cleanup در success/failure/cancel با Receipt؛
- Runner disk/CPU/memory baseline و contention evidence.
Bug Reproduction؛ Compose file تنها Artifact نیست
یک Reproduction معتبر به Trigger، pre-state، exact image/config/data، steps، Expected/Actual، attempt، evidence و cleanup نیاز دارد. قرارداد گزارش باگ قابلبازتولید کمک میکند Compose stack را به Claim محدود وصل کنید.
Cleanup Contract؛ پایان Run بخشی از Test است
CleanupRecord: Run/project literal: Resources expected: Evidence extracted/verified: Containers stopped/removed: Networks removed/retained: Volumes removed/retained + authority: Images/cache retained policy: External objects/queues/files: Secrets revoked/deleted: Residual inventory: Failure/retry/escalation: Completed-at / owner: Receipt digest:
Cleanup PASS یعنی State هدف با Evidence محقق شده، نه اینکه command exit zero بوده است. اگر حذف ناقص شد، Run را CLOSED ننویسید؛ residual resource و Owner را ثبت کنید.
Metric و Countermetric محیط Docker
- Startup time همراه با false-ready/timeout؛
- Reproduction rate همراه با Claim/Fidelity gap؛
- Flake rate همراه با hidden retry؛
- Parallel success همراه با collision/leak؛
- Environment drift همراه با security update lag؛
- Cleanup success همراه با accidental deletion/residual؛
- Image reuse همراه با stale/vulnerable digest؛
- Local-CI parity همراه با resource/platform difference.
شروع در چند ثانیه یا تعداد Container کیفیت نیست. Countermetric مانع میشود با Health سطحی، Retry یا حذف تهاجمی Dashboard را سبز کنید.
آزمایشگاه آفلاین ایرانی
SYN-DOCKER-QA-LAB-IR-01 یک Host، Registry، سه Image، Compose stack، DB، App، Mock، Runner، Volume و Pipeline کاملاً ساختگی در حافظه است. هیچ Host، Repository، Registry، Image، Secret، Database، Service، Customer data، Pipeline، Production، deletion یا Release decision واقعی ندارد و هیچ Docker daemon یا شبکهای را فراخوانی نمیکند.
Fixture شامل Checkout/Order/PaymentAttempt/PSP Stub/Callback/Ledger/Reconciliation ساختگی، canonical IRR و تومان نمایشی ۱:۱۰، رقم فارسی/عربی/لاتین، ی/ی، ک/ک، ZWNJ، RTL/LTR/Bidi، UTC/Asia–Tehran و جلالی فقط نمایشی است. Faultها Tag mutation، wrong architecture، registry timeout، secret leak، DB false-ready، partial migration، duplicate seed، port/namespace collision، volume reuse، hidden retry و cleanup failure هستند.
Checker سطحی چگونه محیط جعلی را سبز میکند؟
Checker سطحی «Docker جادویی»، «Production-identical»، «چند ثانیه»، «صفر Flake»، `down -v` و `prune -a` را میبیند و بهاشتباه میگوید:
DOCKER_MAGIC_IDENTICAL_PRODUCTION_SECONDS_ZERO_FLAKE_DOWN_V_PRUNE_A_READY
این خروجی Host، digest، readiness، data، Secret، Fidelity، Evidence یا Deletion scope را بررسی نکرده و False green است.
Validator مستقل؛ ۹۸۸ کنترل و HOLD
Validator مستقل ۷۶ گروه—از host/engine/compose/project/image تا digest/network/readiness/data/secret/fault/evidence/CI/fidelity/cleanup/security/Iran/review—را با ۱۳ کنترل group-qualified میسازد. Assertion یکتایی دقیقاً ۹۸۸ کنترل را الزام میکند:
HOLD-988 NO_REAL_HOST_REPOSITORY_REGISTRY_IMAGE_SECRET_DATABASE_SERVICE_CUSTOMER_DATA_PIPELINE_PRODUCTION_DELETION_OR_RELEASE_DECISION_PASS
قاعدهٔ دوم مستقل از شمارش ثابت میکند Lab به Docker یا Target واقعی متصل نیست؛ از آن نمیتوان Reproducibility، isolation، security، cleanup یا Release واقعی را نتیجه گرفت.
پس از اصلاح؛ فقط آمادگی Contract Review
پس از پینشدن Host/Compose/Image/Readiness/Data/Secret/Fault/Evidence/CI/Fidelity/Cleanup ساختگی، خروجی میشود:
READY_FOR_DOCKER_TEST_ENVIRONMENT_CONTRACT_REVIEW-0
صفر فقط یعنی فیلد Lab جا نیفتاده؛ نه اینکه Image امن، محیط Production-identical، Test معتبر، Secret محفوظ، داده پاک، Cleanup بیخطر یا Release آماده است.
۳۰ ضدالگوی Docker Test Environment
- Docker جادویی؛
- Container کاملاً ایزوله؛
- Production-identical؛
- `version: ۳.۸` مساوی compatibility؛
- CLI بینسخه؛
- Project name ثابت؛
- `latest`؛
- Tag مساوی artifact؛
- Digest بدون update؛
- Pull مساوی trust؛
- `depends_on` مساوی ready؛
- Sleep ثابت؛
- HTTP ۲۰۰ مساوی readiness؛
- Migration بیreceipt؛
- Seed غیرidempotent؛
- DB خام مساوی test-ready؛
- Secret در YAML/env/log؛
- همهٔ Portها روی ۰.۰.۰.۰؛
- Docker socket mount؛
- Root بینیاز؛
- Volume بیowner؛
- `down -v` عمومی؛
- `prune -a` دورهای؛
- Mock مساوی dependency؛
- Compose file مساوی Local-CI parity؛
- Retry مساوی پایداری؛
- Log بیredaction؛
- Cleanup exit zero مساوی پاکی؛
- Registry bypass ناشناس؛
- READY مساوی Release.
برنامهٔ ۳۰روزهٔ Docker Contract Trial
- روز ۱ تا ۴: Claim، Fidelity و Host/Compose fingerprint را بسازید.
- روز ۵ تا ۸: Project namespace، Image record و digest/update policy را پین کنید.
- روز ۹ تا ۱۲: Readiness، Migration و Seed idempotency را Fault-test کنید.
- روز ۱۳ تا ۱۶: Network/Port/Secret/user/read-only boundary را مرور کنید.
- روز ۱۷ تا ۲۰: Dataset/Volume/Retention و حذف هدفمند مصنوعی را تمرین کنید.
- روز ۲۱ تا ۲۴: Registry/architecture/clock/locale/mock faults را اجرا کنید.
- روز ۲۵ تا ۲۷: Run Manifest، Evidence/Redaction و Local-CI delta را ببندید.
- روز ۲۸: Cleanup failure و residual-resource reconciliation را آزمایش کنید.
- روز ۲۹: Reviewer مستقل Claim/Fidelity/Safety را نقد کند.
- روز ۳۰: Correction plan؛ Lab هیچ Docker target یا deletion واقعی اجرا نمیکند.
چکلیست ۵۸نقطهای محیط تست Docker
- Claim؛
- Owner؛
- Host OS؛
- Kernel؛
- Architecture؛
- Engine؛
- Compose CLI؛
- Compose files؛
- Config validation؛
- Project name؛
- Run namespace؛
- Commit؛
- Service inventory؛
- Registry؛
- Tag؛
- Digest؛
- Platform؛
- Provenance/SBOM؛
- Vulnerability review؛
- Update/rollback؛
- Network؛
- Port binding؛
- Dependency؛
- Healthcheck؛
- Readiness؛
- Migration؛
- Seed؛
- Dataset digest؛
- Schema؛
- Data class؛
- Volume owner؛
- Disposable flag؛
- Bind/tmpfs؛
- Secret reference؛
- Leak scan؛
- Config/env precedence؛
- User/capability؛
- Read-only filesystem؛
- Resource budget؛
- Clock/timezone؛
- Locale/Unicode؛
- IRR/toman؛
- Mock contract؛
- Fault matrix؛
- Oracle؛
- Test selection/count؛
- Attempt/retry؛
- Logs/traces؛
- Redaction؛
- Run manifest؛
- CI delta؛
- Fidelity gap؛
- Evidence archive؛
- Cleanup scope؛
- Deletion authority؛
- Residual inventory؛
- Receipt؛
- Review/Correction.
جمعبندی؛ Compose را به قرارداد آزمایش تبدیل کنید
Docker اختلاف محیط را فقط وقتی کاهش میدهد که Host/Compose/Image/Platform/Data/Clock و External dependency معلوم باشند. Tag mutable را با Digest و Update workflow کنترل کنید، Project را per-run scope کنید و Readiness/Migration/Seed را بهجای Start order یا Sleep ثابت بسنجید.
Secret را از Repo/Env/Log دور نگه دارید، Fidelity gap را صادقانه اعلام و Run Evidence را پیش از Cleanup ذخیره کنید. `down –volumes` فقط برای Project و Volume تأییدشده است و Prune عمومی برنامهٔ نگهداری نیست. محیط پایدار، Stackی است که ایجاد، مشاهده، شکست، تکرار و حذفش قابلردیابی باشد.
پرسشهای متداول Docker برای محیط تست
آیا Docker محیطی کاملاً مشابه Production میسازد؟
خیر. میتواند Image/config/dependencyهای مشخص را نزدیک کند، اما Host kernel، architecture، managed service، network، IAM، scale و device ممکن است متفاوت باشند. Fidelity را DimensionبهDimension ثبت کنید.
آیا `depends_on` یعنی دیتابیس آماده است؟
بهتنهایی نه. Running با Ready فرق دارد. Healthcheck معنادار و `condition: service_healthy`، سپس Migration/Seed completion و App-level readiness لازماند.
برای Reset دیتابیس همیشه `down -v` بزنیم؟
خیر. این گزینه Named و Anonymous volumeهای stack را حذف میکند. Project/Volume/Data class/Owner را Inventory، Evidence را حفظ و فقط Volume مصنوعی و صریحاً Disposable را با مجوز حذف کنید.
Tag نسخهدار برای تکرارپذیری کافی است؟
نه همیشه؛ Tag میتواند جابهجا شود. Digest Artifact دقیق را Pin میکند، اما Patch/Vulnerability را منجمد میکند؛ Update PR، Retest و Rollback digest لازم است.
آیا `docker system prune -a` برای آزادکردن فضا مناسب است؟
نسخهٔ عمومی دورهای نیست؛ دامنهاش فراتر از Project شماست و میتواند Image/Cache لازم برای Reproduction یا کار دیگران را حذف کند. Usage و Owner را Inventory و Cleanup محدود/تأییدشده طراحی کنید.

