Docker etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Docker etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

14 Aralık 2020 Pazartesi

Docker Container Yapısı -3

Bu yazıda Docker Container yapısında yer alan Docker CLI kullanımına, komutlarına ve bilmemiz gerek temel özelliklere değinmeye devam edeceğim.

Docker Container Yapısı -1 ve Docker Containe Yapısı -2 yazılarında bir container oluşturup çalıştırdık ve ona ne yapmasını söylediysek onu yaptı. Container'ın ideal kullanımında da senaryo bu şekilde ilerler. Yani container'ı çalıştırırsınız ve container çalıştırıldığı image dosyasında ki ayarlara göre ayağa kalkar. Başka bir deyişle container çalıştıktan sonra içine girip şunu çalıştır bunu çalıştır demeyiz. Bu işlemlerin tamamı container image oluşturma aşamasında belirtilir ve image olarak paketlenir. Container ise o image den oluşturulmuş çalışan bir kopyadır.  Genel olarak tek bir uygulama çalışması için hazırlanır ve container çalıştırıldığı zaman da o uygulama çalışır  ve uygulama çalıştıkça da container ayakta durmaya devam eder. 

Kısaca bir container hangi uygulamanın çalışması için ayarlandıysa onunla ilgili her türlü ayarın image oluşturma aşamasında ayarlanmasıdır. Dolayısıyla sonradan container'a bağlanıp herhangi bir değişiklik yapmak gerekmez.

Container'a bağlanıp herhangi bir değişiklik yapmamız gerekmez demek container'a bağlanamayız anlamına gelmemektedir.  Docker, container'ın içine bağlanıp değişiklikler yapmamıza izin verir.  Bunun için gerekli tek şey o container image sinin içerisinde bağlanabileceğimiz bir shell olmasıdır ki hemen hemen bütün image'lerde bağlanabileceğimiz bir shell mevcuttur.

Container'a Bağlanma:
Öncelikle bir container oluşturalım:
docker container run -d -p 8282:80 --name htmlcontainer emrahakin/htmlsite

container oluşturma kısmını bir önce ki yazıda detaylı olarak anlatmıştım dilerseniz orayı referans alabilirsiniz.

Container'ımızı oluşturduktan sonra çalışan container'ları listeleyelim

docker container ls




Bu oluşturduğumuz container'a bağlanmak için "exec" komutunu kullanacağız.

docker container exec -it CONTAINER ID sh




Gördüğünüz gibi "sh" komutu ile container içerisinde ki shell'e bağlanmış olduk. Ben Docker imege oluştururken alpine tabanlı bir docker image si oluşturdum. Alpine tabanlı dağıtımlarda "sh" ile bir shell açabiliyorum.
Eğer Ubuntu tabanlı bir image kullansaydım onun içinde bash olduğundan "sh" yerine "bash" yazacaktım.

docker container exec -it CONTAINER ID bash

Peki "-it" nedir?
-it esasında iki opsiyonun birleşimi "--interactive" ve "--tty" opsiyonlarının birleşimi olarak "-it" kullanıyoruz. Yani bu container'a interactive modda bağlan (benim komutlarımı bu container içerisinde çalıştır) ve bunu sağlamak içinde bir terminal bağlantısı kur demek.

Container'a bağlandığımıza göre artık normal bir Linux makine gibi ne yapmak istiyorsak onu yapabiliriz.

Mesela bağlandığımız container'da ki dosyaları "ls" komutu ile listeleyelim

Container'ımızı ayağa kaldırdığımız makinede bir web browser açık localhost:8282 adresine gidersek orada bir web sitesinin çalıştığını göreceğiz.



Şimdi "sh" ile container'ın içine bağlandığımıza göre bu html sayfasını değiştirebilirim.

Docker imnage sini oluştururken bir Dockerfile dosyası hazırlamıştık bu dosyaya buradan ulaşabilirsiniz. Bu Dockerfile dosyasında index.html in /usr/share/ngnix/html klasörü içerisine atılmasını belirtmiştik. Şimdi bu dizine bağlanarak index.html dosyası orada mı bir bakalım.



Bu şekilde tek satır komutla da ilgili klasöre gidebiliriz:

cd usr/share/ngnix/html

Artık index.html dosyasına ulaştığımıza göre değiştirebiliriz:

echo "yeni yazı ekledim" >> index.html

bu komutu çalıştırdığımızda mevcut index.html dosyasına "yeni yazı ekledim" diye bir text eklemiş olacağız.



Web tarayıcımızda sayfayı yenilediğimizde "yeni yazı eklendi" yazısının sayfaya eklendiğini görüyoruz.


Görüldüğü gibi mevcut bir docker container'ın içine girip değişiklik yapabiliyoruz.

Bu container'ın içinde hangi uygulamaların çalıştığını yine "ps" komutuyla görebiliriz. Container'ın içindeyken terminal ekranına "ps" komutunu yazarsak hangi uygulamaların çalıştığı listelecektir.



"exit" komutuyla container'ın içerisinden çıkıp kendi shell ekranımıza dönebiliriz. "exit" komutu ile sadece container ile olan bağlantımızı kesiyoruz container çalışmaya devam eder bunu da "docker container ls" komutuyla görebiliriz. 

Docker Container Yapısı -2

 


Bu yazıda Docker Container yapısında yer alan Docker CLI kullanımına, komutlarına ve bilmemiz gerek temel özelliklere değinmeye devam edeceğim. Dilerseiz buradan Docker Container hakkında ki ilk yazıma ulaşabilirsiniz.

Ben örnek olması açısından Docker Hub üzerinde, içinde nginx ve html olan bir image oluşturdum. Bu yazımda bu image üzerinden ilerleyeceğim. Docker Hub üzerinde image oluşturma kısmına ileride detaylı olarak değineceğim.

Oluşturduğum bu docker image'sinden bir container oluşturduğumuzda localhost' umuzda nginx üzerinde çalışan bir html web sayfası ayağa kalkacak ve yayına başlayacak. Bu docker container'ı oluşturan Dockerfile dosyasını incelemek isterseniz buradan ulaşabilirsiniz.

Container'ı oluşturarak işle başlayalım:

docker container run -d -p 8282:80 --name htmlcontainer emrahakin/htmlsite

Not: burada kullandığımız -p komutu port anlamına geliyor. Container'ımızı istediğimiz bir porttan ayağa kaldırabiliriz ben 8282 portunu kullandım. -d komutu ise container'ımızı detach mode (arka planda çalıştırmak) ile çalıştıracağımızı belirtir. Bu komutlara ileride detaylı olarak değineceğim.

Uygulamamızı ayağa kaldırdıktan sonra terminal satırına aşağıda ki kodu yazarsak çalışan containerlarımızı listelemiş oluruz.

docker container ls

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
21ba7d5780ca emrahakin/htmlsite "/docker-entrypoint.…" 14 minutes ago Up 3 minutes 0.0.0.0:8282->80/tcp htmlcontainer

Ekran çıktısında, emrahakin/htmlsite image'sinden türeyen, htmlcontainer adında bir container'ın 3 dakikadır ayakta olduğunu görüyoruz.

Bu container içerisinde bir nginx server çalıştığı için, container oluşturulduktan sonra çalışmasına devam ediyor. Bir önce ki yazıda olduğu gibi tek sefer çalışan bir uygulama yerine devamlı çalışan bir web uygulaması ayağa kaldırmış olduk.

Şuan da docker'ın yüklü olduğu makinede (localhost) bir web tarayıcı açıp adres olarak localhost:8282 yazarsanız karşınıza aşağıda ki sayfa gelecektir.











Peki makinemizde bir nginx server yüklü değilken bu html sayfa nasıl çalıştı?

Esasında bu sorunun cevabı neden docker kullanıyoruz ile aynı. Çünkü biz container'ımızı içinde nginx yüklü olan ve bu nginx server da html sayfa çalıştıran bir docker image den oluşturduk.

"docker container ls" komutu ile çalışan container'larımızı listelediğimiz zaman her biine bir CONTAINER ID atadığını görürüz. Bu CONTAINER ID bizim ilgili container üzerinde işlem yapabilmemiz için docker tarafından atanan Unique ID lerdir.

