Tutorial: Mengontainerisasi aplikasi .NET
Dalam tutorial ini, Anda akan mempelajari cara membuat kontainer aplikasi .NET dengan Docker. Kontainer memiliki banyak fitur dan manfaat, seperti menjadi infrastruktur yang tidak dapat diubah, menyediakan arsitektur portabel, dan memungkinkan skalabilitas. Gambar dapat digunakan untuk membuat kontainer untuk lingkungan pengembangan lokal, cloud privat, atau cloud publik Anda.
Di tutorial ini, Anda akan:
- Membuat dan menerbitkan aplikasi .NET sederhana
- Membuat dan mengonfigurasi Dockerfile untuk .NET
- Membuat citra Docker
- Membuat dan menjalankan kontainer Docker
Anda akan memahami build kontainer Docker dan menyebarkan tugas untuk aplikasi .NET. Platform Docker menggunakan mesin Docker untuk membuat dan mengemas aplikasi dengan cepat sebagai gambar Docker. Gambar-gambar ini ditulis dalam format Dockerfile untuk disebarkan dan dijalankan dalam kontainer berlapis.
Catatan
Tutorial ini bukan untuk aplikasi ASP.NET Core. Jika Anda menggunakan ASP.NET Core, lihat tutorial Pelajari cara membuat kontainer aplikasi ASP.NET Core.
Prasyarat
Instal prasyarat berikut:
- .NET 8+ SDK
Jika Anda telah menginstal .NET, gunakandotnet --info
perintah untuk menentukan SDK mana yang Anda gunakan. - Docker Community Edition
- Folder kerja sementara untuk aplikasi contoh Dockerfile dan .NET. Dalam tutorial ini, nama docker-working digunakan sebagai folder kerja.
- .NET 7+ SDK
Jika Anda telah menginstal .NET, gunakandotnet --info
perintah untuk menentukan SDK mana yang Anda gunakan. - Docker Community Edition
- Folder kerja sementara untuk aplikasi contoh Dockerfile dan .NET. Dalam tutorial ini, nama docker-working digunakan sebagai folder kerja.
Membuat aplikasi .NET
Anda memerlukan aplikasi .NET yang dijalankan kontainer Docker. Buka terminal Anda, buat folder yang berfungsi jika Anda belum melakukannya, dan masukkan. Di folder kerja, jalankan perintah berikut untuk membuat proyek baru di subdirektori bernama Aplikasi:
dotnet new console -o App -n DotNet.Docker
Pohon folder Anda terlihat seperti berikut ini:
π 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
Perintah dotnet new
membuat folder baru bernama App dan menghasilkan aplikasi konsol "Halo Dunia". Ubah direktori dan navigasikan ke folder Aplikasi , dari sesi terminal Anda. dotnet run
Gunakan perintah untuk memulai aplikasi. Aplikasi berjalan, dan mencetak Hello World!
di bawah perintah:
cd App
dotnet run
Hello World!
Templat default membuat aplikasi yang mencetak ke terminal dan kemudian segera berakhir. Untuk tutorial ini, Anda menggunakan aplikasi yang mengulang tanpa batas waktu. Di editor teks, buka file Program.cs.
Tip
Jika Anda menggunakan Visual Studio Code, dari sesi terminal sebelumnya ketik perintah berikut:
code .
Ini akan membuka folder Aplikasi yang berisi proyek di Visual Studio Code.
Program.cs akan terlihat seperti kode C# berikut:
Console.WriteLine("Hello World!");
Ganti file dengan kode berikut yang menghitung angka setiap detik:
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));
}
Simpan file dan uji program lagi dengan dotnet run
. Ingatlah bahwa aplikasi ini berjalan tanpa batas waktu. Gunakan perintah batalkan Ctrl+C untuk menghentikannya. Berikut ini adalah contoh output:
dotnet run
Counter: 1
Counter: 2
Counter: 3
Counter: 4
^C
Jika Anda meneruskan angka pada baris perintah ke aplikasi, angka tersebut hanya akan dihitung hingga jumlah tersebut lalu keluar. Cobalah dengan dotnet run -- 5
menghitung sampai lima.
Penting
Parameter apa pun setelahnya --
tidak diteruskan ke dotnet run
perintah dan sebaliknya diteruskan ke aplikasi Anda.
Menerbitkan aplikasi .NET
Sebelum menambahkan aplikasi .NET ke gambar Docker, pertama-tama aplikasi harus diterbitkan. Sebaiknya kontainer menjalankan versi aplikasi yang diterbitkan. Untuk menerbitkan aplikasi, jalankan perintah berikut:
dotnet publish -c Release
Perintah ini mengkompilasi aplikasi Anda ke folder terbitkan. Jalur ke folder terbitkan dari folder yang berfungsi harus .\App\bin\Release\net8.0\publish\
.
Perintah ini mengkompilasi aplikasi Anda ke folder terbitkan. Jalur ke folder terbitkan dari folder yang berfungsi harus .\App\bin\Release\net7.0\publish\
.
Dari folder Aplikasi , dapatkan daftar direktori folder terbitkan untuk memverifikasi bahwa file DotNet.Docker.dll telah dibuat.
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
Membuat Dockerfile
File Dockerfile digunakan oleh docker build
perintah untuk membuat gambar kontainer. File ini adalah file teks bernama Dockerfile yang tidak memiliki ekstensi.
Buat file bernama Dockerfile di direktori yang berisi .csproj dan buka di editor teks. Tutorial ini menggunakan gambar runtime ASP.NET Core (yang berisi gambar runtime .NET) dan sesuai dengan aplikasi konsol .NET.
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"]
Catatan
Gambar runtime ASP.NET Core sengaja digunakan di sini, meskipun mcr.microsoft.com/dotnet/runtime:8.0
gambar dapat digunakan.
Tip
Dockerfile ini menggunakan build multi-tahap, yang mengoptimalkan ukuran akhir gambar dengan melapisi build dan hanya menyisakan artefak yang diperlukan. Untuk informasi selengkapnya, lihat Docker Docs: build multi-tahap.
Kata FROM
kunci memerlukan nama gambar kontainer Docker yang sepenuhnya memenuhi syarat. Microsoft Container Registry (MCR, mcr.microsoft.com) adalah sindikat Docker Hub, yang menghosting kontainer yang dapat diakses publik. Segmen adalah dotnet
repositori kontainer, sedangkan sdk
segmen atau aspnet
adalah nama gambar kontainer. Gambar ditandai dengan 8.0
, yang digunakan untuk penerapan versi. Dengan demikian, mcr.microsoft.com/dotnet/aspnet:8.0
adalah runtime .NET 8.0. Pastikan Anda menarik versi runtime yang cocok dengan runtime yang ditargetkan oleh SDK Anda. Misalnya, aplikasi yang dibuat di bagian sebelumnya menggunakan .NET 8.0 SDK, dan gambar dasar yang dimaksud dalam Dockerfile ditandai dengan 8.0.
Penting
Saat menggunakan gambar kontainer berbasis Windows, Anda perlu menentukan tag gambar di luar hanya 8.0
, misalnya, mcr.microsoft.com/dotnet/aspnet:8.0-nanoserver-1809
alih-alih mcr.microsoft.com/dotnet/aspnet:8.0
. Pilih nama gambar berdasarkan apakah Anda menggunakan Nano Server atau Windows Server Core dan versi OS tersebut. Anda dapat menemukan daftar lengkap semua tag yang didukung di . Halaman Docker Hub NET.
Simpan file Dockerfile. Struktur direktori folder kerja akan terlihat seperti berikut ini. Beberapa file dan folder tingkat yang lebih dalam telah dihilangkan untuk menghemat ruang dalam artikel:
π 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"]
Catatan
Gambar runtime ASP.NET Core sengaja digunakan di sini, meskipun mcr.microsoft.com/dotnet/runtime:7.0
gambar dapat digunakan.
Tip
Dockerfile ini menggunakan build multi-tahap, yang mengoptimalkan ukuran akhir gambar dengan melapisi build dan hanya menyisakan artefak yang diperlukan. Untuk informasi selengkapnya, lihat Docker Docs: build multi-tahap.
Kata FROM
kunci memerlukan nama gambar kontainer Docker yang sepenuhnya memenuhi syarat. Microsoft Container Registry (MCR, mcr.microsoft.com) adalah sindikat Docker Hubβyang menghosting kontainer yang dapat diakses publik. Segmen adalah dotnet
repositori kontainer, sedangkan sdk
segmen atau aspnet
adalah nama gambar kontainer. Gambar ditandai dengan 7.0
, yang digunakan untuk penerapan versi. Dengan demikian, mcr.microsoft.com/dotnet/aspnet:7.0
adalah runtime .NET 7.0. Pastikan Anda menarik versi runtime yang cocok dengan runtime yang ditargetkan oleh SDK Anda. Misalnya, aplikasi yang dibuat di bagian sebelumnya menggunakan .NET 7.0 SDK dan gambar dasar yang dimaksud di Dockerfile ditandai dengan 7.0.
Simpan file Dockerfile. Struktur direktori folder kerja akan terlihat seperti berikut ini. Beberapa file dan folder tingkat yang lebih dalam telah dihilangkan untuk menghemat ruang dalam artikel:
π 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
βββ...
Dari terminal Anda, jalankan perintah berikut:
docker build -t counter-image -f Dockerfile .
Docker akan memproses setiap baris di Dockerfile. .
Dalam docker build
perintah mengatur konteks build gambar. Sakelar -f
adalah jalur ke Dockerfile. Perintah ini membangun gambar dan membuat repositori lokal bernama counter-image yang menunjuk ke gambar tersebut. Setelah perintah ini selesai, jalankan docker images
untuk melihat daftar gambar yang diinstal:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
counter-image latest 2f15637dc1f6 10 minutes ago 217MB
counter-image
Repositori adalah nama gambar. Tag latest
adalah tag yang digunakan untuk mengidentifikasi gambar. 2f15637dc1f6
adalah ID gambar. 10 minutes ago
adalah waktu gambar dibuat. 217MB
adalah ukuran gambar. Langkah-langkah akhir Dockerfile adalah membuat kontainer dari gambar dan menjalankan aplikasi, menyalin aplikasi yang diterbitkan ke kontainer, dan menentukan titik masuk.
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
counter-image
Repositori adalah nama gambar. Tag latest
adalah tag yang digunakan untuk mengidentifikasi gambar. 2f15637dc1f6
adalah ID gambar. 10 minutes ago
adalah waktu gambar dibuat. 208MB
adalah ukuran gambar. Langkah-langkah akhir Dockerfile adalah membuat kontainer dari gambar dan menjalankan aplikasi, menyalin aplikasi yang diterbitkan ke kontainer, dan menentukan titik masuk.
FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]
Perintah COPY
memberi tahu Docker untuk menyalin folder yang ditentukan di komputer Anda ke folder dalam kontainer. Dalam contoh ini, folder terbitkan disalin ke folder bernama App/out dalam kontainer.
Perintah WORKDIR
mengubah direktori saat ini di dalam kontainer menjadi Aplikasi.
Perintah berikutnya, ENTRYPOINT
, memberi tahu Docker untuk mengonfigurasi kontainer agar berjalan sebagai yang dapat dieksekusi. Saat kontainer dimulai, ENTRYPOINT
perintah berjalan. Ketika perintah ini berakhir, kontainer akan secara otomatis berhenti.
Tip
Sebelum .NET 8, kontainer yang dikonfigurasi untuk berjalan karena baca-saja mungkin gagal dengan Failed to create CoreCLR, HRESULT: 0x8007000E
. Untuk mengatasi masalah ini, tentukan DOTNET_EnableDiagnostics
variabel lingkungan sebagai 0
(tepat sebelum ENTRYPOINT
langkah):
ENV DOTNET_EnableDiagnostics=0
Untuk informasi selengkapnya tentang berbagai variabel lingkungan .NET, lihat variabel lingkungan .NET.
Catatan
.NET 6 menstandarkan pada prefiks DOTNET_
daripada COMPlus_
untuk variabel lingkungan yang mengonfigurasi perilaku run-time .NET. Namun, prefiks COMPlus_
akan terus berfungsi. Jika Anda menggunakan versi runtime .NET sebelumnya, Anda masih harus menggunakan prefiks COMPlus_
untuk variabel lingkungan.
Membuat kontainer
Setelah memiliki gambar yang berisi aplikasi, Anda dapat membuat kontainer. Anda dapat membuat kontainer dengan dua cara. Pertama, buat kontainer baru yang dihentikan.
docker create --name core-counter counter-image
Perintah ini docker create
membuat kontainer berdasarkan gambar penghitung. Output perintah tersebut menunjukkan ID KONTAINER (ID Anda akan berbeda) dari kontainer yang dibuat:
d0be06126f7db6dd1cee369d911262a353c9b7fb4829a0c11b4b2eb7b2d429cf
Untuk melihat daftar semua kontainer, gunakan docker ps -a
perintah :
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d0be06126f7d counter-image "dotnet DotNet.Dockeβ¦" 12 seconds ago Created core-counter
Mengelola kontainer
Kontainer dibuat dengan nama core-counter
tertentu , nama ini digunakan untuk mengelola kontainer. Contoh berikut menggunakan docker start
perintah untuk memulai kontainer, lalu menggunakan docker ps
perintah untuk hanya menampilkan kontainer yang sedang berjalan:
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
Demikian pula, docker stop
perintah menghentikan kontainer. Contoh berikut menggunakan docker stop
perintah untuk menghentikan kontainer, lalu menggunakan docker ps
perintah untuk menunjukkan bahwa tidak ada kontainer yang berjalan:
docker stop core-counter
core-counter
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Menyambungkan ke kontainer
Setelah kontainer berjalan, Anda dapat menyambungkannya untuk melihat output. docker start
Gunakan perintah dan docker attach
untuk memulai kontainer dan mengintip aliran output. Dalam contoh ini, penekanan tombol Ctrl+C digunakan untuk melepaskan dari kontainer yang sedang berjalan. Penekanan kunci ini mengakhiri proses dalam kontainer kecuali ditentukan lain, yang akan menghentikan kontainer. Parameter --sig-proxy=false
memastikan bahwa Ctrl+C tidak akan menghentikan proses dalam kontainer.
Setelah Anda melepaskan dari kontainer, lampirkan kembali untuk memverifikasi bahwa kontainer masih berjalan dan dihitung.
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
Menghapus kontainer
Untuk artikel ini, Anda tidak ingin kontainer berkeliaran di sekitar yang tidak melakukan apa pun. Hapus kontainer yang sebelumnya Anda buat. Jika kontainer berjalan, hentikan.
docker stop core-counter
Contoh berikut mencantumkan semua kontainer. Kemudian menggunakan docker rm
perintah untuk menghapus kontainer dan kemudian memeriksa kedua kalinya untuk setiap kontainer yang sedang berjalan.
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
Eksekusi tunggal
Docker menyediakan docker run
perintah untuk membuat dan menjalankan kontainer sebagai satu perintah. Perintah ini menghilangkan kebutuhan untuk menjalankan docker create
lalu docker start
. Anda juga dapat mengatur perintah ini untuk menghapus kontainer secara otomatis saat kontainer berhenti. Misalnya, gunakan docker run -it --rm
untuk melakukan dua hal, pertama, secara otomatis menggunakan terminal saat ini untuk menyambungkan ke kontainer, dan kemudian ketika kontainer selesai, hapus:
docker run -it --rm counter-image
Counter: 1
Counter: 2
Counter: 3
Counter: 4
Counter: 5
^C
Kontainer juga meneruskan parameter ke dalam eksekusi aplikasi .NET. Untuk menginstruksikan aplikasi .NET untuk menghitung hanya hingga tiga, teruskan dalam 3.
docker run -it --rm counter-image 3
Counter: 1
Counter: 2
Counter: 3
Dengan docker run -it
, perintah Ctrl+C menghentikan proses yang berjalan dalam kontainer, yang pada gilirannya, menghentikan kontainer. --rm
Karena parameter disediakan, kontainer secara otomatis dihapus ketika proses dihentikan. Verifikasi bahwa itu tidak ada:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Mengubah ENTRYPOINT
Perintah ini docker run
juga memungkinkan Anda memodifikasi ENTRYPOINT
perintah dari Dockerfile dan menjalankan sesuatu yang lain, tetapi hanya untuk kontainer tersebut. Misalnya, gunakan perintah berikut untuk menjalankan bash
atau cmd.exe
. Edit perintah seperlunya.
Dalam contoh ini, ENTRYPOINT
diubah menjadi cmd.exe
. Ctrl+C ditekan untuk mengakhiri proses dan menghentikan kontainer.
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
Perintah penting
Docker memiliki banyak perintah berbeda yang membuat, mengelola, dan berinteraksi dengan kontainer dan gambar. Perintah Docker ini sangat penting untuk mengelola kontainer Anda:
Membersihkan sumber daya
Selama tutorial ini, Anda membuat kontainer dan gambar. Jika mau, hapus sumber daya ini. Gunakan perintah berikut untuk
Mencantumkan semua kontainer
docker ps -a
Hentikan kontainer yang berjalan dengan namanya.
docker stop core-counter
Menghapus kontainer
docker rm core-counter
Selanjutnya, hapus gambar apa pun yang tidak lagi Anda inginkan di komputer Anda. Hapus gambar yang dibuat oleh Dockerfile Anda lalu hapus gambar .NET yang menjadi dasar Dockerfile. Anda dapat menggunakan ID GAMBAR atau string berformat REPOSITORY:TAG.
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
Gunakan perintah untuk melihat daftar gambar yang terinstal.
Tip
File gambar bisa besar. Biasanya, Anda akan menghapus kontainer sementara yang Anda buat saat menguji dan mengembangkan aplikasi Anda. Anda biasanya menyimpan gambar dasar dengan runtime yang diinstal jika Anda berencana membangun gambar lain berdasarkan runtime tersebut.