Egy Docker-tároló karcsúsítása közel 8 GB-ról 200 MB-ra
írta Joshua Harms
A webfejlesztőknek nem ismeretlenek a duzzadt alkalmazások vagy a gigantikus Docker-tárolók. Bár sok alkalmazás lenyűgöző eredményeket érhet el csupán a "node_modules" varázsszavak kimondásával, egy viszonylag egyszerű dotnet alkalmazás is terjedelmes lehet, ha a dotnet SDK és a csomagfüggőségek telepítve vannak.
Ilyen volt az éppen ezt a weboldalt futtató tároló, amely egy egyedi F # program (egy másik .NET nyelv, a C # testvére), nulla csomópontfüggőséggel, kivéve a Stylus és a TypeScript fordítókat. Ezen a webhelyen még a package.json fájl sem található, és a node_modules mappába nem kerül telepítésre függőség. Nagyon közel van a tiszta .NET-hez, és az a Docker-tároló volt, amely a webhelyet üzemeltette közel 8gb egyszer építették.
Elképesztő módon azt sem vettem észre, hogy a webhely tárolója akkora volt, amíg meg nem próbáltam áthelyezni a webhelyet egy egyéni virtuális gépről egy Azure Container webalkalmazásra. A méret olyan nagy volt, hogy a konténer szó szerint nem fog működni az Azure Basic B1 csomagján - a rendelkezésre álló legolcsóbb terv, egyetlen lépéssel magasabb az ingyenes. Az Azure számítási példányom egyáltalán nem tudta meghúzni/kivonni/futtatni a tárolót, és csak 502 szolgáltatás nem elérhető hibát adna vissza.
Kiderült, hogy elkövettem néhány "újonc" hibát, ami miatt a tartályom mérete annyira felpuffadt. Az "újoncot" idézőjelbe tettem, mert ezek többsége olyan dolog, amit tudtam, hogy csinálnom kell, de inkább a lusta utat választottam. Nem gondoltam, hogy ez számít egy ilyen kicsi webhelynek, mert végül is nincs olyan, hogy egy majdnem statikus webhely több legyen, mint egy vagy két gigabájt, ha egyszer egy konténerbe került, ugye?
De utólag visszatekintve ezek az újonc hibák számítanak, és az első passznál kicsit többet kellett volna fektetnem a Dockerfile-m. Három könnyű változtatást hajtottam végre tömegesen csökkentse a webhely tárolójának méretét majdnem nyolc gigabájtról kétszáz megabájt alá:
- Használjon többlépcsős buildeket. A Docker konténerem az fsharp: netcore képet használta, ami önmagában is elég nagy, majd telepítettem a NodeJS futásidőt (és az összes mögöttes csomagot, amelyre támaszkodik), valamint a Stylus és a TypeScript fordítóimat. A többlépcsős összeállítások használatával csak olyan biteket kell bevinnie, mint az F # fordító és a Node a szükséges lépésekhez, majd elejtheti őket, és átmásolhatja a dolgokat egy karcsúbb képbe.
- A forráskód összeállítása után távolítsa el a felesleges fájlokat és csomagokat. Míg maguk a forráskódfájlok nem olyan nagyok, ennek a webhelynek a .NET csomag mappája maga is meghaladta a két gigabájtot - és csak egy olyan webhelyre vonatkozik, ahol csak négy .NET függőség van.
- Használja az Alpine-t végső futásképként. Ez részben kapcsolódik az # 1-hez, de különösen az Alpine használata hatalmas győzelmet jelent minden konténeres alkalmazás számára, mivel összességében kevesebb mint hat megabájt! Ez hatalmas mennyiségű helyet takarít meg, ha csak az adott képet használja a tároló utolsó futási képként. Ezt a zsírt azonban valahonnan levágták, ami azt jelenti, hogy az Alpine-nak csak a futtatásához szükséges csupasz szükségletek vannak, és nem tartozik hozzá olyan közös bináris fájlok, amelyeket egy szokásos Ubuntu-képen találhat.
Egy példa
Vessen egy pillantást egy gyors példára, ahol végigfuttathatjuk a fent vázolt lépéseket. Az alábbiakban pontosan ugyanaz a Dockerfile található, amelyet ezen a weboldalon használtam, mielőtt lecsökkentettem volna:
És ez a Dockerfile egy 7,61 GB méretű tárolót eredményezett:
Amint a Dockerfile-ban láthatja, nem volt csomag.json, és a Node és a Fonal telepítésének egyetlen oka a TypeScript és a Stylus fordító telepítése volt. A webhely a Paket nevű .NET csomagkezelőt használta (és használja) a weboldal csomagjainak visszaállításához. A Paket nagyon hasonlít a Nuget-hez, azzal a különbséggel, hogy támogatja a zárfájlokat, amikor a Nuget parancssori felület nem (bár a zárfájlok hamarosan hamarosan a Nuget-be érkeznek).
A Paket által helyreállított .NET-csomagok egyszerűen a legnagyobb tároló disznók voltak, a tároló képen kívül. A csomagok helyreállítása után borsos volt a súlya 2gb. Ami még meglepőbb, hogy ezt a két gigabájtnyi csomagot egy olyan webhelyhez telepítették, amelynek csak négy függősége van: FSharp.Core, Microsoft.Fsharplu.Json (könnyű JSON-elemző az F # számára), Suave (könnyű webkeret, például ASP). NET vagy Nancy) és a Markdig (egy csomag a Markdown HTML formátumba konvertálásához).
Azt, hogy ez a négy függőség hogyan alakul két gigabájtra, soha nem fogom tudni, mivel még azt is elrendeltem, hogy a Paket kifejezetten csak a netstandard1.0 keretrendszerhez telepítsen csomagokat (ahol általában alapértelmezés szerint az összes keretrendszer-verzióhoz telepít csomagokat, hogy a keretrendszer gyorsabban váltson). Tudom, hogy a Node-nak komoly csomagtömeg-problémái vannak a node_modules mappában, de ez a két gigabájtos csomag-mappa könnyedén elfújja még az általam készített legnagyobb Node-projekteket is.
Ettől függetlenül a Docker-tároló építési folyamata a következő volt:
- Húzza be az amúgy is nagy fsharp: netcore alapképet, és adja hozzá a Node/Fonalat.
- Telepítse a TypeScript és a Stylus fordítókat.
- Másolja az összes fájlt és mappát a forráskönyvtárból, és állítsa vissza a .NET-csomagokat a Paket használatával.
- Fordítsa le a Stylus és a TypeScript fájlokat.
- Hívja meg a dotnet közzétételt a webhely projektben, amely lefordítja a programot, és összes függőséggel együtt összegyűjti őket, egyetlen mappába dobva őket.
A .NET projekt közzététele azt jelentette, hogy a weboldal futtatásához csak a kimeneti mappában volt szükség. A Paket (vagy akár a Nuget) által helyreállított csomagokra ezután már nincs szükség, és csak holt súlyként szolgálnak. Ezenkívül az összes C #, TypeScript és Stylus forrásfájl is holt súlyú volt. Ezeket már lefordították a programba, illetve a JS és a CSS fájlokba. Bár ezek a fájlok közel állnak a .NET csomagok mappájának méretéhez, még mindig nem szükségesek maguknak a webhelynek a futtatásához, és további célokat nem szolgálnak.
Többlépcsős építések hozzáadása
A Dockerfile (és a legtöbb más Dockerfile) legnagyobb fejlesztése a többlépcsős építkezés és a vékony alpesi képre cserélése a végén. A többlépcsős összeállítások azzal az előnnyel járnak, hogy nincs szükségünk a Node és a Yarn telepítésére - csak cserélhetünk a hivatalos Node képre, ha szükséges.
Szeretem rendszerezni a Docker build szkriptjeimet a leglassabb feladattól a leggyorsabbig, amely a Docker gyorsítótár-rendszer előnyeit kihasználva felhasználja az építési lépéseket, ha egyik fájl sem változott. Ebben az esetben a .NET/Paket visszaállítási és közzétételi folyamat a leglassabb része az építési folyamatnak, tehát ez megy először. Ha a TypeScript/Stylus fájlokon változtatásokat hajtanak végre, de az F # fájlokon nem változtatnak, akkor a Dockerfile újrafelhasználja a gyorsítótárban tárolt .NET visszaállítási/összeállítási/közzétételi lépéseket, és csak újrafordítja a kezelőfelület fájljait, ezzel megfelelő időt takarítva meg.
Nagyobb webalkalmazásokban elképzelhető, hogy a Webpack fordítási folyamat lassabb, és érdemes lehet, hogy ez a rész menjen először.
A többlépcsős építések használata valójában nagyon egyszerű. Minden Docker-fájlnak az IMAGENAME nevű fájlból kell indulnia, hogy kiválassza a kezdő képet, és a többlépcsős építések használatához csak annyit kell tennie, hogy még többet ad hozzá azokból, ahol szüksége van rájuk. Azok a képek, amelyeket használni fogok, az fsharp: netcore kép az F # alkalmazás felépítéséhez, majd áttérek a nodejs: 10 képre a TypeScript és a Stylus fordító telepítéséhez/futtatásához, majd végül átállok a Microsoft programra /dotnet:2.2-runtime-alpine a webkiszolgáló futtatásához.
Mivel a Docker minden egyes alkalommal, amikor más képre cserél, valójában egy új tárolóra vált, a fájlokat át kell másolni a különböző szakaszokból, és a WORKDIR-t mindig cserélni kell.
Ezekkel a változtatásokkal a Dockerfile-nak így kell kinéznie:
Egy dolgot észrevehet ebben a Dockerfile-ban: valójában megváltoztatom a dotnet publish parancs futási idejét linux-x64-ről linux-musl-x64-re. Ez néhány percet vett igénybe, mire gondoltam, de kiderült, hogy nem teheti közzé .NET projektjét Linux x64-re, és elvárhatja, hogy egy alpesi tárolóban működjön. Ez két különböző futási idő, ezért ahhoz, hogy a .NET projekt Alpine Docker konténerben működjön, meg kell céloznia a linux-musl-x64 programot .
Miután megépítette ezt a konténert a dokkoló build-myappal. 63% -kal csökken a teljes méret 7,61 gb-ról 2,75 gb-ra!
Mégis van még egy fejlesztés, mégpedig az, hogy csak az alkalmazás futtatásához feltétlenül szükséges fájlokat másolja át - ez azt jelenti, hogy eltávolítja a csomagokat, a forráskód fájlokat, és apró extra dolgokat, például a zárfájlokat és a README fájlokat. Nem lesz olyan drasztikus, mint az Alpine-ra váltás a végső képnél, de (esetemben) csak a csomagok mappa eltávolításával további két gigabájt szabadul fel.
(Látni fogja, hogy másolok egy "posts" mappát is, amely csak egy mappa, amely a weboldal összes bejegyzését tartalmazza Markdown formátumban.)
Végül, még egy dokkoló build-myapp után. 150 MB-nál kisebb súlyú tárolóhoz jutunk:
Néhány egyszerű fejlesztés a Dockerfile-ben drasztikusan csökkentette a konténer méretét 98-tal. Ez hatalmas győzelem valaminek, ami még a weboldal összeállításának folyamatát sem változtatja meg.
Ismerje meg, hogyan építhet sziklaszilárd Shopify alkalmazásokat a C # és az ASP.NET használatával!
Élvezte ezt a cikket? Írtam egy prémium tanfolyamot a C # és az ASP.NET fejlesztőknek, és ez a sziklaszilárd Shopify alkalmazások építéséről szól az első naptól.
Írja be ide az e-mail címét, és ingyenes mintát küldök Önnek Shopify fejlesztési kézikönyv. Segíteni fog a felhasználók Shopify-áruházainak integrálásában és a Shopify számlázási API-val történő terhelésben.
- Stratégiák a puffadt arcok karcsúsítására - Vine Vera véleményekVine Vera vélemények
- Többfunkciós hordozható gyönyörű lábfogyókúrás fitnesz felszerelés; Newestrends
- Szexi Karcsúsító fűzők az Aliexpressen
- Stratégiák a fogyókúra lefutásában; s Világ
- Alakítsa fel a fogyás legkönnyebb módját a karcsúsító megoldásokkal