Mesela bu container'ın loglarını görmek istersek:

docker container logs CONTAINER ID (bende 21ba7d5780ca)

CONTAINER ID sinin tamamını yazmanıza gerek yok ilk 4 hanesi de size istediğiniz sonucu verecektir.

docker container logs 21ba


Container Durdurmak:
stop komutu ile çalışan bir container'ı durdurabiliriz:
docker container stop 21ba

"docker container ls" komutunu çalıştırdığımızda container'ımızın artık bu listede olmadığını görebiliriz. "docker container ls" komutu sadece çalışan container'ları listeler. Containerlarımızın tamamını görmek istiyorsak "docker container ls -a" komutu ile listeleme yapmalıyız.

docker container ls -a

Bu komutu çalıştırdığımızda docker engine içinde yer alan çalışan ve durdurulmuş tüm containerların listesini görebiliriz.

Container Çalıştırmak:
start komutu ile durdurulmuş bir container'ı aynı özellikleriyle yeniden çalıştırabilriz:
docker container start CONTAINER ID (bende 21ba)

duran container'ımızı yeniden çalıştırdıktan sonra "docker container ls" komutuyla yeniden çalışan containerlar listesinde container'ımızı görebiliriz.

Container Silmek:
Container'ı durdurmak ile silmek aynı şey değildir. Eğer zaten durdurulmuş bir container'ı silmek istiyorsak:
docker container rm CONTAINER ID (bende 21ba)

Eğer çalışan bir container'ı silmek istiyorsak: Burada iki opsiyonumuz bulunmakta önce çalışan container'ı "stop" komutu ile durdurabilir ardından silebiliriz yada çalışır vaziyette iken

docker container rm -f CONTAINER ID (bende 21ba)

komutuyla silebiliriz. -f burada force anlamına gelmektedir.

Aynı anda birden fazla container'ı da silebiliriz bunun için "docker container rm" komutundan sonra silinmesini istediğimiz containerların ID lerini aralarında boşluk bırakarak yazmamız yeterli olacaktır.

docker container rm CONTAINER ID1 CONTAINER ID2 CONTAINER ID3 ...

16 Kasım 2020 Pazartesi

Docker Container Yapısı -1

Bu yazıda Docker Container yapısında yer alan Docker CLI kullanımına, komutlarına ve bilmemiz gerek temel özelliklere değinmeye çalışacağım.

Docker CLI (Command Line Interface): Bir docker kurulumu yaptığımızda sisteme yüklenen ve o Docker Engine yi yönetmemizi sağlayan komut satırı ara yüzüdür.

terminal satırına aşağıda ki komutu yazarak makinemizde kurulu olan docker engine hakkında bilgileri görelim:

docker info

komut çalıştırıldığında, makinemizde kurulu olan docker engine hakkında ki bilgileri ekrana yazar.




Çıktıda göreceğimiz gibi mevcutta kaç containerımız var, bu containerların kaç tanesi çalışıyor kaç tanesi durmuş durumda gibi temel bilgilere docker info komutu ile ulaşabiliriz.

Docker içinde kullanabileceğimiz bütün komutlara erişmek için komut satırına "docker" yazmamız yeterli olacaktır

docker

Terminal satırına "docker" komutunu yazıp çalıştırırsak Docker içinde kullanabileceğimiz bütün komutları görmüş oluruz.




Ekran çıktısında Management Commands ve Commands başlıkları altında kullanabileceğimiz komut formatlarını görebiliriz.


Docker ilk ortaya çıktığında komut satırı docker command ( docker run hello-world gibi) şeklindeydi. Bu kullanım Docker'ın geriye dönük uyumlu olamak istemesinden hala çalışıyor.
Docker geliştikçe ve daha kompleks işlemler yapmaya başladıkça komut satırını üç kademeli bir yapıya geçirdi. Bu nedenle hemen hemen her Command kendi Management komutuna sahip oldu. Bu üç kademeli yapıyı da docker management-command command( docker conntainer run hello-world ) şeklinde yapılandırdı.

