[{"data":1,"prerenderedAt":1754},["ShallowReactive",2],{"article-docker-for-ml-engineers":3,"content-query-lGX0PVskFz":989},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"body":11,"_type":983,"_id":984,"_source":985,"_file":986,"_stem":987,"_extension":988},"\u002Farticles\u002Fdocker-for-ml-engineers","articles",false,"","Docker for ML Engineers Who Just Want to Ship a Model","A practical Docker guide for ML engineers — writing Dockerfiles for model serving, keeping images small with multi-stage builds, handling GPUs with NVIDIA base images, and pushing to a registry.","2025-07-11",{"type":12,"children":13,"toc":960},"root",[14,22,28,33,40,45,55,68,79,84,95,100,111,124,131,226,232,253,281,290,295,301,306,312,317,326,347,353,371,420,475,483,511,517,522,531,536,581,593,599,604,636,645,665,670,681,686,692,697,705,710,716,721,727,736,741,747,756,762,767,776,782,795,800,869,874,880,885,894,899,908,913,922,935,939],{"type":15,"tag":16,"props":17,"children":19},"element","h1",{"id":18},"docker-for-ml-engineers-who-just-want-to-ship-a-model",[20],{"type":21,"value":8},"text",{"type":15,"tag":23,"props":24,"children":25},"p",{},[26],{"type":21,"value":27},"You know Python. You can train a model, write a serving script, and get predictions out of an API endpoint. But someone keeps saying you need to \"containerize it,\" and the Docker documentation reads like it was written for infrastructure engineers.",{"type":15,"tag":23,"props":29,"children":30},{},[31],{"type":21,"value":32},"This article skips the container philosophy and goes straight to: here's how to put your model in a Docker image so other people can run it.",{"type":15,"tag":34,"props":35,"children":37},"h2",{"id":36},"the-minimum-viable-dockerfile",[38],{"type":21,"value":39},"The minimum viable Dockerfile",{"type":15,"tag":23,"props":41,"children":42},{},[43],{"type":21,"value":44},"Say you have a directory with these files:",{"type":15,"tag":46,"props":47,"children":49},"pre",{"code":48},"my-model\u002F\n├── serve.py\n├── model.pkl\n└── requirements.txt\n",[50],{"type":15,"tag":51,"props":52,"children":53},"code",{"__ignoreMap":7},[54],{"type":21,"value":48},{"type":15,"tag":23,"props":56,"children":57},{},[58,60,66],{"type":21,"value":59},"Your ",{"type":15,"tag":51,"props":61,"children":63},{"className":62},[],[64],{"type":21,"value":65},"serve.py",{"type":21,"value":67}," is a FastAPI app:",{"type":15,"tag":46,"props":69,"children":74},{"code":70,"language":71,"meta":7,"className":72},"import pickle\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nwith open(\"model.pkl\", \"rb\") as f:\n    model = pickle.load(f)\n\n@app.get(\"\u002Fhealth\")\ndef health():\n    return {\"status\": \"ok\"}\n\n@app.post(\"\u002Fpredict\")\ndef predict(features: list[float]):\n    result = model.predict([features])\n    return {\"prediction\": int(result[0])}\n","python",[73],"language-python",[75],{"type":15,"tag":51,"props":76,"children":77},{"__ignoreMap":7},[78],{"type":21,"value":70},{"type":15,"tag":23,"props":80,"children":81},{},[82],{"type":21,"value":83},"Here's the Dockerfile:",{"type":15,"tag":46,"props":85,"children":90},{"code":86,"language":87,"meta":7,"className":88},"FROM python:3.11-slim\n\nWORKDIR \u002Fapp\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY serve.py model.pkl .\u002F\n\nCMD [\"uvicorn\", \"serve:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n","dockerfile",[89],"language-dockerfile",[91],{"type":15,"tag":51,"props":92,"children":93},{"__ignoreMap":7},[94],{"type":21,"value":86},{"type":15,"tag":23,"props":96,"children":97},{},[98],{"type":21,"value":99},"Build and run:",{"type":15,"tag":46,"props":101,"children":106},{"code":102,"language":103,"meta":7,"className":104},"docker build -t my-model:v1 .\ndocker run -p 8000:8000 my-model:v1\n","bash",[105],"language-bash",[107],{"type":15,"tag":51,"props":108,"children":109},{"__ignoreMap":7},[110],{"type":21,"value":102},{"type":15,"tag":23,"props":112,"children":113},{},[114,116,122],{"type":21,"value":115},"That's it. Hit ",{"type":15,"tag":51,"props":117,"children":119},{"className":118},[],[120],{"type":21,"value":121},"http:\u002F\u002Flocalhost:8000\u002Fhealth",{"type":21,"value":123}," and you should get a response.",{"type":15,"tag":125,"props":126,"children":128},"h3",{"id":127},"what-each-line-does",[129],{"type":21,"value":130},"What each line does",{"type":15,"tag":132,"props":133,"children":134},"ul",{},[135,159,173,198,212],{"type":15,"tag":136,"props":137,"children":138},"li",{},[139,149,151,157],{"type":15,"tag":140,"props":141,"children":142},"strong",{},[143],{"type":15,"tag":51,"props":144,"children":146},{"className":145},[],[147],{"type":21,"value":148},"FROM python:3.11-slim",{"type":21,"value":150}," — start from a base image that already has Python installed. The ",{"type":15,"tag":51,"props":152,"children":154},{"className":153},[],[155],{"type":21,"value":156},"slim",{"type":21,"value":158}," variant is a stripped-down Debian image (~150 MB instead of ~900 MB).",{"type":15,"tag":136,"props":160,"children":161},{},[162,171],{"type":15,"tag":140,"props":163,"children":164},{},[165],{"type":15,"tag":51,"props":166,"children":168},{"className":167},[],[169],{"type":21,"value":170},"WORKDIR \u002Fapp",{"type":21,"value":172}," — set the working directory inside the container. All subsequent commands run from here.",{"type":15,"tag":136,"props":174,"children":175},{},[176,185,187,196],{"type":15,"tag":140,"props":177,"children":178},{},[179],{"type":15,"tag":51,"props":180,"children":182},{"className":181},[],[183],{"type":21,"value":184},"COPY requirements.txt .",{"type":21,"value":186}," then ",{"type":15,"tag":140,"props":188,"children":189},{},[190],{"type":15,"tag":51,"props":191,"children":193},{"className":192},[],[194],{"type":21,"value":195},"RUN pip install",{"type":21,"value":197}," — install dependencies first, before copying the rest of the code. Docker caches each layer, so if your code changes but your dependencies don't, pip install won't re-run.",{"type":15,"tag":136,"props":199,"children":200},{},[201,210],{"type":15,"tag":140,"props":202,"children":203},{},[204],{"type":15,"tag":51,"props":205,"children":207},{"className":206},[],[208],{"type":21,"value":209},"COPY serve.py model.pkl .\u002F",{"type":21,"value":211}," — copy your application code and model into the container.",{"type":15,"tag":136,"props":213,"children":214},{},[215,224],{"type":15,"tag":140,"props":216,"children":217},{},[218],{"type":15,"tag":51,"props":219,"children":221},{"className":220},[],[222],{"type":21,"value":223},"CMD [...]",{"type":21,"value":225}," — the command that runs when the container starts.",{"type":15,"tag":125,"props":227,"children":229},{"id":228},"the-layer-caching-trick",[230],{"type":21,"value":231},"The layer caching trick",{"type":15,"tag":23,"props":233,"children":234},{},[235,237,243,245,251],{"type":21,"value":236},"Docker builds images in layers. Each ",{"type":15,"tag":51,"props":238,"children":240},{"className":239},[],[241],{"type":21,"value":242},"COPY",{"type":21,"value":244}," or ",{"type":15,"tag":51,"props":246,"children":248},{"className":247},[],[249],{"type":21,"value":250},"RUN",{"type":21,"value":252}," instruction creates a layer. If a layer's input hasn't changed since the last build, Docker reuses the cached version.",{"type":15,"tag":23,"props":254,"children":255},{},[256,258,264,266,272,274,279],{"type":21,"value":257},"This is why you copy ",{"type":15,"tag":51,"props":259,"children":261},{"className":260},[],[262],{"type":21,"value":263},"requirements.txt",{"type":21,"value":265}," and install dependencies ",{"type":15,"tag":267,"props":268,"children":269},"em",{},[270],{"type":21,"value":271},"before",{"type":21,"value":273}," copying your code. If you change ",{"type":15,"tag":51,"props":275,"children":277},{"className":276},[],[278],{"type":21,"value":65},{"type":21,"value":280},", Docker reuses the cached pip install layer. If you did it all in one step, changing any file would re-trigger a full pip install.",{"type":15,"tag":46,"props":282,"children":285},{"code":283,"language":87,"meta":7,"className":284},"# Good: dependencies are cached separately from code\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\nCOPY serve.py model.pkl .\u002F\n\n# Bad: any file change re-installs all dependencies\nCOPY . .\nRUN pip install --no-cache-dir -r requirements.txt\n",[89],[286],{"type":15,"tag":51,"props":287,"children":288},{"__ignoreMap":7},[289],{"type":21,"value":283},{"type":15,"tag":23,"props":291,"children":292},{},[293],{"type":21,"value":294},"This matters when your dependencies include PyTorch (2+ GB). You don't want to re-download it every time you fix a typo in your serving code.",{"type":15,"tag":34,"props":296,"children":298},{"id":297},"keeping-images-small",[299],{"type":21,"value":300},"Keeping images small",{"type":15,"tag":23,"props":302,"children":303},{},[304],{"type":21,"value":305},"ML images get big fast. PyTorch alone is over 2 GB. Add CUDA, your model weights, and some data processing libraries and you're looking at 10+ GB images. Big images mean slow pulls, slow deploys, and wasted disk space.",{"type":15,"tag":125,"props":307,"children":309},{"id":308},"multi-stage-builds",[310],{"type":21,"value":311},"Multi-stage builds",{"type":15,"tag":23,"props":313,"children":314},{},[315],{"type":21,"value":316},"A multi-stage build uses one image to install\u002Fbuild things and a second image to run them. Only the second image ships.",{"type":15,"tag":46,"props":318,"children":321},{"code":319,"language":87,"meta":7,"className":320},"# Stage 1: install dependencies\nFROM python:3.11-slim AS builder\n\nWORKDIR \u002Fapp\nCOPY requirements.txt .\nRUN pip install --no-cache-dir --prefix=\u002Finstall -r requirements.txt\n\n# Stage 2: runtime image\nFROM python:3.11-slim\n\nWORKDIR \u002Fapp\nCOPY --from=builder \u002Finstall \u002Fusr\u002Flocal\nCOPY serve.py model.pkl .\u002F\n\nCMD [\"uvicorn\", \"serve:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n",[89],[322],{"type":15,"tag":51,"props":323,"children":324},{"__ignoreMap":7},[325],{"type":21,"value":319},{"type":15,"tag":23,"props":327,"children":328},{},[329,331,337,339,345],{"type":21,"value":330},"The ",{"type":15,"tag":51,"props":332,"children":334},{"className":333},[],[335],{"type":21,"value":336},"builder",{"type":21,"value":338}," stage installs packages into ",{"type":15,"tag":51,"props":340,"children":342},{"className":341},[],[343],{"type":21,"value":344},"\u002Finstall",{"type":21,"value":346},". The runtime stage copies only the installed packages — no pip cache, no build tools, no compiler artifacts. The final image is smaller because it doesn't contain anything needed only at build time.",{"type":15,"tag":125,"props":348,"children":350},{"id":349},"other-size-reduction-tactics",[351],{"type":21,"value":352},"Other size-reduction tactics",{"type":15,"tag":23,"props":354,"children":355},{},[356,369],{"type":15,"tag":140,"props":357,"children":358},{},[359,361,367],{"type":21,"value":360},"Use ",{"type":15,"tag":51,"props":362,"children":364},{"className":363},[],[365],{"type":21,"value":366},"--no-cache-dir",{"type":21,"value":368}," with pip.",{"type":21,"value":370}," Without it, pip caches downloaded packages inside the image. These caches serve no purpose in a container.",{"type":15,"tag":23,"props":372,"children":373},{},[374,379,381,386,388,394,396,402,404,410,412,418],{"type":15,"tag":140,"props":375,"children":376},{},[377],{"type":21,"value":378},"Don't install dev dependencies.",{"type":21,"value":380}," If your ",{"type":15,"tag":51,"props":382,"children":384},{"className":383},[],[385],{"type":21,"value":263},{"type":21,"value":387}," includes ",{"type":15,"tag":51,"props":389,"children":391},{"className":390},[],[392],{"type":21,"value":393},"pytest",{"type":21,"value":395},", ",{"type":15,"tag":51,"props":397,"children":399},{"className":398},[],[400],{"type":21,"value":401},"jupyter",{"type":21,"value":403},", or ",{"type":15,"tag":51,"props":405,"children":407},{"className":406},[],[408],{"type":21,"value":409},"matplotlib",{"type":21,"value":411}," but you don't need them at serving time, create a separate ",{"type":15,"tag":51,"props":413,"children":415},{"className":414},[],[416],{"type":21,"value":417},"requirements-serve.txt",{"type":21,"value":419}," with only the serving dependencies.",{"type":15,"tag":23,"props":421,"children":422},{},[423,435,437,442,444,450,452,458,460,466,467,473],{"type":15,"tag":140,"props":424,"children":425},{},[426,427,433],{"type":21,"value":360},{"type":15,"tag":51,"props":428,"children":430},{"className":429},[],[431],{"type":21,"value":432},".dockerignore",{"type":21,"value":434},".",{"type":21,"value":436}," Without a ",{"type":15,"tag":51,"props":438,"children":440},{"className":439},[],[441],{"type":21,"value":432},{"type":21,"value":443}," file, ",{"type":15,"tag":51,"props":445,"children":447},{"className":446},[],[448],{"type":21,"value":449},"COPY . .",{"type":21,"value":451}," copies everything — including your ",{"type":15,"tag":51,"props":453,"children":455},{"className":454},[],[456],{"type":21,"value":457},".git",{"type":21,"value":459}," directory, ",{"type":15,"tag":51,"props":461,"children":463},{"className":462},[],[464],{"type":21,"value":465},"__pycache__",{"type":21,"value":395},{"type":15,"tag":51,"props":468,"children":470},{"className":469},[],[471],{"type":21,"value":472},".venv",{"type":21,"value":474},", and data files. Create one:",{"type":15,"tag":46,"props":476,"children":478},{"code":477},".git\n__pycache__\n*.pyc\n.venv\ndata\u002F\nnotebooks\u002F\n.env\n",[479],{"type":15,"tag":51,"props":480,"children":481},{"__ignoreMap":7},[482],{"type":21,"value":477},{"type":15,"tag":23,"props":484,"children":485},{},[486,491,493,502,504,509],{"type":15,"tag":140,"props":487,"children":488},{},[489],{"type":21,"value":490},"Consider distroless or Alpine.",{"type":21,"value":492}," If you don't need a shell or package manager at runtime, Google's ",{"type":15,"tag":494,"props":495,"children":499},"a",{"href":496,"rel":497},"https:\u002F\u002Fgithub.com\u002FGoogleContainerTools\u002Fdistroless",[498],"nofollow",[500],{"type":21,"value":501},"distroless",{"type":21,"value":503}," Python images are even smaller than ",{"type":15,"tag":51,"props":505,"children":507},{"className":506},[],[508],{"type":21,"value":156},{"type":21,"value":510},". Alpine is another option but can cause issues with Python packages that have C extensions.",{"type":15,"tag":34,"props":512,"children":514},{"id":513},"gpu-images-with-nvidia",[515],{"type":21,"value":516},"GPU images with NVIDIA",{"type":15,"tag":23,"props":518,"children":519},{},[520],{"type":21,"value":521},"If your model needs GPU inference (deep learning, large models), you need NVIDIA's CUDA runtime in the container. This means using a different base image.",{"type":15,"tag":46,"props":523,"children":526},{"code":524,"language":87,"meta":7,"className":525},"FROM nvidia\u002Fcuda:12.1.1-runtime-ubuntu22.04\n\n# Install Python (NVIDIA images don't include it)\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends python3 python3-pip && \\\n    rm -rf \u002Fvar\u002Flib\u002Fapt\u002Flists\u002F* && \\\n    ln -s \u002Fusr\u002Fbin\u002Fpython3 \u002Fusr\u002Fbin\u002Fpython\n\nWORKDIR \u002Fapp\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY serve.py model\u002F .\u002F\n\nCMD [\"uvicorn\", \"serve:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n",[89],[527],{"type":15,"tag":51,"props":528,"children":529},{"__ignoreMap":7},[530],{"type":21,"value":524},{"type":15,"tag":23,"props":532,"children":533},{},[534],{"type":21,"value":535},"NVIDIA provides several image variants:",{"type":15,"tag":132,"props":537,"children":538},{},[539,553,567],{"type":15,"tag":136,"props":540,"children":541},{},[542,551],{"type":15,"tag":140,"props":543,"children":544},{},[545],{"type":15,"tag":51,"props":546,"children":548},{"className":547},[],[549],{"type":21,"value":550},"base",{"type":21,"value":552}," — CUDA driver libraries only. The smallest option.",{"type":15,"tag":136,"props":554,"children":555},{},[556,565],{"type":15,"tag":140,"props":557,"children":558},{},[559],{"type":15,"tag":51,"props":560,"children":562},{"className":561},[],[563],{"type":21,"value":564},"runtime",{"type":21,"value":566}," — adds CUDA runtime libraries. Use this for inference.",{"type":15,"tag":136,"props":568,"children":569},{},[570,579],{"type":15,"tag":140,"props":571,"children":572},{},[573],{"type":15,"tag":51,"props":574,"children":576},{"className":575},[],[577],{"type":21,"value":578},"devel",{"type":21,"value":580}," — adds compilers and headers. Use this if you need to compile CUDA code (most people don't for serving).",{"type":15,"tag":23,"props":582,"children":583},{},[584,586,591],{"type":21,"value":585},"For inference, ",{"type":15,"tag":51,"props":587,"children":589},{"className":588},[],[590],{"type":21,"value":564},{"type":21,"value":592}," is almost always what you want.",{"type":15,"tag":125,"props":594,"children":596},{"id":595},"running-gpu-containers",[597],{"type":21,"value":598},"Running GPU containers",{"type":15,"tag":23,"props":600,"children":601},{},[602],{"type":21,"value":603},"You need two things on the host:",{"type":15,"tag":605,"props":606,"children":607},"ol",{},[608,618],{"type":15,"tag":136,"props":609,"children":610},{},[611,616],{"type":15,"tag":140,"props":612,"children":613},{},[614],{"type":21,"value":615},"NVIDIA drivers",{"type":21,"value":617}," installed on the host machine (not in the container).",{"type":15,"tag":136,"props":619,"children":620},{},[621,626,628,634],{"type":15,"tag":140,"props":622,"children":623},{},[624],{"type":21,"value":625},"NVIDIA Container Toolkit",{"type":21,"value":627}," (",{"type":15,"tag":51,"props":629,"children":631},{"className":630},[],[632],{"type":21,"value":633},"nvidia-ctk",{"type":21,"value":635},") installed, so Docker can pass GPU devices into the container.",{"type":15,"tag":46,"props":637,"children":640},{"code":638,"language":103,"meta":7,"className":639},"docker run --gpus all -p 8000:8000 my-model-gpu:v1\n",[105],[641],{"type":15,"tag":51,"props":642,"children":643},{"__ignoreMap":7},[644],{"type":21,"value":638},{"type":15,"tag":23,"props":646,"children":647},{},[648,649,655,657,663],{"type":21,"value":330},{"type":15,"tag":51,"props":650,"children":652},{"className":651},[],[653],{"type":21,"value":654},"--gpus all",{"type":21,"value":656}," flag makes all host GPUs available inside the container. You can also specify ",{"type":15,"tag":51,"props":658,"children":660},{"className":659},[],[661],{"type":21,"value":662},"--gpus '\"device=0\"'",{"type":21,"value":664}," for a specific GPU.",{"type":15,"tag":23,"props":666,"children":667},{},[668],{"type":21,"value":669},"On Kubernetes, you'd request GPUs in the Pod spec instead:",{"type":15,"tag":46,"props":671,"children":676},{"code":672,"language":673,"meta":7,"className":674},"resources:\n  limits:\n    nvidia.com\u002Fgpu: 1\n","yaml",[675],"language-yaml",[677],{"type":15,"tag":51,"props":678,"children":679},{"__ignoreMap":7},[680],{"type":21,"value":672},{"type":15,"tag":23,"props":682,"children":683},{},[684],{"type":21,"value":685},"The NVIDIA device plugin handles the rest.",{"type":15,"tag":125,"props":687,"children":689},{"id":688},"pytorch-specific-tip",[690],{"type":21,"value":691},"PyTorch-specific tip",{"type":15,"tag":23,"props":693,"children":694},{},[695],{"type":21,"value":696},"PyTorch distributes separate packages for CPU and GPU. The GPU version includes CUDA bindings and is much larger. Use the right one:",{"type":15,"tag":46,"props":698,"children":700},{"code":699},"# GPU (includes CUDA)\n--extra-index-url https:\u002F\u002Fdownload.pytorch.org\u002Fwhl\u002Fcu121\ntorch==2.1.0\n\n# CPU only (much smaller)\n--extra-index-url https:\u002F\u002Fdownload.pytorch.org\u002Fwhl\u002Fcpu\ntorch==2.1.0\n",[701],{"type":15,"tag":51,"props":702,"children":703},{"__ignoreMap":7},[704],{"type":21,"value":699},{"type":15,"tag":23,"props":706,"children":707},{},[708],{"type":21,"value":709},"If your serving code runs on CPU, use the CPU wheel. Your image will be gigabytes smaller.",{"type":15,"tag":34,"props":711,"children":713},{"id":712},"pushing-to-a-registry",[714],{"type":21,"value":715},"Pushing to a registry",{"type":15,"tag":23,"props":717,"children":718},{},[719],{"type":21,"value":720},"A Docker image on your laptop isn't useful to anyone else. Push it to a container registry so your deployment pipeline can pull it.",{"type":15,"tag":125,"props":722,"children":724},{"id":723},"docker-hub",[725],{"type":21,"value":726},"Docker Hub",{"type":15,"tag":46,"props":728,"children":731},{"code":729,"language":103,"meta":7,"className":730},"docker tag my-model:v1 yourusername\u002Fmy-model:v1\ndocker push yourusername\u002Fmy-model:v1\n",[105],[732],{"type":15,"tag":51,"props":733,"children":734},{"__ignoreMap":7},[735],{"type":21,"value":729},{"type":15,"tag":23,"props":737,"children":738},{},[739],{"type":21,"value":740},"Docker Hub is public by default (free tier). Fine for open-source, not for proprietary models.",{"type":15,"tag":125,"props":742,"children":744},{"id":743},"private-registry-github-container-registry",[745],{"type":21,"value":746},"Private registry (GitHub Container Registry)",{"type":15,"tag":46,"props":748,"children":751},{"code":749,"language":103,"meta":7,"className":750},"echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin\ndocker tag my-model:v1 ghcr.io\u002Fyourorg\u002Fmy-model:v1\ndocker push ghcr.io\u002Fyourorg\u002Fmy-model:v1\n",[105],[752],{"type":15,"tag":51,"props":753,"children":754},{"__ignoreMap":7},[755],{"type":21,"value":749},{"type":15,"tag":125,"props":757,"children":759},{"id":758},"private-registry-self-hosted",[760],{"type":21,"value":761},"Private registry (self-hosted)",{"type":15,"tag":23,"props":763,"children":764},{},[765],{"type":21,"value":766},"If you're on-prem, you might run your own registry (Harbor, or the basic Docker registry):",{"type":15,"tag":46,"props":768,"children":771},{"code":769,"language":103,"meta":7,"className":770},"docker tag my-model:v1 registry.internal.company.com\u002Fml\u002Fmy-model:v1\ndocker push registry.internal.company.com\u002Fml\u002Fmy-model:v1\n",[105],[772],{"type":15,"tag":51,"props":773,"children":774},{"__ignoreMap":7},[775],{"type":21,"value":769},{"type":15,"tag":125,"props":777,"children":779},{"id":778},"tagging-strategy",[780],{"type":21,"value":781},"Tagging strategy",{"type":15,"tag":23,"props":783,"children":784},{},[785,787,793],{"type":21,"value":786},"Don't use ",{"type":15,"tag":51,"props":788,"children":790},{"className":789},[],[791],{"type":21,"value":792},":latest",{"type":21,"value":794},". It's mutable — every push overwrites it. You won't know which version is running in production.",{"type":15,"tag":23,"props":796,"children":797},{},[798],{"type":21,"value":799},"Use one of these:",{"type":15,"tag":132,"props":801,"children":802},{},[803,835,852],{"type":15,"tag":136,"props":804,"children":805},{},[806,811,813,819,820,826,827,833],{"type":15,"tag":140,"props":807,"children":808},{},[809],{"type":21,"value":810},"Version tags:",{"type":21,"value":812}," ",{"type":15,"tag":51,"props":814,"children":816},{"className":815},[],[817],{"type":21,"value":818},":v1",{"type":21,"value":395},{"type":15,"tag":51,"props":821,"children":823},{"className":822},[],[824],{"type":21,"value":825},":v2",{"type":21,"value":395},{"type":15,"tag":51,"props":828,"children":830},{"className":829},[],[831],{"type":21,"value":832},":v3",{"type":21,"value":834},". Simple and clear.",{"type":15,"tag":136,"props":836,"children":837},{},[838,843,844,850],{"type":15,"tag":140,"props":839,"children":840},{},[841],{"type":21,"value":842},"Git SHA:",{"type":21,"value":812},{"type":15,"tag":51,"props":845,"children":847},{"className":846},[],[848],{"type":21,"value":849},":sha-a1b2c3d",{"type":21,"value":851},". Ties the image to a specific commit.",{"type":15,"tag":136,"props":853,"children":854},{},[855,860,861,867],{"type":15,"tag":140,"props":856,"children":857},{},[858],{"type":21,"value":859},"Date-based:",{"type":21,"value":812},{"type":15,"tag":51,"props":862,"children":864},{"className":863},[],[865],{"type":21,"value":866},":2025-07-11",{"type":21,"value":868},". Useful for models that retrain on a schedule.",{"type":15,"tag":23,"props":870,"children":871},{},[872],{"type":21,"value":873},"Tag every image with something immutable. When something breaks in production, you need to know exactly which image is running.",{"type":15,"tag":34,"props":875,"children":877},{"id":876},"the-full-example",[878],{"type":21,"value":879},"The full example",{"type":15,"tag":23,"props":881,"children":882},{},[883],{"type":21,"value":884},"Putting it all together — a multi-stage Dockerfile for a model serving endpoint with health checks:",{"type":15,"tag":46,"props":886,"children":889},{"code":887,"language":87,"meta":7,"className":888},"# Stage 1: install dependencies\nFROM python:3.11-slim AS builder\n\nWORKDIR \u002Fbuild\nCOPY requirements.txt .\nRUN pip install --no-cache-dir --prefix=\u002Finstall -r requirements.txt\n\n# Stage 2: runtime\nFROM python:3.11-slim\n\nWORKDIR \u002Fapp\n\n# Copy installed packages from builder\nCOPY --from=builder \u002Finstall \u002Fusr\u002Flocal\n\n# Copy application code\nCOPY serve.py .\nCOPY model\u002F model\u002F\n\n# Non-root user for security\nRUN useradd --create-home appuser\nUSER appuser\n\nEXPOSE 8000\nHEALTHCHECK --interval=30s --timeout=5s --retries=3 \\\n  CMD python -c \"import urllib.request; urllib.request.urlopen('http:\u002F\u002Flocalhost:8000\u002Fhealth')\"\n\nCMD [\"uvicorn\", \"serve:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n",[89],[890],{"type":15,"tag":51,"props":891,"children":892},{"__ignoreMap":7},[893],{"type":21,"value":887},{"type":15,"tag":23,"props":895,"children":896},{},[897],{"type":21,"value":898},"Build, tag, push:",{"type":15,"tag":46,"props":900,"children":903},{"code":901,"language":103,"meta":7,"className":902},"docker build -t registry.example.com\u002Fml\u002Fmy-model:v1 .\ndocker push registry.example.com\u002Fml\u002Fmy-model:v1\n",[105],[904],{"type":15,"tag":51,"props":905,"children":906},{"__ignoreMap":7},[907],{"type":21,"value":901},{"type":15,"tag":23,"props":909,"children":910},{},[911],{"type":21,"value":912},"Deploy to Kubernetes:",{"type":15,"tag":46,"props":914,"children":917},{"code":915,"language":673,"meta":7,"className":916},"apiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: my-model\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app: my-model\n  template:\n    metadata:\n      labels:\n        app: my-model\n    spec:\n      containers:\n      - name: serve\n        image: registry.example.com\u002Fml\u002Fmy-model:v1\n        ports:\n        - containerPort: 8000\n        livenessProbe:\n          httpGet:\n            path: \u002Fhealth\n            port: 8000\n        readinessProbe:\n          httpGet:\n            path: \u002Fhealth\n            port: 8000\n        resources:\n          requests:\n            memory: \"512Mi\"\n            cpu: \"250m\"\n          limits:\n            memory: \"1Gi\"\n            cpu: \"500m\"\n",[675],[918],{"type":15,"tag":51,"props":919,"children":920},{"__ignoreMap":7},[921],{"type":21,"value":915},{"type":15,"tag":23,"props":923,"children":924},{},[925,927,933],{"type":21,"value":926},"The model is now running in a container, behind a health check, with resource limits, and can be scaled horizontally by changing ",{"type":15,"tag":51,"props":928,"children":930},{"className":929},[],[931],{"type":21,"value":932},"replicas",{"type":21,"value":934},". Anyone with access to the registry can deploy it without knowing anything about Python versions, pip, or your machine's environment.",{"type":15,"tag":936,"props":937,"children":938},"hr",{},[],{"type":15,"tag":23,"props":940,"children":941},{},[942,944,951,953,959],{"type":21,"value":943},"Containerizing ML workloads is a core part of what we set up at ",{"type":15,"tag":494,"props":945,"children":948},{"href":946,"rel":947},"https:\u002F\u002Fdeploying.ai",[498],[949],{"type":21,"value":950},"deploying.ai",{"type":21,"value":952},". If you need help building reliable ML deployment pipelines, ",{"type":15,"tag":494,"props":954,"children":956},{"href":955},"mailto:vlad@deploying.ai",[957],{"type":21,"value":958},"reach out",{"type":21,"value":434},{"title":7,"searchDepth":961,"depth":961,"links":962},2,[963,968,972,976,982],{"id":36,"depth":961,"text":39,"children":964},[965,967],{"id":127,"depth":966,"text":130},3,{"id":228,"depth":966,"text":231},{"id":297,"depth":961,"text":300,"children":969},[970,971],{"id":308,"depth":966,"text":311},{"id":349,"depth":966,"text":352},{"id":513,"depth":961,"text":516,"children":973},[974,975],{"id":595,"depth":966,"text":598},{"id":688,"depth":966,"text":691},{"id":712,"depth":961,"text":715,"children":977},[978,979,980,981],{"id":723,"depth":966,"text":726},{"id":743,"depth":966,"text":746},{"id":758,"depth":966,"text":761},{"id":778,"depth":966,"text":781},{"id":876,"depth":961,"text":879},"markdown","content:articles:docker-for-ml-engineers.md","content","articles\u002Fdocker-for-ml-engineers.md","articles\u002Fdocker-for-ml-engineers","md",{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"body":990,"_type":983,"_id":984,"_source":985,"_file":986,"_stem":987,"_extension":988},{"type":12,"children":991,"toc":1733},[992,996,1000,1004,1008,1012,1019,1029,1037,1041,1049,1053,1061,1071,1075,1153,1157,1173,1194,1202,1206,1210,1214,1218,1222,1230,1246,1250,1264,1302,1346,1353,1373,1377,1381,1389,1393,1432,1442,1446,1450,1475,1483,1499,1503,1511,1515,1519,1523,1530,1534,1538,1542,1546,1554,1558,1562,1570,1574,1578,1586,1590,1600,1604,1661,1665,1669,1673,1681,1685,1693,1697,1705,1715,1718],{"type":15,"tag":16,"props":993,"children":994},{"id":18},[995],{"type":21,"value":8},{"type":15,"tag":23,"props":997,"children":998},{},[999],{"type":21,"value":27},{"type":15,"tag":23,"props":1001,"children":1002},{},[1003],{"type":21,"value":32},{"type":15,"tag":34,"props":1005,"children":1006},{"id":36},[1007],{"type":21,"value":39},{"type":15,"tag":23,"props":1009,"children":1010},{},[1011],{"type":21,"value":44},{"type":15,"tag":46,"props":1013,"children":1014},{"code":48},[1015],{"type":15,"tag":51,"props":1016,"children":1017},{"__ignoreMap":7},[1018],{"type":21,"value":48},{"type":15,"tag":23,"props":1020,"children":1021},{},[1022,1023,1028],{"type":21,"value":59},{"type":15,"tag":51,"props":1024,"children":1026},{"className":1025},[],[1027],{"type":21,"value":65},{"type":21,"value":67},{"type":15,"tag":46,"props":1030,"children":1032},{"code":70,"language":71,"meta":7,"className":1031},[73],[1033],{"type":15,"tag":51,"props":1034,"children":1035},{"__ignoreMap":7},[1036],{"type":21,"value":70},{"type":15,"tag":23,"props":1038,"children":1039},{},[1040],{"type":21,"value":83},{"type":15,"tag":46,"props":1042,"children":1044},{"code":86,"language":87,"meta":7,"className":1043},[89],[1045],{"type":15,"tag":51,"props":1046,"children":1047},{"__ignoreMap":7},[1048],{"type":21,"value":86},{"type":15,"tag":23,"props":1050,"children":1051},{},[1052],{"type":21,"value":99},{"type":15,"tag":46,"props":1054,"children":1056},{"code":102,"language":103,"meta":7,"className":1055},[105],[1057],{"type":15,"tag":51,"props":1058,"children":1059},{"__ignoreMap":7},[1060],{"type":21,"value":102},{"type":15,"tag":23,"props":1062,"children":1063},{},[1064,1065,1070],{"type":21,"value":115},{"type":15,"tag":51,"props":1066,"children":1068},{"className":1067},[],[1069],{"type":21,"value":121},{"type":21,"value":123},{"type":15,"tag":125,"props":1072,"children":1073},{"id":127},[1074],{"type":21,"value":130},{"type":15,"tag":132,"props":1076,"children":1077},{},[1078,1096,1108,1129,1141],{"type":15,"tag":136,"props":1079,"children":1080},{},[1081,1089,1090,1095],{"type":15,"tag":140,"props":1082,"children":1083},{},[1084],{"type":15,"tag":51,"props":1085,"children":1087},{"className":1086},[],[1088],{"type":21,"value":148},{"type":21,"value":150},{"type":15,"tag":51,"props":1091,"children":1093},{"className":1092},[],[1094],{"type":21,"value":156},{"type":21,"value":158},{"type":15,"tag":136,"props":1097,"children":1098},{},[1099,1107],{"type":15,"tag":140,"props":1100,"children":1101},{},[1102],{"type":15,"tag":51,"props":1103,"children":1105},{"className":1104},[],[1106],{"type":21,"value":170},{"type":21,"value":172},{"type":15,"tag":136,"props":1109,"children":1110},{},[1111,1119,1120,1128],{"type":15,"tag":140,"props":1112,"children":1113},{},[1114],{"type":15,"tag":51,"props":1115,"children":1117},{"className":1116},[],[1118],{"type":21,"value":184},{"type":21,"value":186},{"type":15,"tag":140,"props":1121,"children":1122},{},[1123],{"type":15,"tag":51,"props":1124,"children":1126},{"className":1125},[],[1127],{"type":21,"value":195},{"type":21,"value":197},{"type":15,"tag":136,"props":1130,"children":1131},{},[1132,1140],{"type":15,"tag":140,"props":1133,"children":1134},{},[1135],{"type":15,"tag":51,"props":1136,"children":1138},{"className":1137},[],[1139],{"type":21,"value":209},{"type":21,"value":211},{"type":15,"tag":136,"props":1142,"children":1143},{},[1144,1152],{"type":15,"tag":140,"props":1145,"children":1146},{},[1147],{"type":15,"tag":51,"props":1148,"children":1150},{"className":1149},[],[1151],{"type":21,"value":223},{"type":21,"value":225},{"type":15,"tag":125,"props":1154,"children":1155},{"id":228},[1156],{"type":21,"value":231},{"type":15,"tag":23,"props":1158,"children":1159},{},[1160,1161,1166,1167,1172],{"type":21,"value":236},{"type":15,"tag":51,"props":1162,"children":1164},{"className":1163},[],[1165],{"type":21,"value":242},{"type":21,"value":244},{"type":15,"tag":51,"props":1168,"children":1170},{"className":1169},[],[1171],{"type":21,"value":250},{"type":21,"value":252},{"type":15,"tag":23,"props":1174,"children":1175},{},[1176,1177,1182,1183,1187,1188,1193],{"type":21,"value":257},{"type":15,"tag":51,"props":1178,"children":1180},{"className":1179},[],[1181],{"type":21,"value":263},{"type":21,"value":265},{"type":15,"tag":267,"props":1184,"children":1185},{},[1186],{"type":21,"value":271},{"type":21,"value":273},{"type":15,"tag":51,"props":1189,"children":1191},{"className":1190},[],[1192],{"type":21,"value":65},{"type":21,"value":280},{"type":15,"tag":46,"props":1195,"children":1197},{"code":283,"language":87,"meta":7,"className":1196},[89],[1198],{"type":15,"tag":51,"props":1199,"children":1200},{"__ignoreMap":7},[1201],{"type":21,"value":283},{"type":15,"tag":23,"props":1203,"children":1204},{},[1205],{"type":21,"value":294},{"type":15,"tag":34,"props":1207,"children":1208},{"id":297},[1209],{"type":21,"value":300},{"type":15,"tag":23,"props":1211,"children":1212},{},[1213],{"type":21,"value":305},{"type":15,"tag":125,"props":1215,"children":1216},{"id":308},[1217],{"type":21,"value":311},{"type":15,"tag":23,"props":1219,"children":1220},{},[1221],{"type":21,"value":316},{"type":15,"tag":46,"props":1223,"children":1225},{"code":319,"language":87,"meta":7,"className":1224},[89],[1226],{"type":15,"tag":51,"props":1227,"children":1228},{"__ignoreMap":7},[1229],{"type":21,"value":319},{"type":15,"tag":23,"props":1231,"children":1232},{},[1233,1234,1239,1240,1245],{"type":21,"value":330},{"type":15,"tag":51,"props":1235,"children":1237},{"className":1236},[],[1238],{"type":21,"value":336},{"type":21,"value":338},{"type":15,"tag":51,"props":1241,"children":1243},{"className":1242},[],[1244],{"type":21,"value":344},{"type":21,"value":346},{"type":15,"tag":125,"props":1247,"children":1248},{"id":349},[1249],{"type":21,"value":352},{"type":15,"tag":23,"props":1251,"children":1252},{},[1253,1263],{"type":15,"tag":140,"props":1254,"children":1255},{},[1256,1257,1262],{"type":21,"value":360},{"type":15,"tag":51,"props":1258,"children":1260},{"className":1259},[],[1261],{"type":21,"value":366},{"type":21,"value":368},{"type":21,"value":370},{"type":15,"tag":23,"props":1265,"children":1266},{},[1267,1271,1272,1277,1278,1283,1284,1289,1290,1295,1296,1301],{"type":15,"tag":140,"props":1268,"children":1269},{},[1270],{"type":21,"value":378},{"type":21,"value":380},{"type":15,"tag":51,"props":1273,"children":1275},{"className":1274},[],[1276],{"type":21,"value":263},{"type":21,"value":387},{"type":15,"tag":51,"props":1279,"children":1281},{"className":1280},[],[1282],{"type":21,"value":393},{"type":21,"value":395},{"type":15,"tag":51,"props":1285,"children":1287},{"className":1286},[],[1288],{"type":21,"value":401},{"type":21,"value":403},{"type":15,"tag":51,"props":1291,"children":1293},{"className":1292},[],[1294],{"type":21,"value":409},{"type":21,"value":411},{"type":15,"tag":51,"props":1297,"children":1299},{"className":1298},[],[1300],{"type":21,"value":417},{"type":21,"value":419},{"type":15,"tag":23,"props":1303,"children":1304},{},[1305,1315,1316,1321,1322,1327,1328,1333,1334,1339,1340,1345],{"type":15,"tag":140,"props":1306,"children":1307},{},[1308,1309,1314],{"type":21,"value":360},{"type":15,"tag":51,"props":1310,"children":1312},{"className":1311},[],[1313],{"type":21,"value":432},{"type":21,"value":434},{"type":21,"value":436},{"type":15,"tag":51,"props":1317,"children":1319},{"className":1318},[],[1320],{"type":21,"value":432},{"type":21,"value":443},{"type":15,"tag":51,"props":1323,"children":1325},{"className":1324},[],[1326],{"type":21,"value":449},{"type":21,"value":451},{"type":15,"tag":51,"props":1329,"children":1331},{"className":1330},[],[1332],{"type":21,"value":457},{"type":21,"value":459},{"type":15,"tag":51,"props":1335,"children":1337},{"className":1336},[],[1338],{"type":21,"value":465},{"type":21,"value":395},{"type":15,"tag":51,"props":1341,"children":1343},{"className":1342},[],[1344],{"type":21,"value":472},{"type":21,"value":474},{"type":15,"tag":46,"props":1347,"children":1348},{"code":477},[1349],{"type":15,"tag":51,"props":1350,"children":1351},{"__ignoreMap":7},[1352],{"type":21,"value":477},{"type":15,"tag":23,"props":1354,"children":1355},{},[1356,1360,1361,1366,1367,1372],{"type":15,"tag":140,"props":1357,"children":1358},{},[1359],{"type":21,"value":490},{"type":21,"value":492},{"type":15,"tag":494,"props":1362,"children":1364},{"href":496,"rel":1363},[498],[1365],{"type":21,"value":501},{"type":21,"value":503},{"type":15,"tag":51,"props":1368,"children":1370},{"className":1369},[],[1371],{"type":21,"value":156},{"type":21,"value":510},{"type":15,"tag":34,"props":1374,"children":1375},{"id":513},[1376],{"type":21,"value":516},{"type":15,"tag":23,"props":1378,"children":1379},{},[1380],{"type":21,"value":521},{"type":15,"tag":46,"props":1382,"children":1384},{"code":524,"language":87,"meta":7,"className":1383},[89],[1385],{"type":15,"tag":51,"props":1386,"children":1387},{"__ignoreMap":7},[1388],{"type":21,"value":524},{"type":15,"tag":23,"props":1390,"children":1391},{},[1392],{"type":21,"value":535},{"type":15,"tag":132,"props":1394,"children":1395},{},[1396,1408,1420],{"type":15,"tag":136,"props":1397,"children":1398},{},[1399,1407],{"type":15,"tag":140,"props":1400,"children":1401},{},[1402],{"type":15,"tag":51,"props":1403,"children":1405},{"className":1404},[],[1406],{"type":21,"value":550},{"type":21,"value":552},{"type":15,"tag":136,"props":1409,"children":1410},{},[1411,1419],{"type":15,"tag":140,"props":1412,"children":1413},{},[1414],{"type":15,"tag":51,"props":1415,"children":1417},{"className":1416},[],[1418],{"type":21,"value":564},{"type":21,"value":566},{"type":15,"tag":136,"props":1421,"children":1422},{},[1423,1431],{"type":15,"tag":140,"props":1424,"children":1425},{},[1426],{"type":15,"tag":51,"props":1427,"children":1429},{"className":1428},[],[1430],{"type":21,"value":578},{"type":21,"value":580},{"type":15,"tag":23,"props":1433,"children":1434},{},[1435,1436,1441],{"type":21,"value":585},{"type":15,"tag":51,"props":1437,"children":1439},{"className":1438},[],[1440],{"type":21,"value":564},{"type":21,"value":592},{"type":15,"tag":125,"props":1443,"children":1444},{"id":595},[1445],{"type":21,"value":598},{"type":15,"tag":23,"props":1447,"children":1448},{},[1449],{"type":21,"value":603},{"type":15,"tag":605,"props":1451,"children":1452},{},[1453,1461],{"type":15,"tag":136,"props":1454,"children":1455},{},[1456,1460],{"type":15,"tag":140,"props":1457,"children":1458},{},[1459],{"type":21,"value":615},{"type":21,"value":617},{"type":15,"tag":136,"props":1462,"children":1463},{},[1464,1468,1469,1474],{"type":15,"tag":140,"props":1465,"children":1466},{},[1467],{"type":21,"value":625},{"type":21,"value":627},{"type":15,"tag":51,"props":1470,"children":1472},{"className":1471},[],[1473],{"type":21,"value":633},{"type":21,"value":635},{"type":15,"tag":46,"props":1476,"children":1478},{"code":638,"language":103,"meta":7,"className":1477},[105],[1479],{"type":15,"tag":51,"props":1480,"children":1481},{"__ignoreMap":7},[1482],{"type":21,"value":638},{"type":15,"tag":23,"props":1484,"children":1485},{},[1486,1487,1492,1493,1498],{"type":21,"value":330},{"type":15,"tag":51,"props":1488,"children":1490},{"className":1489},[],[1491],{"type":21,"value":654},{"type":21,"value":656},{"type":15,"tag":51,"props":1494,"children":1496},{"className":1495},[],[1497],{"type":21,"value":662},{"type":21,"value":664},{"type":15,"tag":23,"props":1500,"children":1501},{},[1502],{"type":21,"value":669},{"type":15,"tag":46,"props":1504,"children":1506},{"code":672,"language":673,"meta":7,"className":1505},[675],[1507],{"type":15,"tag":51,"props":1508,"children":1509},{"__ignoreMap":7},[1510],{"type":21,"value":672},{"type":15,"tag":23,"props":1512,"children":1513},{},[1514],{"type":21,"value":685},{"type":15,"tag":125,"props":1516,"children":1517},{"id":688},[1518],{"type":21,"value":691},{"type":15,"tag":23,"props":1520,"children":1521},{},[1522],{"type":21,"value":696},{"type":15,"tag":46,"props":1524,"children":1525},{"code":699},[1526],{"type":15,"tag":51,"props":1527,"children":1528},{"__ignoreMap":7},[1529],{"type":21,"value":699},{"type":15,"tag":23,"props":1531,"children":1532},{},[1533],{"type":21,"value":709},{"type":15,"tag":34,"props":1535,"children":1536},{"id":712},[1537],{"type":21,"value":715},{"type":15,"tag":23,"props":1539,"children":1540},{},[1541],{"type":21,"value":720},{"type":15,"tag":125,"props":1543,"children":1544},{"id":723},[1545],{"type":21,"value":726},{"type":15,"tag":46,"props":1547,"children":1549},{"code":729,"language":103,"meta":7,"className":1548},[105],[1550],{"type":15,"tag":51,"props":1551,"children":1552},{"__ignoreMap":7},[1553],{"type":21,"value":729},{"type":15,"tag":23,"props":1555,"children":1556},{},[1557],{"type":21,"value":740},{"type":15,"tag":125,"props":1559,"children":1560},{"id":743},[1561],{"type":21,"value":746},{"type":15,"tag":46,"props":1563,"children":1565},{"code":749,"language":103,"meta":7,"className":1564},[105],[1566],{"type":15,"tag":51,"props":1567,"children":1568},{"__ignoreMap":7},[1569],{"type":21,"value":749},{"type":15,"tag":125,"props":1571,"children":1572},{"id":758},[1573],{"type":21,"value":761},{"type":15,"tag":23,"props":1575,"children":1576},{},[1577],{"type":21,"value":766},{"type":15,"tag":46,"props":1579,"children":1581},{"code":769,"language":103,"meta":7,"className":1580},[105],[1582],{"type":15,"tag":51,"props":1583,"children":1584},{"__ignoreMap":7},[1585],{"type":21,"value":769},{"type":15,"tag":125,"props":1587,"children":1588},{"id":778},[1589],{"type":21,"value":781},{"type":15,"tag":23,"props":1591,"children":1592},{},[1593,1594,1599],{"type":21,"value":786},{"type":15,"tag":51,"props":1595,"children":1597},{"className":1596},[],[1598],{"type":21,"value":792},{"type":21,"value":794},{"type":15,"tag":23,"props":1601,"children":1602},{},[1603],{"type":21,"value":799},{"type":15,"tag":132,"props":1605,"children":1606},{},[1607,1633,1647],{"type":15,"tag":136,"props":1608,"children":1609},{},[1610,1614,1615,1620,1621,1626,1627,1632],{"type":15,"tag":140,"props":1611,"children":1612},{},[1613],{"type":21,"value":810},{"type":21,"value":812},{"type":15,"tag":51,"props":1616,"children":1618},{"className":1617},[],[1619],{"type":21,"value":818},{"type":21,"value":395},{"type":15,"tag":51,"props":1622,"children":1624},{"className":1623},[],[1625],{"type":21,"value":825},{"type":21,"value":395},{"type":15,"tag":51,"props":1628,"children":1630},{"className":1629},[],[1631],{"type":21,"value":832},{"type":21,"value":834},{"type":15,"tag":136,"props":1634,"children":1635},{},[1636,1640,1641,1646],{"type":15,"tag":140,"props":1637,"children":1638},{},[1639],{"type":21,"value":842},{"type":21,"value":812},{"type":15,"tag":51,"props":1642,"children":1644},{"className":1643},[],[1645],{"type":21,"value":849},{"type":21,"value":851},{"type":15,"tag":136,"props":1648,"children":1649},{},[1650,1654,1655,1660],{"type":15,"tag":140,"props":1651,"children":1652},{},[1653],{"type":21,"value":859},{"type":21,"value":812},{"type":15,"tag":51,"props":1656,"children":1658},{"className":1657},[],[1659],{"type":21,"value":866},{"type":21,"value":868},{"type":15,"tag":23,"props":1662,"children":1663},{},[1664],{"type":21,"value":873},{"type":15,"tag":34,"props":1666,"children":1667},{"id":876},[1668],{"type":21,"value":879},{"type":15,"tag":23,"props":1670,"children":1671},{},[1672],{"type":21,"value":884},{"type":15,"tag":46,"props":1674,"children":1676},{"code":887,"language":87,"meta":7,"className":1675},[89],[1677],{"type":15,"tag":51,"props":1678,"children":1679},{"__ignoreMap":7},[1680],{"type":21,"value":887},{"type":15,"tag":23,"props":1682,"children":1683},{},[1684],{"type":21,"value":898},{"type":15,"tag":46,"props":1686,"children":1688},{"code":901,"language":103,"meta":7,"className":1687},[105],[1689],{"type":15,"tag":51,"props":1690,"children":1691},{"__ignoreMap":7},[1692],{"type":21,"value":901},{"type":15,"tag":23,"props":1694,"children":1695},{},[1696],{"type":21,"value":912},{"type":15,"tag":46,"props":1698,"children":1700},{"code":915,"language":673,"meta":7,"className":1699},[675],[1701],{"type":15,"tag":51,"props":1702,"children":1703},{"__ignoreMap":7},[1704],{"type":21,"value":915},{"type":15,"tag":23,"props":1706,"children":1707},{},[1708,1709,1714],{"type":21,"value":926},{"type":15,"tag":51,"props":1710,"children":1712},{"className":1711},[],[1713],{"type":21,"value":932},{"type":21,"value":934},{"type":15,"tag":936,"props":1716,"children":1717},{},[],{"type":15,"tag":23,"props":1719,"children":1720},{},[1721,1722,1727,1728,1732],{"type":21,"value":943},{"type":15,"tag":494,"props":1723,"children":1725},{"href":946,"rel":1724},[498],[1726],{"type":21,"value":950},{"type":21,"value":952},{"type":15,"tag":494,"props":1729,"children":1730},{"href":955},[1731],{"type":21,"value":958},{"type":21,"value":434},{"title":7,"searchDepth":961,"depth":961,"links":1734},[1735,1739,1743,1747,1753],{"id":36,"depth":961,"text":39,"children":1736},[1737,1738],{"id":127,"depth":966,"text":130},{"id":228,"depth":966,"text":231},{"id":297,"depth":961,"text":300,"children":1740},[1741,1742],{"id":308,"depth":966,"text":311},{"id":349,"depth":966,"text":352},{"id":513,"depth":961,"text":516,"children":1744},[1745,1746],{"id":595,"depth":966,"text":598},{"id":688,"depth":966,"text":691},{"id":712,"depth":961,"text":715,"children":1748},[1749,1750,1751,1752],{"id":723,"depth":966,"text":726},{"id":743,"depth":966,"text":746},{"id":758,"depth":966,"text":761},{"id":778,"depth":966,"text":781},{"id":876,"depth":961,"text":879},1785232227842]