Oktatóanyag: .NET-alkalmazás tárolóba helyezése
Ebben az oktatóanyagban megtudhatja, hogyan tárolózhat egy .NET-alkalmazást a Dockerrel. A tárolók számos funkcióval és előnnyel rendelkeznek, például nem módosítható infrastruktúra, hordozható architektúrát biztosítanak, és lehetővé teszik a méretezhetőséget. A rendszerkép segítségével tárolókat hozhat létre a helyi fejlesztési környezethez, a magánfelhőhöz vagy a nyilvános felhőhöz.
Az oktatóanyag során az alábbi lépéseket fogja végrehajtani:
- Egyszerű .NET-alkalmazás létrehozása és közzététele
- Dockerfile létrehozása és konfigurálása a .NET-hez
- Docker-rendszerkép összeállítása
- Docker-tároló létrehozása és futtatása
Megismerheti a Docker-tárolók .NET-alkalmazásokhoz készült buildelési és üzembe helyezési feladatait. A Docker-platform a Docker motorral gyorsan hozhat létre és csomagolhat alkalmazásokat Docker-rendszerképekként. Ezek a képek Dockerfile formátumban vannak megírva, hogy egy rétegzett tárolóban legyenek üzembe helyezve és futtatva.
Feljegyzés
Ez az oktatóanyag nem ASP.NET Core-alkalmazásokhoz készült. Ha ASP.NET Core-t használ, olvassa el a ASP.NET Core-alkalmazás oktatóanyagának tárolóba foglalását ismertető témakört.
Előfeltételek
Telepítse a következő előfeltételeket:
- .NET 8+ SDK
Ha telepítve van a .NET, adotnet --info
paranccsal állapítsa meg, hogy melyik SDK-t használja. - Docker Community Edition
- A Dockerfile és a .NET-példaalkalmazás ideiglenes munkamappája. Ebben az oktatóanyagban a docker-working nevet használjuk munkamappaként.
- .NET 7+ SDK
Ha telepítve van a .NET, adotnet --info
paranccsal állapítsa meg, hogy melyik SDK-t használja. - Docker Community Edition
- A Dockerfile és a .NET-példaalkalmazás ideiglenes munkamappája. Ebben az oktatóanyagban a docker-working nevet használjuk munkamappaként.
.NET-alkalmazás létrehozása
Szüksége van egy .NET-alkalmazásra, amelyet a Docker-tároló futtat. Nyissa meg a terminált, hozzon létre egy munkamappát, ha még nem tette meg, és írja be. A munkamappában futtassa a következő parancsot egy új projekt létrehozásához egy Alkalmazás nevű alkönyvtárban:
dotnet new console -o App -n DotNet.Docker
A mappafa a következőhöz hasonlóan néz ki:
📁 docker-working
└──📂 App
├──DotNet.Docker.csproj
├──Program.cs
└──📂 obj
├── DotNet.Docker.csproj.nuget.dgspec.json
├── DotNet.Docker.csproj.nuget.g.props
├── DotNet.Docker.csproj.nuget.g.targets
├── project.assets.json
└── project.nuget.cache
A dotnet new
parancs létrehoz egy alkalmazás nevű új mappát, és létrehoz egy ""Helló világ!" alkalmazás" konzolalkalmazást. Módosítsa a könyvtárakat, és lépjen az Alkalmazás mappába a terminálmunkamenetből. dotnet run
Az alkalmazás elindításához használja a parancsot. Az alkalmazás fut, és nyomtassa ki Hello World!
a parancs alatt:
cd App
dotnet run
Hello World!
Az alapértelmezett sablon létrehoz egy alkalmazást, amely a terminálon nyomtat, majd azonnal leáll. Ebben az oktatóanyagban egy határozatlan ideig hurkolható alkalmazást használ. Nyissa meg a Program.cs fájlt egy szövegszerkesztőben.
Tipp.
Ha Visual Studio Code-ot használ, az előző terminálmunkamenetből írja be a következő parancsot:
code .
Ekkor megnyílik a projektet tartalmazó alkalmazásmappa a Visual Studio Code-ban.
A Program.cs a következő C#-kódhoz hasonlóan kell kinéznie:
Console.WriteLine("Hello World!");
Cserélje le a fájlt a következő kódra, amely másodpercenként számokat számol:
var counter = 0;
var max = args.Length is not 0 ? Convert.ToInt32(args[0]) : -1;
while (max is -1 || counter < max)
{
Console.WriteLine($"Counter: {++counter}");
await Task.Delay(TimeSpan.FromMilliseconds(1_000));
}
var counter = 0;
var max = args.Length is not 0 ? Convert.ToInt32(args[0]) : -1;
while (max is -1 || counter < max)
{
Console.WriteLine($"Counter: {++counter}");
await Task.Delay(TimeSpan.FromMilliseconds(1_000));
}
Mentse a fájlt, és tesztelje újra a programot a következővel dotnet run
: . Ne feledje, hogy ez az alkalmazás határozatlan ideig fut. A Ctrl+C billentyűkombinációval állítsa le. Az alábbiakban egy példakimenet látható:
dotnet run
Counter: 1
Counter: 2
Counter: 3
Counter: 4
^C
Ha egy számot ad át a parancssorban az alkalmazásnak, az csak addig az összegig számít, majd kilép. Próbálja ki, dotnet run -- 5
hogy számoljon ötig.
Fontos
A rendszer nem adja át a paramétereket --
a dotnet run
parancsnak, és nem továbbítja az alkalmazásnak.
.NET-alkalmazás közzététele
Mielőtt hozzáadja a .NET-alkalmazást a Docker-lemezképhez, először közzé kell tenni. A legjobb, ha a tároló az alkalmazás közzétett verzióját futtatja. Az alkalmazás közzétételéhez futtassa a következő parancsot:
dotnet publish -c Release
Ez a parancs lefordítja az alkalmazást a közzétételi mappába. A közzétételi mappának a munkamappából való elérési útnak kell lennie.\App\bin\Release\net8.0\publish\
.
Ez a parancs lefordítja az alkalmazást a közzétételi mappába. A közzétételi mappának a munkamappából való elérési útnak kell lennie.\App\bin\Release\net7.0\publish\
.
Az Alkalmazás mappából szerezze be a közzétételi mappa könyvtárlistát, és ellenőrizze, hogy a DotNet.Docker.dll fájl létrejött-e.
dir .\bin\Release\net8.0\publish\
Directory: C:\Users\default\App\bin\Release\net8.0\publish
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 9/22/2023 9:17 AM 431 DotNet.Docker.deps.json
-a--- 9/22/2023 9:17 AM 6144 DotNet.Docker.dll
-a--- 9/22/2023 9:17 AM 157696 DotNet.Docker.exe
-a--- 9/22/2023 9:17 AM 11688 DotNet.Docker.pdb
-a--- 9/22/2023 9:17 AM 353 DotNet.Docker.runtimeconfig.json
dir .\bin\Release\net7.0\publish\
Directory: C:\Users\default\App\bin\Release\net7.0\publish
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2/13/2023 1:52 PM 431 DotNet.Docker.deps.json
-a--- 2/13/2023 1:52 PM 6144 DotNet.Docker.dll
-a--- 2/13/2023 1:52 PM 153600 DotNet.Docker.exe
-a--- 2/13/2023 1:52 PM 11052 DotNet.Docker.pdb
-a--- 2/13/2023 1:52 PM 253 DotNet.Docker.runtimeconfig.json
A Dockerfile létrehozása
A Dockerfile-fájlt a docker build
parancs egy tárolólemezkép létrehozásához használja. Ez a fájl egy Dockerfile nevű szövegfájl, amely nem rendelkezik kiterjesztéssel.
Hozzon létre egy Dockerfile nevű fájlt a .csproj könyvtárban, és nyissa meg egy szövegszerkesztőben. Ez az oktatóanyag a ASP.NET Core futtatókörnyezeti rendszerképet használja (amely tartalmazza a .NET-futtatókörnyezet rendszerképét), és megfelel a .NET-konzolalkalmazásnak.
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /App
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]
Feljegyzés
A rendszer szándékosan használja a ASP.NET Core futtatókörnyezeti rendszerképet, bár a mcr.microsoft.com/dotnet/runtime:8.0
rendszerképet használhatta volna.
Tipp.
Ez a Dockerfile többfázisú buildeket használ, amelyek a build rétegzésével optimalizálják a rendszerkép végső méretét, és csak a szükséges összetevőket hagyják meg. További információ: Docker Docs: többfázisú buildek.
A FROM
kulcsszóhoz teljes mértékben minősített Docker-tárolórendszerkép-név szükséges. A Microsoft Container Registry (MCR, mcr.microsoft.com) a Docker Hub szindikátusa, amely nyilvánosan elérhető tárolókat üzemeltet. A dotnet
szegmens a tárolóadattár, míg a sdk
szegmens aspnet
a tárolórendszerkép neve. A rendszerkép a verziószámozáshoz használt címkével 8.0
van megjelölve. mcr.microsoft.com/dotnet/aspnet:8.0
Így a .NET 8.0 futtatókörnyezet. Győződjön meg arról, hogy lekéri az SDK által megcélzott futtatókörnyezetnek megfelelő futtatókörnyezetet. Az előző szakaszban létrehozott alkalmazás például a .NET 8.0 SDK-t használta, a Dockerfile-ban hivatkozott alaprendszerkép pedig 8.0-val van megjelölve.
Fontos
Windows-alapú tárolórendszerképek használata esetén a rendszerképcímkét egyszerűen 8.0
meg kell adnia, például ahelyett, mcr.microsoft.com/dotnet/aspnet:8.0-nanoserver-1809
hogy a rendszerképcímkét kellene megadnia mcr.microsoft.com/dotnet/aspnet:8.0
. Válasszon egy képnevet attól függően, hogy a Nano Servert vagy a Windows Server Core-t használja-e, és hogy az operációs rendszer melyik verzióját használja. Az összes támogatott címke teljes listája megtalálható a webhelyen. A NET Docker Hub-oldala.
Mentse a Dockerfile fájlt. A munkamappa könyvtárszerkezetének az alábbihoz hasonlóan kell kinéznie. Néhány mélyebb szintű fájl és mappa kimaradt, hogy helyet takarítson meg a cikkben:
📁 docker-working
└──📂 App
├── Dockerfile
├── DotNet.Docker.csproj
├── Program.cs
├──📂 bin
│ └──📂 Release
│ └──📂 net8.0
│ └──📂 publish
│ ├── DotNet.Docker.deps.json
│ ├── DotNet.Docker.exe
│ ├── DotNet.Docker.dll
│ ├── DotNet.Docker.pdb
│ └── DotNet.Docker.runtimeconfig.json
└──📁 obj
└──...
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
WORKDIR /App
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]
Feljegyzés
A rendszer szándékosan használja a ASP.NET Core futtatókörnyezeti rendszerképet, bár a mcr.microsoft.com/dotnet/runtime:7.0
rendszerképet használhatta volna.
Tipp.
Ez a Dockerfile többfázisú buildeket használ, amelyek a build rétegzésével optimalizálják a rendszerkép végső méretét, és csak a szükséges összetevőket hagyják meg. További információ: Docker Docs: többfázisú buildek.
A FROM
kulcsszóhoz teljes mértékben minősített Docker-tárolórendszerkép-név szükséges. A Microsoft Container Registry (MCR, mcr.microsoft.com) a Docker Hub szindikátusa, amely nyilvánosan elérhető tárolókat üzemeltet. A dotnet
szegmens a tárolóadattár, míg a sdk
szegmens aspnet
a tárolórendszerkép neve. A rendszerkép a verziószámozáshoz használt címkével 7.0
van megjelölve. mcr.microsoft.com/dotnet/aspnet:7.0
Így a .NET 7.0 futtatókörnyezet. Győződjön meg arról, hogy lekéri az SDK által megcélzott futtatókörnyezetnek megfelelő futtatókörnyezetet. Az előző szakaszban létrehozott alkalmazás például a .NET 7.0 SDK-t használta, és a Dockerfile-ban hivatkozott alaprendszerkép 7.0-s címkével van megjelölve.
Mentse a Dockerfile fájlt. A munkamappa könyvtárszerkezetének az alábbihoz hasonlóan kell kinéznie. Néhány mélyebb szintű fájl és mappa kimaradt, hogy helyet takarítson meg a cikkben:
📁 docker-working
└──📂 App
├── Dockerfile
├── DotNet.Docker.csproj
├── Program.cs
├──📂 bin
│ └──📂 Release
│ └──📂 net7.0
│ └──📂 publish
│ ├── DotNet.Docker.deps.json
│ ├── DotNet.Docker.exe
│ ├── DotNet.Docker.dll
│ ├── DotNet.Docker.pdb
│ └── DotNet.Docker.runtimeconfig.json
└──📁 obj
└──...
A terminálon futtassa a következő parancsot:
docker build -t counter-image -f Dockerfile .
A Docker a Docker-fájl minden sorát feldolgozni fogja. A .
parancs a docker build
rendszerkép buildkörnyezetét állítja be. A -f
kapcsoló a Dockerfile elérési útja. Ez a parancs létrehozza a rendszerképet, és létrehoz egy számlálókép nevű helyi adattárat, amely erre a képre mutat. A parancs befejeződése után futtassa docker images
a telepített képek listáját:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
counter-image latest 2f15637dc1f6 10 minutes ago 217MB
Az counter-image
adattár a kép neve. A latest
címke a kép azonosítására használt címke. Ez 2f15637dc1f6
a képazonosító. A 10 minutes ago
rendszerkép létrehozásának időpontja. A 217MB
kép mérete. A Dockerfile utolsó lépéseként hozzon létre egy tárolót a rendszerképből, futtassa az alkalmazást, másolja a közzétett alkalmazást a tárolóba, és határozza meg a belépési pontot.
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
counter-image latest 2f15637dc1f6 10 minutes ago 208MB
Az counter-image
adattár a kép neve. A latest
címke a kép azonosítására használt címke. Ez 2f15637dc1f6
a képazonosító. A 10 minutes ago
rendszerkép létrehozásának időpontja. A 208MB
kép mérete. A Dockerfile utolsó lépéseként hozzon létre egy tárolót a rendszerképből, futtassa az alkalmazást, másolja a közzétett alkalmazást a tárolóba, és határozza meg a belépési pontot.
FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]
A COPY
parancs arra utasítja a Dockert, hogy másolja a számítógép megadott mappáját a tároló egyik mappájába. Ebben a példában a közzétételi mappát a rendszer egy Alkalmazás/ki nevű mappába másolja a tárolóban.
A WORKDIR
parancs a tároló aktuális könyvtárát Alkalmazásra módosítja.
A következő parancs arra utasítja a Dockert, ENTRYPOINT
hogy konfigurálja a tárolót végrehajthatóként való futtatásra. A tároló indításakor a ENTRYPOINT
parancs fut. Ha ez a parancs véget ér, a tároló automatikusan leáll.
Tipp.
A .NET 8 előtt az írásvédettként való futtatásra konfigurált tárolók Failed to create CoreCLR, HRESULT: 0x8007000E
sikertelenek lehetnek. A probléma megoldásához adjon meg egy környezeti változót DOTNET_EnableDiagnostics
a következő módon 0
(a ENTRYPOINT
lépés előtt):
ENV DOTNET_EnableDiagnostics=0
A különböző .NET környezeti változókkal kapcsolatos további információkért lásd a .NET környezeti változókat.
Feljegyzés
A .NET 6 az előtagon DOTNET_
szabványosítja a .NET futásidejű viselkedést konfiguráló környezeti változók helyett COMPlus_
. Az COMPlus_
előtag azonban továbbra is működni fog. Ha a .NET-futtatókörnyezet egy korábbi verzióját használja, akkor is használja a COMPlus_
környezeti változók előtagját.
Tároló létrehozása
Most, hogy már rendelkezik az alkalmazást tartalmazó képpel, létrehozhat egy tárolót. Tárolót kétféleképpen hozhat létre. Először hozzon létre egy leállított új tárolót.
docker create --name core-counter counter-image
Ez a docker create
parancs létrehoz egy tárolót a számlálórendszerkép alapján. A parancs kimenete a létrehozott tároló tárolóazonosítóját jeleníti meg (a sajátjai eltérőek lesznek):
d0be06126f7db6dd1cee369d911262a353c9b7fb4829a0c11b4b2eb7b2d429cf
Az összes tároló listájának megtekintéséhez használja a docker ps -a
következő parancsot:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d0be06126f7d counter-image "dotnet DotNet.Docke…" 12 seconds ago Created core-counter
A tároló kezelése
A tároló egy adott névvel core-counter
lett létrehozva, a rendszer ezt a nevet használja a tároló kezeléséhez. Az alábbi példa a parancsot használja a docker start
tároló elindításához, majd a docker ps
parancs használatával csak a futó tárolókat jeleníti meg:
docker start core-counter
core-counter
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf01364df453 counter-image "dotnet DotNet.Docke…" 53 seconds ago Up 10 seconds core-counter
Hasonlóképpen, a docker stop
parancs leállítja a tárolót. Az alábbi példa a docker stop
parancs használatával állítja le a tárolót, majd a docker ps
parancs használatával megmutatja, hogy nincsenek tárolók:
docker stop core-counter
core-counter
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Csatlakozás tárolóba
A tároló futtatása után csatlakozhat hozzá a kimenet megtekintéséhez. Az és docker attach
a docker start
parancsokkal indítsa el a tárolót, és nézze meg a kimeneti streamet. Ebben a példában a Ctrl+C billentyűkombinációval leválasztható a futó tárolóról. Ez a billentyűleütés a tárolóban befejezi a folyamatot, hacsak nincs másként megadva, ami leállítja a tárolót. A --sig-proxy=false
paraméter biztosítja, hogy a Ctrl+C billentyűkombináció ne állítsa le a folyamatot a tárolóban.
Miután leválasztotta a tárolót, próbálkozzon újra annak ellenőrzéséhez, hogy még fut-e, és számol-e.
docker start core-counter
core-counter
docker attach --sig-proxy=false core-counter
Counter: 7
Counter: 8
Counter: 9
^C
docker attach --sig-proxy=false core-counter
Counter: 17
Counter: 18
Counter: 19
^C
Tároló törlése
Ebben a cikkben nem szeretné, hogy a tárolók ne tegyenek semmit. Törölje a korábban létrehozott tárolót. Ha a tároló fut, állítsa le.
docker stop core-counter
Az alábbi példa az összes tárolót felsorolja. Ezután a docker rm
parancs használatával törli a tárolót, majd másodszor ellenőrzi a futó tárolókat.
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f6424a7ddce counter-image "dotnet DotNet.Dock…" 7 minutes ago Exited (143) 20 seconds ago core-counter
docker rm core-counter
core-counter
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Egyszeri futtatás
A Docker a docker run
tároló egyetlen parancsként való létrehozásához és futtatásához biztosítja a parancsot. Ez a parancs szükségtelenné teszi a futtatás és a docker start
futtatás szükségességétdocker create
. Ezt a parancsot úgy is beállíthatja, hogy a tároló leállásakor automatikusan törölje a tárolót. Ha például docker run -it --rm
két dolgot szeretne elvégezni, először automatikusan használja az aktuális terminált a tárolóhoz való csatlakozáshoz, majd amikor a tároló befejeződik, távolítsa el:
docker run -it --rm counter-image
Counter: 1
Counter: 2
Counter: 3
Counter: 4
Counter: 5
^C
A tároló a paramétereket is átadja a .NET-alkalmazás végrehajtásához. Ha azt szeretné, hogy a .NET-alkalmazás csak háromra számoljon, adja meg a 3-at.
docker run -it --rm counter-image 3
Counter: 1
Counter: 2
Counter: 3
A docker run -it
Ctrl+C paranccsal leállítja a tárolóban futó folyamatot, amely viszont leállítja a tárolót. Mivel a --rm
paraméter meg lett adva, a tároló automatikusan törlődik a folyamat leállításakor. Ellenőrizze, hogy nem létezik-e:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
A ENTRYPOINT módosítása
A docker run
parancs emellett lehetővé teszi a ENTRYPOINT
parancs módosítását a Dockerfile-ból , és futtathat valami mást, de csak az adott tárolóra vonatkozóan. Futtassa vagy futtassa bash
cmd.exe
például a következő parancsot. Szükség szerint szerkessze a parancsot.
Ebben a példában ENTRYPOINT
a rendszer a következőre cmd.exe
módosul: . A Ctrl+C billentyűkombinációt lenyomva befejezi a folyamatot, és leállítja a tárolót.
docker run -it --rm --entrypoint "cmd.exe" counter-image
Microsoft Windows [Version 10.0.17763.379]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\>dir
Volume in drive C has no label.
Volume Serial Number is 3005-1E84
Directory of C:\
04/09/2019 08:46 AM <DIR> app
03/07/2019 10:25 AM 5,510 License.txt
04/02/2019 01:35 PM <DIR> Program Files
04/09/2019 01:06 PM <DIR> Users
04/02/2019 01:35 PM <DIR> Windows
1 File(s) 5,510 bytes
4 Dir(s) 21,246,517,248 bytes free
C:\>^C
Alapvető parancsok
A Docker számos különböző parancsot tartalmaz, amelyek tárolókat és lemezképeket hoznak létre, kezelnek és kezelnek. Ezek a Docker-parancsok nélkülözhetetlenek a tárolók kezeléséhez:
Az erőforrások eltávolítása
Ebben az oktatóanyagban tárolókat és lemezképeket hozott létre. Ha szeretné, törölje ezeket az erőforrásokat. Az alábbi parancsokkal
Az összes tároló listázása
docker ps -a
Állítsa le a nevük alapján futó tárolókat.
docker stop core-counter
A tároló törlése
docker rm core-counter
Ezután törölje azokat a képeket, amelyeket már nem szeretne a gépén. Törölje a Dockerfile által létrehozott képet, majd törölje azt a .NET-lemezképet, amelyen a Dockerfile alapult. Használhatja a KÉPazonosítót vagy a REPOSITORY:TAG formázott sztringet.
docker rmi counter-image:latest
docker rmi mcr.microsoft.com/dotnet/aspnet:8.0
docker rmi counter-image:latest
docker rmi mcr.microsoft.com/dotnet/aspnet:7.0
docker images
A parancs használatával megtekintheti a telepített képek listáját.
Tipp.
A képfájlok nagy méretűek lehetnek. Általában eltávolítaná az alkalmazás tesztelése és fejlesztése során létrehozott ideiglenes tárolókat. Az alaprendszerképeket általában a futtatókörnyezettel együtt kell tárolnia, ha az adott futtatókörnyezet alapján más rendszerképeket szeretne készíteni.
Következő lépések
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: