[{"data":1,"prerenderedAt":1495},["ShallowReactive",2],{"\u002Fblog\u002Fvscode-docker-build-debugging":3},{"id":4,"title":5,"body":6,"createdAt":1483,"description":1484,"extension":1485,"externalPost":1486,"githubLink":1486,"language":1487,"meta":1488,"navigation":1042,"ogImage":1486,"path":1489,"robots":1486,"seo":1490,"stem":1491,"tags":1492,"__hash__":1494,"date":1483},"blog\u002Fblog\u002Fvscode-docker-build-debugging.md","Docker Build Debugging in VS Code",{"type":7,"value":8,"toc":1451},"minimark",[9,13,17,28,31,36,39,72,75,86,90,96,99,137,140,145,148,153,164,167,192,202,209,212,238,241,266,269,273,283,287,290,376,380,386,411,417,443,450,457,461,464,467,485,492,495,499,502,506,519,522,526,532,535,658,661,689,692,865,869,872,876,883,890,894,904,909,913,923,929,933,939,942,960,967,980,985,988,1001,1007,1011,1017,1181,1191,1205,1212,1236,1242,1266,1269,1273,1279,1282,1290,1296,1299,1314,1319,1323,1326,1330,1333,1337,1345,1349,1358,1361,1365,1368,1377,1380,1384,1447],[10,11,5],"h1",{"id":12},"docker-build-debugging-in-vs-code",[14,15,16],"p",{},"Debugging a Docker build has always had an awkward side to it. When a Dockerfile build fails, it rarely fails in a friendly place. Most of the time you end up staring at an unhelpful error line, rereading the file, rebuilding the image, and trying to guess what state the image was left in.",[14,18,19,20,27],{},"To address that pain, Docker brought this experience to VS Code through ",[21,22,26],"a",{"href":23,"rel":24},"https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=docker.docker",[25],"nofollow","Docker DX",". It lets you stop the build at the right step, inspect variables, explore the filesystem, and even open a temporary shell to test commands before changing the Dockerfile.",[14,29,30],{},"This is specifically about build debugging in VS Code, not about attaching a debugger to an application that is already running inside a container.",[32,33,35],"h2",{"id":34},"what-docker-build-debugging-looked-like-before-docker-dx","What Docker build debugging looked like before Docker DX",[14,37,38],{},"Before this extension, the flow usually looked like this:",[40,41,42,51,54,57,60,66,69],"ol",{},[43,44,45,46,50],"li",{},"run ",[47,48,49],"code",{},"docker build",";",[43,52,53],{},"read an error message that is not always very helpful;",[43,55,56],{},"comment out lines after the failure point;",[43,58,59],{},"build again;",[43,61,62,63,50],{},"start an intermediate container with ",[47,64,65],{},"docker run",[43,67,68],{},"open a shell and test commands manually;",[43,70,71],{},"go back to the Dockerfile, fix it, and repeat.",[14,73,74],{},"The problem was not only the time you lost. It was also the lack of context. Instead of watching the build happen step by step, you ended up experimenting around it and rebuilding the image state in your head.",[14,76,77,78,81,82,85],{},"When the problem was a ",[47,79,80],{},"COPY",", a variable, a bad ",[47,83,84],{},"WORKDIR",", or just a typo, that loop got old very quickly.",[32,87,89],{"id":88},"what-changed-with-docker-dx","What changed with Docker DX",[14,91,92,95],{},[21,93,26],{"href":23,"rel":94},[25]," is Docker's official extension for VS Code. The most relevant part here is build debugging, built on top of Buildx and the Debug Adapter Protocol, or DAP.",[14,97,98],{},"In practice, that gives you the ability to:",[100,101,102,105,108,119,122,128],"ul",{},[43,103,104],{},"set breakpoints on Dockerfile instructions;",[43,106,107],{},"step through the build line by line;",[43,109,110,111,114,115,118],{},"inspect ",[47,112,113],{},"ARG"," and ",[47,116,117],{},"ENV"," variables;",[43,120,121],{},"explore the filesystem at that stage of the build;",[43,123,124,125,50],{},"open a temporary shell in the suspended image with ",[47,126,127],{},"exec",[43,129,130,131,133,134,136],{},"understand much faster whether the problem is a typo, a ",[47,132,80],{},", the build context, a ",[47,135,84],{},", a variable, or a missing dependency.",[14,138,139],{},"This does not turn a Dockerfile into a regular program, but it gets much closer to the kind of debugging experience people have wanted for years.",[141,142,144],"h3",{"id":143},"prerequisites","Prerequisites",[14,146,147],{},"Before opening VS Code, it is worth checking the basics.",[149,150,152],"h4",{"id":151},"_1-updated-docker","1. Updated Docker",[14,154,155,156,159,160,163],{},"The ",[21,157,26],{"href":23,"rel":158},[25]," documentation recommends Docker Desktop ",[47,161,162],{},"4.46"," or later. If you are not using Docker Desktop, the key point is having Buildx with DAP support.",[14,165,166],{},"Check it with:",[168,169,174],"pre",{"className":170,"code":171,"language":172,"meta":173,"style":173},"language-bash shiki shiki-themes github-dark","docker buildx version\n","bash","",[47,175,176],{"__ignoreMap":173},[177,178,181,185,189],"span",{"class":179,"line":180},"line",1,[177,182,184],{"class":183},"svObZ","docker",[177,186,188],{"class":187},"sU2Wk"," buildx",[177,190,191],{"class":187}," version\n",[14,193,155,194,197,198,201],{},[21,195,26],{"href":23,"rel":196},[25]," debugging guide refers to ",[47,199,200],{},"Buildx v0.28.0"," or later.",[14,203,204,205,208],{},"Then check that the ",[47,206,207],{},"dap"," subcommand is available.",[14,210,211],{},"In Bash:",[168,213,215],{"className":170,"code":214,"language":172,"meta":173,"style":173},"BUILDX_EXPERIMENTAL=1 docker buildx dap\n",[47,216,217],{"__ignoreMap":173},[177,218,219,223,227,230,233,235],{"class":179,"line":180},[177,220,222],{"class":221},"s95oV","BUILDX_EXPERIMENTAL",[177,224,226],{"class":225},"snl16","=",[177,228,229],{"class":187},"1",[177,231,232],{"class":183}," docker",[177,234,188],{"class":187},[177,236,237],{"class":187}," dap\n",[14,239,240],{},"In PowerShell:",[168,242,246],{"className":243,"code":244,"language":245,"meta":173,"style":173},"language-powershell shiki shiki-themes github-dark","$env:BUILDX_EXPERIMENTAL=1; docker buildx dap\n","powershell",[47,247,248],{"__ignoreMap":173},[177,249,250,253,257,259,261,263],{"class":179,"line":180},[177,251,252],{"class":221},"$",[177,254,256],{"class":255},"sDLfK","env:",[177,258,222],{"class":221},[177,260,226],{"class":225},[177,262,229],{"class":255},[177,264,265],{"class":221},"; docker buildx dap\n",[14,267,268],{},"If that command is not available, VS Code will not be able to start build debugging.",[149,270,272],{"id":271},"_2-install-docker-dx","2. Install Docker DX",[14,274,275,276,282],{},"On the Marketplace, the extension is published by Docker under the identifier ",[21,277,279],{"href":23,"rel":278},[25],[47,280,281],{},"docker.docker",".",[32,284,286],{"id":285},"the-3-extensions-that-usually-get-mixed-up","The 3 extensions that usually get mixed up",[14,288,289],{},"At this point, a lot of people install container-related extensions in VS Code without being fully sure where one ends and the next begins. The current picture looks like this:",[291,292,293,312],"table",{},[294,295,296],"thead",{},[297,298,299,303,306,309],"tr",{},[300,301,302],"th",{},"Extension",[300,304,305],{},"Publisher",[300,307,308],{},"Best for",[300,310,311],{},"Important notes",[313,314,315,344,360],"tbody",{},[297,316,317,325,328,331],{},[318,319,320],"td",{},[21,321,324],{"href":322,"rel":323},"https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=ms-azuretools.vscode-docker",[25],"ms-azuretools.vscode-docker",[318,326,327],{},"Microsoft",[318,329,330],{},"Compatibility with the older experience",[318,332,333,334,338,339,282],{},"It is no longer the classic extension. Today it works as the ",[21,335,337],{"href":322,"rel":336},[25],"Docker Extension Pack"," and includes ",[21,340,343],{"href":341,"rel":342},"https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=ms-azuretools.vscode-containers",[25],"Container Tools",[297,345,346,352,354,357],{},[318,347,348],{},[21,349,351],{"href":341,"rel":350},[25],"ms-azuretools.vscode-containers",[318,353,327],{},[318,355,356],{},"Managing containers, Compose, and scaffolding",[318,358,359],{},"It replaces the earlier Docker extension functionality from Microsoft.",[297,361,362,367,370,373],{},[318,363,364],{},[21,365,281],{"href":23,"rel":366},[25],[318,368,369],{},"Docker",[318,371,372],{},"Advanced authoring for Dockerfile, Compose, Bake, and build debugging",[318,374,375],{},"It is Docker's official extension for richer editing and Buildx-based build debugging.",[141,377,379],{"id":378},"what-each-one-does-best","What each one does best",[149,381,383],{"id":382},"docker-dx",[21,384,26],{"href":23,"rel":385},[25],[100,387,388,394,397,400,403,406],{},[43,389,390,393],{},[47,391,392],{},"Dockerfile"," linting with BuildKit and Buildx;",[43,395,396],{},"build checks and best practice suggestions;",[43,398,399],{},"Compose editing with project context;",[43,401,402],{},"Bake editing;",[43,404,405],{},"experimental vulnerability analysis;",[43,407,408,410],{},[47,409,392],{}," build debugging.",[149,412,414],{"id":413},"container-tools",[21,415,343],{"href":341,"rel":416},[25],[100,418,419,422,425,435],{},[43,420,421],{},"explorer for containers, images, networks, and volumes;",[43,423,424],{},"management commands in the Command Palette;",[43,426,427,428,430,431,434],{},"generating ",[47,429,392],{},", ",[47,432,433],{},".dockerignore",", and Compose files;",[43,436,437,114,440,50],{},[47,438,439],{},"Compose Up",[47,441,442],{},"Compose Up - Select Services",[149,444,446],{"id":445},"microsoft-docker-extension-pack",[21,447,449],{"href":322,"rel":448},[25],"Microsoft Docker Extension Pack",[14,451,452,453,456],{},"Today it mostly serves as a transition point. The Marketplace itself explains that the Docker extension became an extension pack and that ",[21,454,343],{"href":341,"rel":455},[25]," replaced the earlier extension.",[141,458,460],{"id":459},"can-i-use-docker-dx-and-container-tools-together","Can I use Docker DX and Container Tools together?",[14,462,463],{},"Yes. In fact, both Docker and Microsoft describe that setup as valid.",[14,465,466],{},"In practice, the split usually looks like this:",[100,468,469,479],{},[43,470,471,472,475,476,478],{},"use ",[21,473,26],{"href":23,"rel":474},[25]," to write and debug ",[47,477,392],{}," files;",[43,480,471,481,484],{},[21,482,343],{"href":341,"rel":483},[25]," to manage containers and Compose workflows.",[14,486,487,488,491],{},"The only thing to watch for is duplicated features, especially in Compose. The ",[21,489,26],{"href":23,"rel":490},[25]," FAQ documents cases where repeated suggestions and hovers may appear.",[14,493,494],{},"If that happens, in your VS Code settings, you can disable the overlapping features in one of the extensions.",[32,496,498],{"id":497},"how-to-configure-docker-dx-in-vs-code","How to configure Docker DX in VS Code",[14,500,501],{},"There are two main ways to start.",[141,503,505],{"id":504},"quick-start","Quick start",[14,507,508,509,511,512,430,515,518],{},"If you open a ",[47,510,392],{}," and go to ",[47,513,514],{},"Run and Debug",[21,516,26],{"href":23,"rel":517},[25]," can often fill in a minimal configuration automatically.",[14,520,521],{},"For a quick test, that is usually enough.",[141,523,525],{"id":524},"explicit-launchjson-configuration","Explicit launch.json configuration",[14,527,528,529,282],{},"If you want something reproducible, it is better to save the configuration in ",[47,530,531],{},".vscode\u002Flaunch.json",[14,533,534],{},"Minimal example:",[168,536,540],{"className":537,"code":538,"language":539,"meta":173,"style":173},"language-json shiki shiki-themes github-dark","{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"type\": \"dockerfile\",\n      \"request\": \"launch\",\n      \"name\": \"Docker: Build\",\n      \"dockerfile\": \"Dockerfile\",\n      \"contextPath\": \"${workspaceFolder}\"\n    }\n  ]\n}\n","json",[47,541,542,547,562,571,577,590,603,616,629,640,646,652],{"__ignoreMap":173},[177,543,544],{"class":179,"line":180},[177,545,546],{"class":221},"{\n",[177,548,550,553,556,559],{"class":179,"line":549},2,[177,551,552],{"class":255},"  \"version\"",[177,554,555],{"class":221},": ",[177,557,558],{"class":187},"\"0.2.0\"",[177,560,561],{"class":221},",\n",[177,563,565,568],{"class":179,"line":564},3,[177,566,567],{"class":255},"  \"configurations\"",[177,569,570],{"class":221},": [\n",[177,572,574],{"class":179,"line":573},4,[177,575,576],{"class":221},"    {\n",[177,578,580,583,585,588],{"class":179,"line":579},5,[177,581,582],{"class":255},"      \"type\"",[177,584,555],{"class":221},[177,586,587],{"class":187},"\"dockerfile\"",[177,589,561],{"class":221},[177,591,593,596,598,601],{"class":179,"line":592},6,[177,594,595],{"class":255},"      \"request\"",[177,597,555],{"class":221},[177,599,600],{"class":187},"\"launch\"",[177,602,561],{"class":221},[177,604,606,609,611,614],{"class":179,"line":605},7,[177,607,608],{"class":255},"      \"name\"",[177,610,555],{"class":221},[177,612,613],{"class":187},"\"Docker: Build\"",[177,615,561],{"class":221},[177,617,619,622,624,627],{"class":179,"line":618},8,[177,620,621],{"class":255},"      \"dockerfile\"",[177,623,555],{"class":221},[177,625,626],{"class":187},"\"Dockerfile\"",[177,628,561],{"class":221},[177,630,632,635,637],{"class":179,"line":631},9,[177,633,634],{"class":255},"      \"contextPath\"",[177,636,555],{"class":221},[177,638,639],{"class":187},"\"${workspaceFolder}\"\n",[177,641,643],{"class":179,"line":642},10,[177,644,645],{"class":221},"    }\n",[177,647,649],{"class":179,"line":648},11,[177,650,651],{"class":221},"  ]\n",[177,653,655],{"class":179,"line":654},12,[177,656,657],{"class":221},"}\n",[14,659,660],{},"If you need to, you can also add:",[100,662,663,669,679],{},[43,664,665,668],{},[47,666,667],{},"target"," to pick a specific stage;",[43,670,671,674,675,678],{},[47,672,673],{},"args"," to pass ",[47,676,677],{},"--build-arg"," and other build arguments;",[43,680,681,684,685,688],{},[47,682,683],{},"stopOnEntry"," set to ",[47,686,687],{},"true"," to suspend right at the start.",[14,690,691],{},"A slightly more complete example:",[168,693,695],{"className":537,"code":694,"language":539,"meta":173,"style":173},"{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"type\": \"dockerfile\", \u002F\u002F required, must not be modified\n      \"request\": \"launch\", \u002F\u002F required, must not be modified\n      \"name\": \"Docker: Build\", \u002F\u002F required, configurable\n      \"dockerfile\": \"Dockerfile\", \u002F\u002F required, configurable\n      \"contextPath\": \"${workspaceFolder}\", \u002F\u002F optional, defaults to ${workspaceFolder}\n      \"cwd\": \"${workspaceFolder}\", \u002F\u002F optional, defaults to ${workspaceFolder}\n      \"target\": \"builder\", \u002F\u002F optional, should be a build stage in the Dockerfile\n      \"args\": [\"--build-arg\", \"NODE_ENV=development\"], \u002F\u002F additional arguments for the build command\n      \"stopOnEntry\": false \u002F\u002F if the debugger should suspend on the first line, defaults to false\n    }\n  ]\n}\n",[47,696,697,701,711,717,721,735,747,760,772,786,799,814,836,850,855,860],{"__ignoreMap":173},[177,698,699],{"class":179,"line":180},[177,700,546],{"class":221},[177,702,703,705,707,709],{"class":179,"line":549},[177,704,552],{"class":255},[177,706,555],{"class":221},[177,708,558],{"class":187},[177,710,561],{"class":221},[177,712,713,715],{"class":179,"line":564},[177,714,567],{"class":255},[177,716,570],{"class":221},[177,718,719],{"class":179,"line":573},[177,720,576],{"class":221},[177,722,723,725,727,729,731],{"class":179,"line":579},[177,724,582],{"class":255},[177,726,555],{"class":221},[177,728,587],{"class":187},[177,730,430],{"class":221},[177,732,734],{"class":733},"sAwPA","\u002F\u002F required, must not be modified\n",[177,736,737,739,741,743,745],{"class":179,"line":592},[177,738,595],{"class":255},[177,740,555],{"class":221},[177,742,600],{"class":187},[177,744,430],{"class":221},[177,746,734],{"class":733},[177,748,749,751,753,755,757],{"class":179,"line":605},[177,750,608],{"class":255},[177,752,555],{"class":221},[177,754,613],{"class":187},[177,756,430],{"class":221},[177,758,759],{"class":733},"\u002F\u002F required, configurable\n",[177,761,762,764,766,768,770],{"class":179,"line":618},[177,763,621],{"class":255},[177,765,555],{"class":221},[177,767,626],{"class":187},[177,769,430],{"class":221},[177,771,759],{"class":733},[177,773,774,776,778,781,783],{"class":179,"line":631},[177,775,634],{"class":255},[177,777,555],{"class":221},[177,779,780],{"class":187},"\"${workspaceFolder}\"",[177,782,430],{"class":221},[177,784,785],{"class":733},"\u002F\u002F optional, defaults to ${workspaceFolder}\n",[177,787,788,791,793,795,797],{"class":179,"line":642},[177,789,790],{"class":255},"      \"cwd\"",[177,792,555],{"class":221},[177,794,780],{"class":187},[177,796,430],{"class":221},[177,798,785],{"class":733},[177,800,801,804,806,809,811],{"class":179,"line":648},[177,802,803],{"class":255},"      \"target\"",[177,805,555],{"class":221},[177,807,808],{"class":187},"\"builder\"",[177,810,430],{"class":221},[177,812,813],{"class":733},"\u002F\u002F optional, should be a build stage in the Dockerfile\n",[177,815,816,819,822,825,827,830,833],{"class":179,"line":654},[177,817,818],{"class":255},"      \"args\"",[177,820,821],{"class":221},": [",[177,823,824],{"class":187},"\"--build-arg\"",[177,826,430],{"class":221},[177,828,829],{"class":187},"\"NODE_ENV=development\"",[177,831,832],{"class":221},"], ",[177,834,835],{"class":733},"\u002F\u002F additional arguments for the build command\n",[177,837,839,842,844,847],{"class":179,"line":838},13,[177,840,841],{"class":255},"      \"stopOnEntry\"",[177,843,555],{"class":221},[177,845,846],{"class":255},"false",[177,848,849],{"class":733}," \u002F\u002F if the debugger should suspend on the first line, defaults to false\n",[177,851,853],{"class":179,"line":852},14,[177,854,645],{"class":221},[177,856,858],{"class":179,"line":857},15,[177,859,651],{"class":221},[177,861,863],{"class":179,"line":862},16,[177,864,657],{"class":221},[32,866,868],{"id":867},"how-to-debug-a-docker-build","How to debug a Docker build",[14,870,871],{},"Once the configuration is in place, the flow is fairly straightforward.",[141,873,875],{"id":874},"_1-set-a-breakpoint-on-a-useful-instruction","1. Set a breakpoint on a useful instruction",[14,877,878,879,882],{},"In general, ",[47,880,881],{},"RUN"," instructions are the best places to stop, because by that point you usually already have useful state to inspect and a concrete command whose effects are easy to validate.",[14,884,885],{},[886,887],"img",{"alt":888,"src":889},"Setting Breakpoints","https:\u002F\u002Fgithub.com\u002Fdocker\u002Fvscode-extension\u002Fraw\u002Fmain\u002Fresources\u002Fdebugging\u002Fadd-breakpoints.png",[141,891,893],{"id":892},"_2-start-the-session","2. Start the session",[14,895,896,897,900,901,903],{},"You can start the session with ",[47,898,899],{},"F5"," or by clicking the start button in the ",[47,902,514],{}," panel.",[14,905,906,907,282],{},"The build will stop at the marked instruction, or right at the beginning if you use ",[47,908,683],{},[141,910,912],{"id":911},"_3-inspect-variables","3. Inspect variables",[14,914,915,916,919,920,922],{},"In the ",[47,917,918],{},"Variables"," panel, VS Code shows ",[47,921,117],{}," values and filesystem state. That is especially useful when you have variable substitution, computed paths, parameterized versions, or stages that behave differently depending on the environment.",[14,924,925],{},[886,926],{"alt":927,"src":928},"Inspecting Variables","https:\u002F\u002Fgithub.com\u002Fdocker\u002Fvscode-extension\u002Fraw\u002Fmain\u002Fresources\u002Fdebugging\u002Fvariables.png",[141,930,932],{"id":931},"_4-open-the-filesystem-explorer","4. Open the filesystem explorer",[14,934,935,936,938],{},"This is one of the most practical parts of the experience. Instead of running ",[47,937,65],{}," and browsing a shell just to confirm whether a file exists, you can inspect the directory tree directly in the debugger.",[14,940,941],{},"That is especially useful for catching issues such as:",[100,943,944,949,952,957],{},[43,945,946,948],{},[47,947,80],{}," going to the wrong path;",[43,950,951],{},"an incomplete build context;",[43,953,954,955,50],{},"files excluded by ",[47,956,433],{},[43,958,959],{},"accidentally creating a file where you expected a directory.",[141,961,963,964,966],{"id":962},"_5-use-exec-in-the-debug-console","5. Use ",[47,965,127],{}," in the Debug Console",[14,968,969,970,973,974,976,977,282],{},"When the build is suspended, open the ",[47,971,972],{},"Debug Console",", type ",[47,975,127],{},", and press ",[47,978,979],{},"Enter",[14,981,982,983,282],{},"If everything works as expected, VS Code opens a new terminal attached to the current image state. From there you can test commands, validate paths, try installing a package, and confirm the fix before writing it back into the ",[47,984,392],{},[14,986,987],{},"That shortens the feedback loop a lot between:",[100,989,990,993,996],{},[43,991,992],{},"finding the problem;",[43,994,995],{},"validating the hypothesis;",[43,997,998,999,282],{},"and writing the correct line back into the ",[47,1000,392],{},[14,1002,1003],{},[886,1004],{"alt":1005,"src":1006},"Opening a Shell Inside the Image Being Built","https:\u002F\u002Fgithub.com\u002Fdocker\u002Fvscode-extension\u002Fraw\u002Fmain\u002Fresources\u002Fdebugging\u002Fdebug-exec-invoke.png",[32,1008,1010],{"id":1009},"a-practical-example","A practical example",[14,1012,1013,1014,1016],{},"Imagine this ",[47,1015,392],{},":",[168,1018,1022],{"className":1019,"code":1020,"language":1021,"meta":173,"style":173},"language-dockerfile shiki shiki-themes github-dark","FROM mcr.microsoft.com\u002Fdotnet\u002Fsdk:10.0.201 AS build\n\nWORKDIR \u002Fsrc\n\nCOPY .\u002Fsrc\u002F*.csproj .\u002F\nRUN dotnet restore .\u002F*.csproj\n\nCOPY .\u002F .\u002F\n\nRUN ls -la .\u002F\nRUN dotnet build -c Release .\u002F*.csproj\nRUN dotnet publish .\u002F*.csproj \\\n  -c Release \\\n  --no-build \\\n  --no-restore \\\n  -o \u002Fpublish\n\nFROM mcr.microsoft.com\u002Fdotnet\u002Faspnet:10.0.5 AS runtime\n\nCOPY --from=build \u002Fpublish .\n\nENTRYPOINT [\"dotnet\", \"Demo.Api.dll\"]\n","dockerfile",[47,1023,1024,1038,1044,1051,1055,1062,1069,1073,1080,1084,1091,1098,1105,1110,1115,1120,1125,1130,1143,1148,1156,1161],{"__ignoreMap":173},[177,1025,1026,1029,1032,1035],{"class":179,"line":180},[177,1027,1028],{"class":225},"FROM",[177,1030,1031],{"class":221}," mcr.microsoft.com\u002Fdotnet\u002Fsdk:10.0.201 ",[177,1033,1034],{"class":225},"AS",[177,1036,1037],{"class":221}," build\n",[177,1039,1040],{"class":179,"line":549},[177,1041,1043],{"emptyLinePlaceholder":1042},true,"\n",[177,1045,1046,1048],{"class":179,"line":564},[177,1047,84],{"class":225},[177,1049,1050],{"class":221}," \u002Fsrc\n",[177,1052,1053],{"class":179,"line":573},[177,1054,1043],{"emptyLinePlaceholder":1042},[177,1056,1057,1059],{"class":179,"line":579},[177,1058,80],{"class":225},[177,1060,1061],{"class":221}," .\u002Fsrc\u002F*.csproj .\u002F\n",[177,1063,1064,1066],{"class":179,"line":592},[177,1065,881],{"class":225},[177,1067,1068],{"class":221}," dotnet restore .\u002F*.csproj\n",[177,1070,1071],{"class":179,"line":605},[177,1072,1043],{"emptyLinePlaceholder":1042},[177,1074,1075,1077],{"class":179,"line":618},[177,1076,80],{"class":225},[177,1078,1079],{"class":221}," .\u002F .\u002F\n",[177,1081,1082],{"class":179,"line":631},[177,1083,1043],{"emptyLinePlaceholder":1042},[177,1085,1086,1088],{"class":179,"line":642},[177,1087,881],{"class":225},[177,1089,1090],{"class":221}," ls -la .\u002F\n",[177,1092,1093,1095],{"class":179,"line":648},[177,1094,881],{"class":225},[177,1096,1097],{"class":221}," dotnet build -c Release .\u002F*.csproj\n",[177,1099,1100,1102],{"class":179,"line":654},[177,1101,881],{"class":225},[177,1103,1104],{"class":221}," dotnet publish .\u002F*.csproj \\\n",[177,1106,1107],{"class":179,"line":838},[177,1108,1109],{"class":221},"  -c Release \\\n",[177,1111,1112],{"class":179,"line":852},[177,1113,1114],{"class":221},"  --no-build \\\n",[177,1116,1117],{"class":179,"line":857},[177,1118,1119],{"class":221},"  --no-restore \\\n",[177,1121,1122],{"class":179,"line":862},[177,1123,1124],{"class":221},"  -o \u002Fpublish\n",[177,1126,1128],{"class":179,"line":1127},17,[177,1129,1043],{"emptyLinePlaceholder":1042},[177,1131,1133,1135,1138,1140],{"class":179,"line":1132},18,[177,1134,1028],{"class":225},[177,1136,1137],{"class":221}," mcr.microsoft.com\u002Fdotnet\u002Faspnet:10.0.5 ",[177,1139,1034],{"class":225},[177,1141,1142],{"class":221}," runtime\n",[177,1144,1146],{"class":179,"line":1145},19,[177,1147,1043],{"emptyLinePlaceholder":1042},[177,1149,1151,1153],{"class":179,"line":1150},20,[177,1152,80],{"class":225},[177,1154,1155],{"class":221}," --from=build \u002Fpublish .\n",[177,1157,1159],{"class":179,"line":1158},21,[177,1160,1043],{"emptyLinePlaceholder":1042},[177,1162,1164,1167,1170,1173,1175,1178],{"class":179,"line":1163},22,[177,1165,1166],{"class":225},"ENTRYPOINT",[177,1168,1169],{"class":221}," [",[177,1171,1172],{"class":187},"\"dotnet\"",[177,1174,430],{"class":221},[177,1176,1177],{"class":187},"\"Demo.Api.dll\"",[177,1179,1180],{"class":221},"]\n",[14,1182,1183,1184,1187,1188,282],{},"The problem is ",[47,1185,1186],{},"COPY .\u002F .\u002F",", which should be ",[47,1189,1190],{},"COPY .\u002Fsrc .\u002F",[14,1192,1193,1194,1197,1198,1201,1202,1204],{},"In other words, you expected the contents of the ",[47,1195,1196],{},"src"," folder to be available directly inside ",[47,1199,1200],{},"\u002Fsrc",", but ",[47,1203,1186],{}," copied the repository root.",[14,1206,1207,1208,1211],{},"Without ",[21,1209,26],{"href":23,"rel":1210},[25],", the usual path would be:",[100,1213,1214,1218,1221,1224,1227,1230,1233],{},[43,1215,45,1216,50],{},[47,1217,49],{},[43,1219,1220],{},"read the error;",[43,1222,1223],{},"maybe comment out lines below it;",[43,1225,1226],{},"create an intermediate image;",[43,1228,1229],{},"open a shell;",[43,1231,1232],{},"inspect the filesystem manually;",[43,1234,1235],{},"and go back to the file.",[14,1237,1238,1239,1016],{},"With ",[21,1240,26],{"href":23,"rel":1241},[25],[40,1243,1244,1249,1252,1257,1260],{},[43,1245,1246,1247,50],{},"set a breakpoint on the ",[47,1248,881],{},[43,1250,1251],{},"start the debug session;",[43,1253,45,1254,1256],{},[47,1255,127],{}," to open a shell and inspect the filesystem, or use the filesystem explorer directly;",[43,1258,1259],{},"confirm the fix:",[43,1261,1262,1263,1265],{},"go back to the ",[47,1264,392],{}," and correct the line;",[14,1267,1268],{},"That kind of simple mistake does not justify five rebuilds in a row. This is exactly where the new experience pays off.",[141,1270,1272],{"id":1271},"reset-after-using-the-cli-during-debugging","Reset after using the CLI during debugging",[14,1274,1275,1276,1278],{},"This detail is worth being very clear about. When you use ",[47,1277,127],{}," to open a shell in the suspended image and make manual changes, those changes do not persist when you move to the next step.",[14,1280,1281],{},"The terminal itself warns you about that.",[168,1283,1288],{"className":1284,"code":1286,"language":1287},[1285],"language-text","Changes to the container will be reset after the next step is executed.\n","text",[47,1289,1286],{"__ignoreMap":173},[14,1291,1292,1293,1295],{},"That is actually a good product decision, because it stops the debug session from depending on ad hoc changes that were never written into the ",[47,1294,392],{},". The shell is there to validate ideas and experiment, not to patch the build outside the file.",[14,1297,1298],{},"In short:",[100,1300,1301,1306,1311],{},[43,1302,471,1303,1305],{},[47,1304,127],{}," to test;",[43,1307,1308,1309,50],{},"copy the real fix into the ",[47,1310,392],{},[43,1312,1313],{},"restart the debug session if you need to validate again.",[14,1315,1316],{},[886,1317],{"alt":1272,"src":1318},"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fvscode-extension\u002Fraw\u002Fmain\u002Fresources\u002Fdebugging\u002Fdebug-exec-shell.png",[32,1320,1322],{"id":1321},"other-ides-and-editors","Other IDEs and editors",[14,1324,1325],{},"Buildx relies on the Debug Adapter Protocol, so the idea is not locked to VS Code.",[141,1327,1329],{"id":1328},"vs-code","VS Code",[14,1331,1332],{},"This is still the most mature and direct implementation right now.",[141,1334,1336],{"id":1335},"neovim","Neovim",[14,1338,1339,1340,282],{},"The Buildx repository points to official support through the ",[21,1341,1344],{"href":1342,"rel":1343},"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fnvim-dap-docker",[25],"plugin",[141,1346,1348],{"id":1347},"jetbrains","JetBrains",[14,1350,1351,1352,1357],{},"In Docker's public material, integration with JetBrains IDEs shows up through DAP-related plugins such as ",[21,1353,1356],{"href":1354,"rel":1355},"https:\u002F\u002Fgithub.com\u002Fredhat-developer\u002Flsp4ij",[25],"LSP4IJ",". In practice, that means the integration is plugin-based rather than a native part of Docker DX itself.",[14,1359,1360],{},"If you want the lowest-friction option today, VS Code is still the most direct choice.",[32,1362,1364],{"id":1363},"limitations-worth-knowing-about","Limitations worth knowing about",[14,1366,1367],{},"You can still tell this is a relatively recent feature. It is already useful in day-to-day work, but it still has a few rough edges, many of them coming from Buildx DAP itself.",[14,1369,1370,1371,1373,1374,1376],{},"For example, ",[47,1372,127],{}," does not always open a shell, the file explorer does not work in every scenario, and stepping can still feel odd in some stages. DAP also has known limits, such as not distinguishing identical ",[47,1375,1028],{}," directives and not allowing arbitrary pauses.",[14,1378,1379],{},"That said, the direction is good. The feature is already useful today, and the current Buildx DAP documentation still lists limitations and future improvements, so it is reasonable to expect it to keep maturing.",[32,1381,1383],{"id":1382},"references","References",[100,1385,1386,1409],{},[43,1387,1388,1389],{},"Extensions\n",[100,1390,1391,1397,1403],{},[43,1392,1393],{},[21,1394,1396],{"href":23,"rel":1395},[25],"Docker DX on the Marketplace",[43,1398,1399],{},[21,1400,1402],{"href":341,"rel":1401},[25],"Container Tools on the Marketplace",[43,1404,1405],{},[21,1406,1408],{"href":322,"rel":1407},[25],"Docker Extension Pack on the Marketplace",[43,1410,1411,1412],{},"Debugging and DAP\n",[100,1413,1414,1421,1428,1435,1440],{},[43,1415,1416],{},[21,1417,1420],{"href":1418,"rel":1419},"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fvscode-extension\u002Fblob\u002Fmain\u002FDEBUGGING.md",[25],"Docker DX official debugging guide",[43,1422,1423],{},[21,1424,1427],{"href":1425,"rel":1426},"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fvscode-extension\u002Fblob\u002Fmain\u002FFAQ.md",[25],"Docker DX FAQ",[43,1429,1430],{},[21,1431,1434],{"href":1432,"rel":1433},"https:\u002F\u002Fgithub.com\u002Fdocker\u002Fbuildx\u002Fblob\u002Fmaster\u002Fdocs\u002Fdap.md",[25],"Buildx Debug Adapter Protocol",[43,1436,1437],{},[21,1438,1356],{"href":1354,"rel":1439},[25],[43,1441,1442],{},[21,1443,1446],{"href":1444,"rel":1445},"https:\u002F\u002Fmicrosoft.github.io\u002Fdebug-adapter-protocol",[25],"Debug Adapter Protocol",[1448,1449,1450],"style",{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":173,"searchDepth":549,"depth":549,"links":1452},[1453,1454,1457,1461,1465,1473,1476,1481,1482],{"id":34,"depth":549,"text":35},{"id":88,"depth":549,"text":89,"children":1455},[1456],{"id":143,"depth":564,"text":144},{"id":285,"depth":549,"text":286,"children":1458},[1459,1460],{"id":378,"depth":564,"text":379},{"id":459,"depth":564,"text":460},{"id":497,"depth":549,"text":498,"children":1462},[1463,1464],{"id":504,"depth":564,"text":505},{"id":524,"depth":564,"text":525},{"id":867,"depth":549,"text":868,"children":1466},[1467,1468,1469,1470,1471],{"id":874,"depth":564,"text":875},{"id":892,"depth":564,"text":893},{"id":911,"depth":564,"text":912},{"id":931,"depth":564,"text":932},{"id":962,"depth":564,"text":1472},"5. Use exec in the Debug Console",{"id":1009,"depth":549,"text":1010,"children":1474},[1475],{"id":1271,"depth":564,"text":1272},{"id":1321,"depth":549,"text":1322,"children":1477},[1478,1479,1480],{"id":1328,"depth":564,"text":1329},{"id":1335,"depth":564,"text":1336},{"id":1347,"depth":564,"text":1348},{"id":1363,"depth":549,"text":1364},{"id":1382,"depth":549,"text":1383},"2026-04-19","Learn how to debug Docker builds in VS Code with Docker DX, when to use Container Tools, and how to avoid blind rebuilds.","md",null,"en",{},"\u002Fblog\u002Fvscode-docker-build-debugging",{"title":5,"description":1484},"blog\u002Fvscode-docker-build-debugging",[369,1493],"VSCode","j7HoW5GXxGLEqvG9kaYMz95nazpeQW2576ZIrL28zD4",1776617315494]