Kısacası Docker da hangi Management Command ile işlem yapmak istiyorsak önce onu yazıyoruz ardından Command komutunu yazıyoruz. Bu kısımda bütün komutları ezberlememize tabi ki olanak yok. Ezberlemeye çalışmak yerine --help yardım komutunu kullanmak bizim için daha faydalı olacaktır. Mesela "image" lerle ilgili bir işlem yapmak istiyoruz, terminal satırına docker image --help komutunu yazalım.

docker image --help




Ekran çıktısından da gördüğünüz gibi image Management Commands'ı ile yapabileceğimiz komutlar karşımıza çıkıyor. Örnek olarak bir tane image silmek istiyorsak. Commands lara baktığımızda silme komutunun "rm" olduğunu görüyoruz. Peki "docker image rm" komutunu nasıl kullancağız?
Komut satırına "docker image rm --help" yazarsak image içinde "rm" i nasıl kullanabileceğimizi bize gösterecektir.




En üstte gördüğümüz gibi docker image rm [OPTIONS] IMAGE [IMAGE...] yapısıyla image management-commands' ını kullanabiliyoruz.
Örnek olarak:

docker image rm -f hello-world

Docker Container:
Bir docker container'ı nasıl oluşturacağımızı komut satırına "--help" fonksiyonu ile öğrenelim.

docker container --help




Ekran çıktısını incelediğimizde "create" komutu bir container oluşturmamızı, "start" komutu ise o container'ı başlatmamızı sağlıyor.
Her defasında önce container'ı oluşturup sonra start ile çalıştırmak yerine "run" komutunu da kullanabiliriz. Bu komut (run) yukarıda da açıklandığı gibi container yoksa önce oluşturuyor sonra da çalıştırıyor.

Peki docker container run komutunu nasıl kullanacağız?

docker container run --help

Bu komutu yazdığınızda karşınıza uzunca bir liste çıkacaktır. Bu listeyi inceleyip farklı komutlar kullanabilirsiniz. Ben örnek olması amacıyla "run" komutunu inceleyeceğim.

Ekran çıktısında önemli olan kısım Usage kısmıdır. Docker, Usage kısmında bu komutu nasıl kullanacağımızı  bize söylüyor.                                                                                                                                                                                                                   
"Usage:  docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]"

docker container run daha sonra girmek istediğim bir "OPSIONS" varsa bunu yazıyorum sonra hangi "IMAGE" den bir container yaratmak istiyorsam o image'nin adını giriyorum en son olarak ta bu image içinde farklı bir komut çalıştırmak istiyorsam o komutları giriyorum. Hadi deneyelim:

docker container run --name ilkcontainer emrahakin/ilkcontainer
Komut satırına aşağıda ki komutu yazdığımızda ilkcontainer adında emrahakin/ilkcontainer image sinden bir container oluşturacağız.
docker container run --name ilkcontainer emrahakin/ilkcontainer 




Görüldüğü gibi docker run komutundan sonra emrahakin/ilkcontainer image si bizde olmadığı için önce docker hub dan bu image yi çekti ve ardından bu image den ilkcontainer isminde bir container oluşturdu ve container içerisinde ki uygulamayı çalıştırdı "Merhaba İlk Container Başarıyla Oluşturuldu" yazısını yazdı ve container kapatıldı.

https://github.com/emrakin/DockerLearningRepo/tree/main/CreateDockerImage/CreateDockerImage  dilerseniz bu linkte ki Dockerfile dosyasını ve ilkcontainer olarak indirdiğimiz .NET Console Uygulamasını inceleyebilirsiniz.

docker container ls -a
Komut satırına docker container ls -a yazarsak sistemimizde oluşturulmuş bütün container ları görebiliriz. (-a yazmazsak sadece çalışan container ları görebiliriz.)

