Tutorial: Membuat aplikasi multi-kontainer dengan Docker Compose
Dalam tutorial ini, Anda mempelajari cara mengelola lebih dari satu kontainer dan berkomunikasi di antara mereka saat menggunakan Alat Kontainer di Visual Studio. Mengelola beberapa container memerlukan orkestrasi container dan memerlukan orkestra seperti Docker Compose atau Service Fabric. Untuk prosedur ini, Anda menggunakan Docker Compose. Docker Compose sangat bagus untuk penelusuran kesalahan dan pengujian lokal selama siklus pengembangan.
Sampel lengkap yang Anda buat dalam tutorial ini dapat ditemukan di GitHub di https://github.com/MicrosoftDocs/vs-tutorial-samples di folder docker/ComposeSample.
Prasyarat
- Desktop Docker
- Visual Studio 2019 dengan beban kerja Pengembangan Web, Alat Azure, dan/atau pengembangan lintas platform .NET yang diinstal
- Desktop Docker
- Visual Studio 2022 dengan beban kerja Pengembangan Web, Alat Azure, dan/atau pengembangan lintas platform .NET yang diinstal. Penginstalan ini mencakup alat pengembangan .NET 8.
Membuat proyek Aplikasi Web
Di Visual Studio, buat proyek Aplikasi Web ASP.NET Core, bernama WebFrontEnd
, untuk membuat aplikasi web dengan halaman Razor.
Jangan pilih Aktifkan Dukungan Docker. Anda menambahkan dukungan Docker nanti dalam prosesnya.
Catatan
Di Visual Studio 2022 17.2 dan yang lebih baru, Anda dapat menggunakan Fungsi Azure untuk proyek ini.
Jangan pilih Aktifkan Dukungan Docker. Anda menambahkan dukungan Docker nanti dalam prosesnya.
Membuat proyek API Web
Tambahkan proyek ke solusi yang sama dan beri nama MyWebAPI. Pilih API sebagai jenis proyek, dan kosongkan kotak centang untuk Konfigurasi untuk HTTPS. Dalam desain ini, kami hanya menggunakan SSL untuk komunikasi dengan klien, bukan untuk komunikasi antar kontainer dalam aplikasi web yang sama. Hanya WebFrontEnd
perlu HTTPS dan kode dalam contoh mengasumsikan bahwa Anda telah menghapus kotak centang tersebut. Secara umum, sertifikat pengembang .NET yang digunakan oleh Visual Studio hanya didukung untuk permintaan eksternal ke kontainer, bukan untuk permintaan kontainer ke kontainer.
Tambahkan proyek ke solusi yang sama dan beri nama WebAPI . Pilih API sebagai jenis proyek, dan kosongkan kotak centang untuk Konfigurasi untuk HTTPS. Dalam desain ini, kami hanya menggunakan SSL untuk komunikasi dengan klien, bukan untuk komunikasi antar kontainer dalam aplikasi web yang sama. Hanya
WebFrontEnd
perlu HTTPS dan kode dalam contoh mengasumsikan bahwa Anda telah menghapus kotak centang tersebut. Secara umum, sertifikat pengembang .NET yang digunakan oleh Visual Studio hanya didukung untuk permintaan eksternal ke kontainer, bukan untuk permintaan kontainer ke kontainer.Tambahkan dukungan untuk Redis Cache. Tambahkan paket NuGet
Microsoft.Extensions.Caching.StackExchangeRedis
(bukanStackExchange.Redis
). Di Program.cs , tambahkan baris berikut, tepat sebelumvar app = builder.Build()
:builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = "redis:6379"; // redis is the container name of the redis service. 6379 is the default port options.InstanceName = "SampleInstance"; });
Tambahkan menggunakan arahan di Program.cs untuk
Microsoft.Extensions.Caching.Distributed
danMicrosoft.Extensions.Caching.StackExchangeRedis
.using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.StackExchangeRedis;
Dalam proyek Web API, hapus WeatherForecast.cs dan Controllers/WeatherForecastController.cs yang ada, dan tambahkan file di bawah Controllers, CounterController.cs , dengan konten berikut:
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Distributed; using StackExchange.Redis; namespace WebApi.Controllers { [ApiController] [Route("[controller]")] public class CounterController : ControllerBase { private readonly ILogger<CounterController> _logger; private readonly IDistributedCache _cache; public CounterController(ILogger<CounterController> logger, IDistributedCache cache) { _logger = logger; _cache = cache; } [HttpGet(Name = "GetCounter")] public string Get() { string key = "Counter"; string? result = null; try { var counterStr = _cache.GetString(key); if (int.TryParse(counterStr, out int counter)) { counter++; } else { counter = 0; } result = counter.ToString(); _cache.SetString(key, result); } catch(RedisConnectionException) { result = "Redis cache is not found."; } return result; } } }
Layanan menambah penghitung setiap kali halaman diakses dan menyimpan penghitung dalam cache Redis.
Menambahkan kode untuk memanggil API Web
Dalam proyek
WebFrontEnd
, buka file Index.cshtml.cs, dan ganti metodeOnGet
dengan kode berikut.public async Task OnGet() { ViewData["Message"] = "Hello from webfrontend"; using (var client = new System.Net.Http.HttpClient()) { // Call *mywebapi*, and display its response in the page var request = new System.Net.Http.HttpRequestMessage(); request.RequestUri = new Uri("http://mywebapi/WeatherForecast"); // request.RequestUri = new Uri("http://mywebapi/api/values/1"); // For ASP.NET 2.x, comment out previous line and uncomment this line. var response = await client.SendAsync(request); ViewData["Message"] += " and " + await response.Content.ReadAsStringAsync(); } }
Catatan
Dalam kode dunia nyata, Anda tidak boleh membuang
HttpClient
setelah setiap permintaan. Untuk praktik terbaik, lihat Menggunakan HttpClientFactory untuk menerapkan permintaan HTTP yang tangguh.Dalam file Index.cshtml, tambahkan baris untuk ditampilkan
ViewData["Message"]
sehingga file terlihat seperti kode berikut:@page @model IndexModel @{ ViewData["Title"] = "Home page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Learn about <a href="/aspnet/core">building Web apps with ASP.NET Core</a>.</p> <p>@ViewData["Message"]</p> </div>
(ASP.NET 2.x saja) Sekarang di proyek API Web, tambahkan kode ke pengontrol Nilai untuk menyesuaikan pesan yang dikembalikan oleh API untuk panggilan yang Anda tambahkan dari webfrontend.
// GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { return "webapi (with value " + id + ")"; }
Catatan
Di .NET Core 3.1 dan yang lebih baru, Anda dapat menggunakan API WeatherForecast yang disediakan daripada kode tambahan ini. Namun, Anda perlu mengomentari panggilan ke UseHttpsRedirection dalam proyek API Web karena kode menggunakan HTTP untuk melakukan panggilan daripada HTTPS.
//app.UseHttpsRedirection();
Tambahkan dukungan Docker Compose
Dalam proyek
WebFrontEnd
, pilih Tambahkan > Dukungan Orkestrator Kontainer. Dialog Opsi Dukungan Docker muncul.Pilih Docker Compose.
Pilih OS Target Anda, misalnya, Linux.
Visual Studio membuat file docker-compose.yml dan file .dockerignore di node docker-compose dalam solusi, dan proyek tersebut ditampilkan dalam huruf tebal, yang menunjukkan bahwa ini adalah proyek startup.
docker-compose.yml muncul sebagai berikut:
version: '3.4' services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile
Yang
version
ditentukan di baris pertama adalah versi file Docker Compose. Anda biasanya tidak boleh mengubahnya, karena digunakan oleh alat untuk memahami cara menginterpretasikan file.File .dockerignore berisi jenis file dan ekstensi yang tidak perlu disertakan Docker dalam kontainer. File ini umumnya dikaitkan dengan lingkungan pengembangan dan kontrol sumber, bukan bagian dari aplikasi atau layanan yang Anda kembangkan.
Lihat bagian Alat Kontainer pada panel keluaran untuk detail perintah yang dijalankan. Anda dapat melihat alat baris perintah docker-compose digunakan untuk mengonfigurasi dan membuat kontainer runtime.
Dalam proyek API Web, klik kanan lagi pada node proyek, dan pilih Tambahkan>Dukungan Orkestrator Kontainer. Pilih Docker Compose, lalu pilih OS target yang sama.
Catatan
Pada langkah ini, Visual Studio akan menawarkan untuk membuat Dockerfile. Jika Anda melakukan ini pada proyek yang sudah memiliki dukungan Docker, Anda akan ditanya apakah ingin menimpa file Docker yang ada. Jika Anda telah membuat perubahan di Dockerfile yang ingin Anda simpan, pilih tidak.
Visual Studio membuat beberapa perubahan pada file YML docker compose Anda. Sekarang kedua layanan disertakan.
version: '3.4' services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi build: context: . dockerfile: MyWebAPI/Dockerfile
Proyek pertama tempat Anda menambahkan orkestrasi penampung diatur untuk diluncurkan saat Anda menjalankan atau men-debug. Anda dapat mengonfigurasi tindakan peluncuran di Properti Proyek untuk proyek docker-compose. Pada node proyek docker-compose, klik kanan untuk membuka menu konteks, lalu pilih Properti, atau gunakan Alt+Enter. Cuplikan layar berikut menunjukkan properti yang Anda inginkan untuk solusi yang digunakan di sini. Misalnya, Anda dapat mengubah halaman yang dimuat dengan menyesuaikan properti URL Layanan.
Inilah yang Anda lihat saat diluncurkan (versi .NET Core 2.x):
Aplikasi web untuk .NET 3.1 menampilkan data cuaca dalam format JSON.
Sekarang misalkan Anda hanya tertarik untuk memiliki debugger yang dilampirkan ke WebFrontEnd, bukan proyek API Web. Dari bilah menu, Anda dapat menggunakan menu dropdown di sebelah tombol mulai untuk membuka menu opsi debug; pilih Mengelola Pengaturan Peluncuran Tulis Docker.
Mengelola Pengaturan Peluncuran Tulis Docker muncul. Dengan dialog ini, Anda dapat mengontrol subset layanan mana yang diluncurkan selama sesi debugging, yang diluncurkan dengan atau tanpa debugger terpasang, dan layanan peluncuran dan URL. Lihat Memulai subset layanan Compose.
Pilih Baru untuk membuat profil baru, dan beri nama
Debug WebFrontEnd only
. Kemudian, atur proyek API Web ke Mulai tanpa penelusuran kesalahan, biarkan proyek WebFrontEnd diatur untuk memulai dengan penelusuran kesalahan, dan pilih Simpan.Konfigurasi baru dipilih sebagai default untuk F5 berikutnya.
Tekan F5 untuk mengonfirmasi bahwa ini berfungsi seperti yang Anda harapkan.
Selamat, Anda menjalankan aplikasi Docker Compose dengan profil Docker Compose kustom.
Dalam proyek
WebFrontEnd
, buka file Index.cshtml.cs, dan ganti metodeOnGet
dengan kode berikut.public async Task OnGet() { using (var client = new System.Net.Http.HttpClient()) { // Call *mywebapi*, and display its response in the page var request = new System.Net.Http.HttpRequestMessage(); // webapi is the container name request.RequestUri = new Uri("http://webapi/Counter"); var response = await client.SendAsync(request); string counter = await response.Content.ReadAsStringAsync(); ViewData["Message"] = $"Counter value from cache :{counter}"; } }
Catatan
Dalam kode dunia nyata, Anda tidak boleh membuang
HttpClient
setelah setiap permintaan. Untuk praktik terbaik, lihat Menggunakan HttpClientFactory untuk menerapkan permintaan HTTP yang tangguh.Dalam file Index.cshtml, tambahkan baris untuk ditampilkan
ViewData["Message"]
sehingga file terlihat seperti kode berikut:@page @model IndexModel @{ ViewData["Title"] = "Home page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Learn about <a href="/aspnet/core">building Web apps with ASP.NET Core</a>.</p> <p>@ViewData["Message"]</p> </div>
Kode ini menampilkan nilai penghitung yang dikembalikan dari proyek API Web.
Tambahkan dukungan Docker Compose
Dalam proyek
WebFrontEnd
, pilih Tambahkan > Dukungan Orkestrator Kontainer. Dialog Opsi Dukungan Docker muncul.Pilih Docker Compose.
Pilih OS Target Anda, misalnya, Linux.
Visual Studio membuat file docker-compose.yml dan file .dockerignore di node docker-compose dalam solusi, dan proyek tersebut ditampilkan dalam huruf tebal, yang menunjukkan bahwa ini adalah proyek startup.
docker-compose.yml muncul sebagai berikut:
version: '3.4' services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile
Yang
version
ditentukan di baris pertama adalah versi file Docker Compose. Anda biasanya tidak boleh mengubahnya, karena digunakan oleh alat untuk memahami cara menginterpretasikan file.File .dockerignore berisi jenis file dan ekstensi yang tidak perlu disertakan Docker dalam kontainer. File ini umumnya dikaitkan dengan lingkungan pengembangan dan kontrol sumber, bukan bagian dari aplikasi atau layanan yang Anda kembangkan.
Lihat bagian Alat Kontainer pada panel keluaran untuk detail perintah yang dijalankan. Anda dapat melihat alat baris perintah docker-compose digunakan untuk mengonfigurasi dan membuat kontainer runtime.
Dalam proyek API Web, klik kanan lagi pada node proyek, dan pilih Tambahkan>Dukungan Orkestrator Kontainer. Pilih Docker Compose, lalu pilih OS target yang sama.
Catatan
Pada langkah ini, Visual Studio akan menawarkan untuk membuat Dockerfile. Jika Anda melakukan ini pada proyek yang sudah memiliki dukungan Docker, Anda akan ditanya apakah ingin menimpa file Docker yang ada. Jika Anda telah membuat perubahan di Dockerfile yang ingin Anda simpan, pilih tidak.
Visual Studio membuat beberapa perubahan pada file YML docker compose Anda. Sekarang kedua layanan disertakan.
version: '3.4' services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi build: context: . dockerfile: MyWebAPI/Dockerfile
Tambahkan cache Redis ke file
docker.compose.yml
:redis: image: redis
Pastikan lekukan berada pada level yang sama dengan dua layanan lainnya.
Proyek pertama tempat Anda menambahkan orkestrasi penampung diatur untuk diluncurkan saat Anda menjalankan atau men-debug. Anda dapat mengonfigurasi tindakan peluncuran di Properti Proyek untuk proyek docker-compose. Pada node proyek docker-compose, klik kanan untuk membuka menu konteks, lalu pilih Properti, atau gunakan Alt+Enter. Misalnya, Anda dapat mengubah halaman yang dimuat dengan menyesuaikan properti URL Layanan.
Tekan F5. Inilah yang Anda lihat saat diluncurkan:
Anda dapat memantau kontainer menggunakan jendela Kontainer . Jika Anda tidak melihat jendela, gunakan kotak pencarian, tekan Ctrl+K, Ctrl+O, atau tekan Ctrl+Q. Di bawah Pencarian fitur, cari
containers
, dan pilih Tampilkan>Kontainer Windows>Lainnya dari daftar.Perluas simpul Kontainer Solusi, dan pilih simpul untuk proyek Docker Compose Anda untuk melihat log gabungan di tab Log di jendela ini.
Anda juga dapat memilih simpul untuk kontainer individual untuk melihat log, variabel lingkungan, sistem file, dan detail lainnya.
Siapkan profil peluncuran
Solusi ini memiliki Redis Cache, tetapi tidak efisien untuk membangun kembali wadah cache Redis setiap kali Anda memulai sesi debugging. Untuk menghindari situasi tersebut, Anda dapat menyiapkan beberapa profil peluncuran. Buat satu profil untuk memulai cache Redis. Buat profil kedua untuk memulai layanan lain. Profil kedua dapat menggunakan kontainer cache Redis yang sudah berjalan. Dari bilah menu, Anda dapat menggunakan menu dropdown di samping tombol mulai untuk membuka menu dengan opsi penelusuran kesalahan. Pilih Kelola Peluncuran Docker Compose Pengaturan.
Mengelola Pengaturan Peluncuran Tulis Docker muncul. Dengan dialog ini, Anda dapat mengontrol subset layanan mana yang diluncurkan selama sesi debugging, yang diluncurkan dengan atau tanpa debugger terpasang, dan layanan peluncuran dan URL. Lihat Memulai subset layanan Compose.
Pilih Baru untuk membuat profil baru, dan beri nama
Start Redis
. Kemudian, setel wadah Redis ke Mulai tanpa debug , biarkan set lainnya ke Jangan mulai , dan pilih Simpan .Kemudian buat profil lain
Start My Services
yang tidak memulai Redis, tetapi memulai dua layanan lainnya.(Opsional) Buat profil ketiga
Start All
untuk memulai semuanya. Anda dapat memilih Mulai tanpa men-debug untuk Redis.Pilih Mulai Redis dari daftar tarik-turun di bilah alat utama Visual Studio, tekan F5 . Wadah Redis dibuat dan dimulai. Anda dapat menggunakan jendela Containers untuk melihat bahwa itu sedang berjalan. Selanjutnya, pilih Mulai Layanan Saya dari daftar tarik-turun dan tekan F5 untuk meluncurkannya. Sekarang Anda dapat menjaga wadah cache Redis tetap berjalan di banyak sesi debug berikutnya. Setiap kali Anda menggunakan Mulai Layanan Saya, layanan tersebut menggunakan kontainer cache Redis yang sama.
Selamat, Anda menjalankan aplikasi Docker Compose dengan profil Docker Compose kustom.
Langkah berikutnya
Lihat opsi untuk menyebarkan kontainer ke Azure.