DevContainers در حال تبدیل شدن به روش پیشفرض برای شروع کدنویسی یک پروژه جدید هستند

هر پروژه نرمافزاری سرانجام به جمله «روی ماشین من کار میکند» میرسد. ریشه این مشکل همیشه یکسان است: محیطهای توسعه محلی، نامرئی و تقریباً غیرممکن برای مستندسازی کامل هستند. شما ممکن است یک requirements.txt یا یک package.json را commit کنید، اما نمیتوانید نسخه Python، نسخه خاص یک کتابخانه C که توسط یک افزونه بومی لینک شده، متغیرهای محیطی تنظیم شده در پروفایل shell خود، یا ابزارهای سیستمی نصب شده بهصورت سراسری را commit کنید. فاصله بین آنچه ذخیره شده و آنچه واقعاً در حال اجراست، جایی است که اشکالزدایی از بین میرود.
Dev Containers یک رویکرد مبتنی بر مشخصات برای قابل تکرار، قابل حمل و نسخهبندی کردن محیطهای توسعه در کنار کد است. این مشخصات که در اصل توسط مایکروسافت برای VS Code توسعه یافته اما اکنون به عنوان یک استاندارد باز تحت سازمان GitHub devcontainers نگهداری میشود، یک فایل .devcontainer/devcontainer.json را تعریف میکند که محیط کامل را توصیف میکند: کدام تصویر Docker یا Dockerfile استفاده شود، کدام افزونههای VS Code نصب شوند، کدام پورتها فوروارد شوند، کدام دستورات چرخه حیات در هنگام راهاندازی اجرا شوند، و کدام متغیرهای محیطی تزریق شوند.
نحوه کار
هنگامی که یک پروژه با پیکربندی .devcontainer در VS Code باز میکنید، IDE از شما میخواهد که دوباره در یک container باز کنید. تصویر Docker مشخص شده را میسازد یا میکشد، container را اجرا میکند و دایرکتوری پروژه شما را درون آن mount میکند. سپس ویرایشگر شما طوری عمل میکند که گویی در حال اجرای محلی است، اما سرورهای زبان، linterها، formatterها و debuggerهای آن همگی داخل container در برابر محیط دقیقی که در فایل پیکربندی مشخص شده اجرا میشوند. روی ماشین توسعهدهنده دیگری – یا در GitHub Codespaces، یا در یک Pipeline CI – همان container بهطور یکسان ساخته و اجرا میشود.
فرمت devcontainer.json به یک DSL محیطی نسبتاً کامل تبدیل شده است. میتوانید یک تصویر پایه (mcr.microsoft.com/devcontainers/python:3.12، یک تصویر داخلی تیم، یا یک Dockerfile محلی) مشخص کنید، بستههای سیستمی اضافی را از طریق features – افزونههای محیطی کوچک و ترکیبپذیر که توسط مایکروسافت و جامعه برای مواردی مانند Docker-in-Docker، GitHub CLI، Terraform، یا Node.js نگهداری میشوند – نصب کنید، و دستورات پس از ایجاد را مشخص کنید که بهطور خودکار هنگام شروع container اجرا میشوند. فیلد customizations.vscode.extensions در VS Code تضمین میکند که هر توسعهدهنده پروژه را با همان مجموعه افزونههای نصب شده باز کند، بدون نیاز به هماهنگی دستی درباره نسخه linter که هر کس اجرا میکند.
GitHub Codespaces و محیط توسعه ابری
GitHub Codespaces بزرگترین استقرار مشخصات Dev Container است. هنگامی که یک Codespace را در هر مخزن GitHub – از جمله یک Fork که قبلاً به آن دست نزدهاید – باز میکنید، GitHub یک container از devcontainer.json مخزن (یا یک پیشفرض منطقی در صورت عدم وجود) میسازد و یک VS Code مبتنی بر مرورگر کاملاً پیکربندی شده به شما میدهد که به آن متصل است. محیط توسعه حدود 30 ثانیه در دسترس است.
برای مشارکت در نرمافزار متنباز، تأثیر بر فرایند ورود قابل توجه است. مسیر سنتی برای مشارکت در یک پروژه شامل کلون کردن، خواندن یک CONTRIBUTING.md، نصب runtimeهای زبان، فهمیدن اینکه کدام نسخه از یک وابستگی با چیز دیگری در سیستم شما تداخل دارد، و صرف 45 دقیقه قبل از نوشتن یک خط کد بود. یک مخزن با قابلیت Codespace آن را به این کاهش میدهد: روی "Code" کلیک کنید، روی "Open in Codespace" کلیک کنید، 30 ثانیه صبر کنید، کدنویسی را شروع کنید. برای maintainerهایی که به دنبال کاهش مانع مشارکت هستند، این یک تغییر معنادار است.
برای سازمانها، Codespaces ارزش متفاوتی ارائه میدهد: زمان ورود توسعهدهنده. روز اول یک مهندس جدید در یک شرکت معمولاً ساعتها پیکربندی یک محیط توسعه محلی را شامل میشود – نصب نسخه صحیح هر ابزار، پیکربندی اعتبارنامهها، اجرای اسکریپتهای راهاندازی که نیمهکاره عمل میکنند. یک devcontainer بهدرستی پیکربندی شده آن را به باز کردن یک مرورگر کاهش میدهد. GitHub گزارش میدهد که سازمانهایی که بهطور منظم از Codespaces استفاده میکنند، زمان ورود را از روزها به ساعت کاهش میبینند.
فراتر از VS Code: مشخصات باز
مشخصات Dev Container دیگر منحصر به VS Code نیست. IDEهای JetBrains (IntelliJ، WebStorm، PyCharm، GoLand) از پیکربندیهای devcontainer بهصورت بومی پشتیبانی میکنند. devcontainer CLI امکان ساخت و اجرای containerها را از خط فرمان بدون هیچ IDE فراهم میکند. و از آنجایی که مشخصات مبتنی بر Docker است، هر سیستم CI که میتواند Docker را اجرا کند، میتواند از همان container برای تست استفاده کند که توسعهدهندگان برای توسعه استفاده میکنند – این کلاس از باگهای "محلی عبور میکند، در CI شکست میخورد" را که ناشی از تفاوت محیط است حذف میکند.
Daytona، Coder و چند شرکت دیگر پلتفرمهای محیط توسعه از راه دور مدیریت شده را بر اساس مشخصات Dev Container ساختهاند که هدف آن شرکتهایی است که عملکرد مشابه Codespaces را بدون وابستگی به GitHub میخواهند. استاندارد باز به این معنی است که اکوسیستم ابزار به یک فروشنده خاص محدود نمیشود.
زمانی که DevContainers ارزش سربار را دارند
DevContainers ابزار مناسبی برای هر پروژه نیستند. سربار واقعی است: زمان راهاندازی container (معمولاً 5-30 ثانیه بسته به اندازه تصویر و سختافزار)، لایه شناختی "آیا الان داخل container هستم" و زمان مهندسی برای نوشتن و نگهداری یک devcontainer.json خوب. برای یک پروژه فردی با یک stack ساده و پایدار، یک محیط مجازی و یک README ممکن است کافی باشد.
جایی که DevContainers بهوضوح هزینه خود را پرداخت میکنند: پروژههایی با وابستگیهای بومی پیچیده (درایورهای پایگاه داده، کتابخانههای پردازش تصویر، فریمورکهای ML با نیازمندیهای CUDA)، تیمهایی با ناهمگنی قابل توجه OS (توسعهدهندگان Windows، macOS، Linux روی یک پروژه)، پروژههایی با مسیرهای ورود طولانی، و هر پروژهای که در آن "دیروز کار میکرد، امروز Homebrew را بهروز کردم" یک مکالمه تکراری است. هرچه محیط پیچیدهتر و وابسته به تیم باشد، استدلال قویتر است.
استدلال برابری CI صرفنظر از اندازه تیم بهطور جداگانه قانعکننده است. اجرای تستها در همان container که در آن توسعه میدهید، یکی از ناامیدکنندهترین الگوهای اشکالزدایی در نرمافزار را حذف میکند: تستی که به دلیل یک وابستگی محیطی (یک ابزار نصب شده سراسری، یک فایل در دایرکتوری خانه، یک تنظیمات locale خاص) بهصورت محلی عبور میکند و در CI شکست میخورد زیرا محیط CI تمیزتر است.
نقطه شروع عملی
سادهترین راه برای امتحان DevContainers، پروژهای است که از قبل دارای Dockerfile یا از Docker Compose استفاده میکند. یک .devcontainer/devcontainer.json اضافه کنید که به Dockerfile موجود شما اشاره کند، افزونههایی که تیم شما استفاده میکند را مشخص کنید و آن را commit کنید. افزونه Dev Containers VS Code (رایگان، بیش از 30 میلیون دانلود) بقیه کار را انجام میدهد. قالبهای devcontainer مایکروسافت – موجود در containers.dev – نقاط شروع برای بیشتر stackهای رایج را فراهم میکنند: Node.js، Python، Go، Rust، Java، .NET، Ruby، PHP و بیشتر.
مشکل "روی ماشین من کار میکند" توسط DevContainers بهطور کامل حل نمیشود – پیکربندی زمان اجرا، وضعیت پایگاه داده تولید و تفاوتهای توپولوژی شبکه همچنان وجود دارند. اما برای لایهای از مشکل که در نسخههای ابزار و وابستگیهای سیستمی قرار دارد، مشخصات به اندازه کافی بالغ شده است که "یک devcontainer اضافه کنید" اکنون توصیهای منطقی برای بیشتر پروژههایی است که بهطور پیشپا افتاده ساده نیستند.