ilkcontainer isimli container a baktığınız da "STATUS" kısmında Exited (yani kapatılmış) yazdığını göreceksiniz. Kapatılmasının sebebini şöyle açıklayabiliriz.
Bir docker imajından container oluşturduğumuz zaman içinde  varsayılan olarak çalışması için bir uygulama vardır. Bu uygulama çalıştığı sürece container ayakta kalır. Uygulama çalışmayı bıraktığı zaman container da kapanır. Bizim docker imajımızda yer alan uygulama da ekrana "Merhaba İlk Container Başarıyla Oluşturuldu" yazısını yazdıktan sonra kapandığı için ilkcontainer adında oluşturduğumuz container da Exited olmuş durumda. Yukarıda da bahsettiğim gibi ben burada bir .NET Console App uygulaması yaptım Dockerfile ve uygulamaya https://github.com/emrakin/DockerLearningRepo/tree/main/CreateDockerImage/CreateDockerImage bu linkten ulaşabilir ve inceleyebilirsiniz.

Bir sonra ki anlatımda container yapısına devam edeceğim ve bir web uygulamasının docker içinde nasıl çalıştırıldığından bahsedeceğim.

30 Nisan 2019 Salı

.Net Core Uygulamasında Redis Cache Kullanımı


Bu yazıda Docker üzerinde bir Redis Container'ı koşturup, artından bir .Net Core Mvc projesinde nasıl kullanılacağını inceleyeceğiz. Redis (distributed cahce)' de amaç, bir web sayfası yada bir web API' dan gelen istekler olduğunda her seferinde servise ya da DB'ye gitmektense bu istekleri In Memory olarak yani ram'den karşılanması ve bu sayede performansın arttırılmasıdır.

Yazının tamamında kullanılacak teknolojiler;
  • Docker
  • Redis
  • .Net Core
Öncelikle eğer makinamızda Docker yok ise https://www.emrakin.com/2019/04/docker-nedir-neden-kullanlr-nasl.html bu adresten Docker kurulumu hakkında bilgi edinebilirsiniz.

Docker üzerinde bir Redis Container koştumak için aşağıdaki kodu kullanalar "6379" portundan ayağa kalkması sağlanır.
docker run -d --name Redis -p 6379:6379 redis

Ben .Net Core Mvc projesinde Redis için ServiceStack kullandım. İlgili kütüphaneyi https://www.nuget.org/packages/ServiceStack.Redis.Core bu linkten inceleyebilir ve Nuget ile projenize ekleyebilirsiniz.
PM> Install-Package ServiceStack.Redis.Core

Redis'in .Net Core projesinde kullanımı için Startup.cs'de AddDistributedRedisCache() methodu ile redisserver'ın IP ve Portu'nu tanımlıyoruz.
public void ConfigureServices(IServiceCollection services)
{
     services.Configure<CookiePolicyOptions>(options =>
     {
           options.CheckConsentNeeded = context => true;
           options.MinimumSameSitePolicy = SameSiteMode.None;
     });
     services.AddDistributedRedisCache(options =>
     {
            options.InstanceName = "RedisNetCoreSample";
            options.Configuration = "localhost:6379"; //Your Redis Connection
      });

      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

AddDistributedRedisCache() methodunu Startup.cs' de kullanmak için Microsoft.Extensions.Caching.Redis'i Nugetten projenize dahil etmeniz gerekiyor.
PM> Install-Package Microsoft.Extensions.Caching.Redis

Models: Models klasörü altında Person.cs adında bir sınıf oluşturuyoruz.
public class Personal
{
     public int ID { get; set; }
     public string Name { get; set; }
     public string Surname { get; set; }
     public int Age { get; set; }
 }

Projemize RedisRepository adında bir klasör ekliyoruz. Bu klasör altında Redis'le ilgili işlemlerimizi bir interface yapı da tutacağız. RedisRepository klasörünün altında IRedisService adında bir interface oluşturuyoruz.
public interface IRedisService
{
     List<Person> GetAll(string cachekey);
     Person GetById(string cachekey);
 }

RedisRepository klasörü altına IRedisService.cs den  inheritance olmuş RedisManager.cs adında bir sınıf oluşturuyoruz.
public class RedisManager : IRedisService
{
    public List<Person> GetAll(string cachekey)
        {
            using (IRedisClient client = new RedisClient())
            {
                List<Person> dataList = new List<Person>();
                List<string> allKeys = client.SearchKeys(cachekey);
                foreach (string key in allKeys)
                {
                    dataList.Add(client.Get<Person>(key));
                }
                return dataList;
            }
        }

        public Person GetById(int personId, string cachekey)
        {
            using (IRedisClient client = new RedisClient())
            {
                var redisdata = client.Get<Person>(cachekey);

                return redisdata;
            }
        }
}

IRedisServise ve RedisManager'ı Startup.cs'e dahil etmemiz gerekiyor.

public void ConfigureServices(IServiceCollection services)
{
      services.Configure<CookiePolicyOptions>(options =>
      {
             options.CheckConsentNeeded = context => true;
             options.MinimumSameSitePolicy = SameSiteMode.None;
      });
      services.AddDistributedRedisCache(options =>
      {
            options.InstanceName = "RedisNetCoreSample";
            options.Configuration = "localhost:6379"; //Your Redis Connection
      });

      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

      services.AddScoped<IRedisService, RedisManager>();
}

HomeController.cs/HomeController(): Öncelikle person sınıfı tipinde yeni bir kayıt oluşturup Redis cache'e atıyoruz.

- "cachedata.SetValue("Person"+personvalue.ID, personvalue);": Redis'de "Person+ID" key'ine karşılık value değeri olarak oluşturulan dataByte[] dizisi SetValue() methodu ile atıyoruz.

private readonly IRedisService _redisService;

public HomeController(IRedisService redisService)
{
      _redisService = redisService;
   
     using (IRedisClient client = new RedisClient())
     {
           if (client.SearchKeys("Person*").Count == 0)
           {
                 var personvalue = new Person();
                 personvalue.ID = 1;
                 personvalue.Name = "Emrah";
                 personvalue.Surname = "Akın";
                 personvalue.Age = 40;

                 var cachedata = client.As<Person>();
                 cachedata.SetValue("Person"+personvalue.ID, personvalue);

            }
      }
}

HomController.cs/Index: Redis'e "Person" key'i ile atılan tüm verileri getirmek için "Person*" ile çağırıyoruz.
public IActionResult Index()
{
      const string cacheKey = "Person*";
      var redisdata = _redisService.GetAll(cacheKey);

      return View(redisdata);
}

Index.cshtml:  View modelden gelenleri ekrana yansıtıyoruz

@model IEnumerable<NetCoreRedis.Models.Person>
@{
    ViewData["Title"] = "Index";
}

<table class="table">
    <thead>
        <tr>
            <th>
                ID
            </th>
            <th>
                Name
            </th>
            <th>
                SurName
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>

        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.ID)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Surname)
                </td>
                <td>
                    @Html.ActionLink("Details", "Home", new { id = item.ID }) |
                </td>
            </tr>
        }
    </tbody>
</table>

HomeController.cs/Detail: 
public IActionResult Detail(int Id)
{
    string cacheKey = "Person"+Id;
    var redisdata = _redisService.GetById(cacheKey);

     return View(redisdata);
}

Detail.cshtml: 
@model NetCoreRedis.Models.Person
@{
    ViewData["Title"] = "Detail";
}

<h3><b>Person:</b></h3>

<table class="table">
    <tr>
        <td>Ad:</td>
        <td>@Model.Name</td>
    </tr>
    <tr>
        <td>Soyad:</td>
        <td>@Model.Surname</td>
    </tr>
    <tr>
        <td>Yaş:</td>
        <td>@Model.Age</td>
    </tr>
</table>


Docker container olarak ayaklandırdığımız Redis cache üzerinden key value'larımızı görmek için terminal ekranına aşağıdaki kodu yazdıktan sonra "Keys *" komunu kullanabilirsiniz.

docker exec -it Redis redis-cli

Projenin bitmiş haline https://github.com/emrakin/.NetCore-Redis buradan ulaşabilirsiniz.

İlgili Kaynaklar:

22 Nisan 2019 Pazartesi

Docker Nedir, Neden Kullanılır, Nasıl Kurulur, Nasıl Kullanılır?(Wordpress Kurulumu)



Kısa tanımıyla Docker; geliştirdiğiniz uygulamaları platform bağımsız bir şekilde kullanabilmenizi sağlayan "container" teknolojisidir.

Docker' ı anlayabilmek için öncelikle virtualization teknolojilerini anlamak gerektiğine inanıyorum.

Virtualization teknolojilerisinin ne olduğunu derinlemesine anlatmak yerine en kısa en basit anlatımıyla virtualization bir işletim sisteminin içerisine birden fazla işletim sistemini kurabilmektir. Yani bir Windows içerisine bir Windows daha kurmak ya da bir MacOs veya Linux kurabilmek gibi kısa, basit ama olayı anlatan bir tanımla başlamış olalım.

Peki bunu neden kullanmak isteriz?

Elinizde bir tane bilgisayar var diyelim ve bunu birden fazla kişinin kullanmasını istiyorsunuz. Her kullanıcının istediği programları kurmasını, kendi işlerini yapmalarını ve bütün bunlar olurken de birbirleriyle çakışmayacak şekilde tamamen izole edilmiş ortamlar oluşturmak istiyorsunuz.
Daha sonra herhangi bir kişinin artık bu ortamı kullanmasını istemediğinizde sadece ona ayırdığınız izole edilmiş ortamı silerek bu kişi için kurduğunuz işletim sisteminin ve programların diğer kullanıcılar etkilemeden ortamdan kaldırılmasını istiyorsunuz. İşte bu isteklerinizi yapabildiğiniz teknolojin adı Virtualization Teknolojisi.


Docker'ı neden kullanmak isteriz?


Yine bir örnek üzerinden gitmemiz gerekirse bir .Net Core API projesinde datalarınızı Redis üzerinden okuyup yazdırsak daha mı iyi olur sorusuna cevap arıyorsunuz. Bunun için önce Redis'i kurmanız ve ayaklandırmamız gerekir. Peki aradığınız teknoloji Redis değilse? O zaman ya kurduğunuz Redis'i bilgisayarınızda bırakıp başka bir şeyler arayacaksınız yada Redis'i bilgisayarınızdan kaldırmaya çalışacaksınız yada bunların hiç birini yapmayıp Docker için hazırlanmış bir Redis imageını makinenizde çalıştıracak ve testlerinizi gerçekleştirdikten sonra oluşturmuş olduğunuz Docker Container'ı silip hayatınıza kaldığınız yerden devam edeceksiniz.

Docker tarihçesi ve daha detaylı bilgi için Gökhan Şengün tarafından yazılan şu yazıyı okuyabilirsiniz.

Docker'ın en temel mantığı "benim bilgisayarımda çalışan her bilgisayarda çalışır." dır.

Docker Nasıl Kurulur?


İşletim sisteminiz MacOs ise aşağıdaki linkten kurulumu yapabilirsiniz.

https://docs.docker.com/docker-for-mac/install/



İşletim sisteminiz Linux ise aşağıdaki linkten sol tarafta ki menüden kendi Linux'ınıza uygun kurulumu yapabilirsiniz.

https://docs.docker.com/install/


İşletim sisteminiz Hyper-V içeriyorsa. (Windows Pro, Enterprise vb) Aşağıdaki linkten indirip kurulumu yapabilirsiniz.

https://docs.docker.com/docker-for-windows/install/



Eğer işletim sisteminiz Windows 10'sa Docker toolbox ile kurulumu yapabilirsiniz.

https://docs.docker.com/toolbox/toolbox_install_windows/


NOT: Kurulum sonrası Docker Quickstart Terminal'i açın. Bunun öncesinde BIOS' dan VIRTUALIZATION ayarlarını Enable yapmayı unutmayın.

https://www.youtube.com/watch?v=za5eAnVVWfs


Artık kurulumu tamamladığımıza göre Docker-CLI üzerinde çalışmaya başlayabiliriz.

Docker CLI

Ben komutları Windows üzerinde çalıştırıp çıktıları sizinle paylaşacağım ancak bütün komutlar Mac OS X ve Linux sistemlerde de aynen çalışacaktır sadece çıktılar farklı olabilir.

İşletim sistemimizin terminalini açıp komutları yazmaya başlayabiliriz.

1. Öncelikle Docker kurulumumuzun doğru çalışıp çalışmadığını kontrol etmek için docker version komutunu yazalım. 

C:\Users\xxx>docker version
Client: Docker Engine - Community
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        6247962
 Built:             Sun Feb 10 04:12:31 2019
 OS/Arch:           windows/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       6247962
  Built:            Sun Feb 10 04:13:06 2019
  OS/Arch:          linux/amd64
  Experimental:     false

Dikkat ederseniz Client (Docker CLI) kısmında windows/amd64 olan Os/Arch tipi Server (Docker Daemon) kısmında linux/amd64 olarak görünüyor. Bunun nedeni Daemon Windows içinde ki Hypervisor tarafından çalıştırılan bir Linux makinede koşuyor.

2. Artık Docker kurulumumuzun başarılı olduğunu biliyoruz o zaman DockerHub'dan ilk Docker Image'ımızı inidirip çalıştıralım.
Benim amacım Windows bir makinede Wordpress'i kurmak. Şuan benim bilgisayarımda Wordpress için gerekli hiç bir şey kurulu değil. (MySQL, Apache Server vb.).

Öncelikle bize bir MySQL birde Wordpress Image'ı gerekli.

Wordpress image: https://hub.docker.com/_/wordpress
MySQL Image: https://hub.docker.com/_/mysql

Image dosyalarını nasıl indireceğimiz ve nasıl kullanacağımız hakkında detaylı bilgiler ilgili linklerde mevcut ben sadece temel olarak bir örneklendirme yapacağım ayrıntıya girmek isteyenler ilgili linklerde ki anlatımları takip edebilirler.

docker pull mysql pull komutu ile ilgili mySQL Docker Image'ını indiriyoruz.



C:\Users\xxx>docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
27833a3ba0a5: Already exists
864c283b3c4b: Pull complete
cea281b2278b: Pull complete
8f856c14f5af: Pull complete
9c4f38c23b6f: Pull complete
1b810e1751b3: Pull complete
5479aaef3d30: Pull complete
ded8fa2e1614: Pull complete
636033ba4d2e: Pull complete
902e6010661d: Pull complete
dbe44d2bf055: Pull complete
e906385f419d: Pull complete
Digest: sha256:a7cf659a764732a27963429a87eccc8457e6d4af0ee9d5140a3b56e74986eed7
Status: Downloaded newer image for mysql:latest

docker pull wordperss ile WordPress Docker Image'ını indiriyoruz.


docker images komutu ile indirdiğimiz ve kullanıma hazır Docker Image' larımızı görebilirsiniz.

Şimdi sıra geldi mySQL ve WordPress Image'larını çalıştırmaya.


docker run --name mysql01 -e MYSQL_ROOT_PASSWORD=Password1234 -d mysql --default-authentication-plugin=mysql_native_password


Bu komut ile MySQL'i çalıştırıyoruz.

docker run --name wordpress01 --link mysql01 -p 8080:80 -e WORDPRESS_DB_HOST=mysql01:3306 -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=Password1234 -e WORDPRESS_DB_NAME=wordpress -e WORDPRESS_TABLE_PREFIX=wp_ -d wordpress

Bu komut ile Wordpress'i çalıştırıyoruz.

MySQL ve Wordpress Container'larımızı çalıştırdıktan sonra docker ps komutu ile çalışan Container'larımıza göz atalım.

72818047f6f4       wordpress       ...     0.0.0.0:8080->80/tcp     wordpress01
f3193821ad7b       mysql       ...     306/tcp, 33060/tcp     mysql01

Görüldüğü gibi iki Container da çalışıyor. Kullandığımızdan browserdan http:localhos:8080 adresini yazarak wordpress sitemizi kurmaya başlayabiliriz.


Kaynaklar:
https://medium.com/5bayt/windows-10-home-docker-kurulumu-7bc71475558

https://gokhansengun.com/docker-nedir-nasil-calisir-nerede-kullanilir/

https://www.youtube.com/watch?v=g_Q7TDsrwgo&list=PL_Z0TaFYSF3LTfMIRjPUlVoUipQA0JlL2&index=8