<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Mevcut Bir Bulut Uygulamanın Docker ve Docker Teknolojilerini Kullanarak Bağımsız Çalışabilir Hale Getirilmesi Deneyimi (Experience of Converting an Existing Cloud Application into a Standalone System by Using Docker and Related Technologies)</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>r Mum</string-name>
          <email>serdar.mumcu@nurd.com</email>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff2">2</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Anahtar Kelimeler: Standalone</institution>
          ,
          <addr-line>On-premise, Docker, Docker Swarm, Valkyrie, Dockerfile, Docker-compose, Overlay Network</addr-line>
        </aff>
        <aff id="aff1">
          <label>1</label>
          <institution>Comodo Threat Research Labs</institution>
          ,
          <addr-line>NuRD Inovasyon Merkezi, Ankara</addr-line>
        </aff>
        <aff id="aff2">
          <label>2</label>
          <institution>Giriş ve Docker Hakkında</institution>
        </aff>
      </contrib-group>
      <abstract>
        <p>In this paper, some basic information about Docker technology, which is frequently mentioned nowadays, is given and its differences with and advantages over virtualization technologies are mentioned. In addition to this, a brief information about Valkyrie architecture, which is a cloud-based product, is given and the actions to be taken to meet the requirements and expected problems are mentioned. Finally, the experience of converting this product into a standalone package using Docker and Docker technologies; the way Docker and Docker Swarm technologies are utilized throughout this experience; and additional benefits obtained while using this architecture have been discussed. Özet. Bu bildiride temel olarak öncelikle günümüzde adından sıkça bahsettiren Docker teknolojisi hakkında temel bilgiler verilmiş, sanallaştırma teknolojileri ile olan farklılıklarından ve avantajlarından söz edilmiş, akabinde mevcut bir bulut (cloud) ürün olan Valkyrie mimarisi ile ilgili kısa bir bilgilendirme ve çözülmesi gereken ihtiyacın ve karşılaşılabilecek olası sorunların aktarılması sonrasında Docker ve Docker teknolojilerini kullanarak bahsedilen mevcut bulut ürünü bağımsız (standalone) bir kurulum haline getirme deneyimine ve bu deneyim sırasında Docker ve Docker Swarm teknolojilerinin konumlandırılma yöntemine ve ilgili mimarileri kullanmanın getirdiği ek faydalara değinilmiştir.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>
        Günümüzde oldukça popüler bir hale gelen Docker teknolojisi aslında LXC [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ]
dediğimiz (Linux Container) IBM tarafından 2008 yılında Linux çekirdeğine
eklenmiş, işletim sistemi seviyesinde sanallaştırma sağlayan bir teknolojiyi temel
alarak geliştirilmiştir. Özellikle uygulamaları aynı ev sahibi işletim sistemi (Host
Operating System) üzerinde birbirinden izole şekilde çalıştırabilmesiyle öne çıkmış
bir teknolojidir. Bunu yaparken de sıklıkla kullandığımız sanal makinelerden oldukça
farklı bir yöntem kullanmaktadır [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ].
      </p>
      <p>
        Öncelikle sanal makineler tam anlamıyla tüm işletim sistemi modüllerine sahip bir
misafir işletim sistemi (Guest Operation System) çalıştırmak zorunluluğu ile gelirler.
Bu işletim sisteminin açılması, yeniden başlatılması gerekli modüllerin yüklenmesi,
servislerinin ayağa kalkması oldukça ciddi bir zaman alır. Aynı zamanda tüm bu ek
işletim sistemi modül, servis ve sürücüleri belli bir oranda üzerinde çalıştığı
donanımın işlemci, bellek ve disk kaynaklarından fazladan tüketime neden olurlar. Bu
kaynaklara getirilen ek tüketim aslında ek maliyet anlamına da gelir [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ].
      </p>
      <p>Sanallaştırmanın temel amacı mevcut sahip olduğumuz donanımlar üzerinde
bağımsız uygulamalar çalıştırmaktır. Docker bu anlamda ihtiyaç duyulan açığı
kapatan bir teknoloji olarak karşımıza çıkmaktadır. Docker içinde bulunduğu işletim
sisteminin (Host OS) dışında ek bir işletim sistemine ihtiyaç duymadan
uygulamalarımızı birbirinden izole çalıştırabilmemizi sağlar.</p>
      <p>
        Şekil 1. Docker ve Sanal Makine Farkı [
        <xref ref-type="bibr" rid="ref12">12</xref>
        ]
      </p>
      <p>
        Bunu yaparken de oldukça hızlı ve donanımımıza da ek bir kaynak tüketimi
getirmeden bu işlemleri gerçekleştirebilmemize yardımcı olur. Her uygulama aynı
işletim sistemi üzerinde birbirinden bağımsız olarak kendi bağımlılıklarıyla çalışabilir
ve uygulamalar kolaylıkla olduğu haliyle başka bir ortama taşınabilir. Özellikle
geliştiricilerin yakındığı ve kendi makinelerinde çalışan kodun ya da uygulamanın
sunucuda çalışmaması şeklindeki sorunların oluşmasının en başından önüne geçer [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ].
      </p>
      <p>
        Aslında Docker geliştiricinin geliştirme şeklini ve uygulamalarımızı dağıtma
yöntemlerimizi temelinden değiştirerek bizi mikroservis (microservice) mimarisine de
hazır hale getirir [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ].
Bu bildiride, NuRD Inovasyon Merkezi altında faaliyet gösteren Comodo Threat
Research Labs birimi olarak gerçek bir ihtiyacımızı Docker’ın getirdiği olanaklar ile
çözdüğümüz ve sonuçlarından oldukça memnun kaldığımız bir senaryomuz ve bu
senaryo sırasındaki elde ettiğimiz deneyimlerimiz ve edindiğimiz faydalar
paylaşılmaktadır. Firmamızda geliştirmekte olduğumuz Valkyrie: Gerçek Zamanlı
Tehdit Tespit Sistemi (Valkyrie: Real Time Threat Identification Service) isimli
sistemimiz aslında bulut üzerinde sunduğumuz birbirinden çok farklı bileşenlerden
oluşan bir altyapıya sahip bir üründür. Ürün içerisindeki bileşenler uygulama
sunucuları (web application servers), veri tabanı sistemleri (database systems), kuyruk
mekanizmaları (queue systems), hafızalama sunucuları (cache) vb. gibi çoğu açık
kaynaklı ürünlerdir. Normalde, Valkyrie ürününü bir bulut sistem hizmet sunucusu
(cloud provider) üzerinden hizmet alarak hizmete sunulmaktadır ancak bazı büyük
kurumlar bu sistemi güvenlik ve bilgi gizliliği gibi nedenlerle kendi ortamları
içerisinde bağımsız (standalone) kurulum şeklinde kullanmak isteyebilmektedir.
      </p>
      <p>Sadece bellekleme sunucusunun (cache server) bile 7 farklı sunucudan oluşan bir
yapıyı kurumun kendi ortamına sadece kurmak ve konfigüre etmek bile başlı başına
büyük bir sorun iken bir de ilgili kuruma en az yerinde destek ile sistemin bakım ve
idamesini gerçekleştirmek büyük zorluklar getirmekte ve karmaşa yaratmaktadır.</p>
      <p>Şekil 2. Valkyrie Mevcut Mimari
3</p>
    </sec>
    <sec id="sec-2">
      <title>Uygulanan Çözüm Hakkında</title>
      <p>Bu soruna çözüm olarak sistemdeki tüm uygulamaları ve bileşenleri öncelikle
dockerize etmek ve ilgili kurumun bu çözüm için tahsis ettiği makine sayısı ne olursa
olsun, oluşturulacak docker container’ları ilgili sunuculara yine Docker’ın sağladığı
Docker Compose ve Docker Swarm teknolojilerini kullanarak dağıtmak şeklinde bir
çözüm benimsenmiştir.</p>
      <p>
        Docker’laştırmak (dockerization) aynı zamanda bu bileşenlerin kurulumlarını
standart hale getirmek ve dokümante etmek anlamına da gelmektedir. Bunun için
Dockerfile ismini verdiğimiz özel bir dosya oluşturulmaktadır [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ].
      </p>
      <p>Şekil. 3. Dockerfile Örnek Dosya</p>
      <p>Bu dosyalar da yine uygulama kodları gibi bir kaynak kontrol (source control)
sistemi üzerinde saklanmaktadır. İstenildiği ya da gerektiğinde bu dosyalar
güncellenerek kurulum parametreleri değiştirilebilmektedir. Daha öncesinde de her ne
kadar kurulum adımları dokümante edilse de (operasyon dokümanları - runbook’lar
ile) her seferinde bu işlemlerin bir kişi tarafından baştan sona adım adım uygulanması
gerekmekteydi. Aynı zamanda bazen manuel yapılan çözümlerin bu dokümantasyona
yansıtılmaması gibi sorunlar da oluşabilmekteydi. Bu çözümü gerçekleştirebilmek
için öncelikle tüm bu farklı bileşenleri geliştirici makinesinde çalışabilir hale
getirilmesi hedeflenmiştir. Normalde geliştirici makinesine tüm bu bileşenler
kurulabilse bile bazıları küme yapıda olduğu için birden fazla makineye ihtiyaç
duyuluyor ve gerçek ortam ile eşlenik bir kurulum yapılamamaktaydı.</p>
      <p>
        Öncelikle bu sorunu çözebilmek için tüm uygulama ve bileşenler
docker’laştırılmıştır. (Nginx-uwsgi, Redis, RabbitMQ, ElasticSearch, Logstash,
SocketIO, Syslog, Jenkins) Dockerlaştırma sırasında kalıcı (persistent) olması
gereken veriler için Docker’ın takılan birim (Volume Mount) [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ] özelliğinden
faydalanılmıştır. Daha sonra tüm dockerize edilen ilgili bileşenler Docker Compose
ürünü ile tanımlanmıştır. Bu ürün sayesinde geliştirici sadece tek bir komut
çalıştırarak bütün sistemi kendi makinesinde docker container’lar içerisinde ve sanal
bir ağ ile çalışabilir hale getirebilmektedir. Bu sayede onlarca sanal makine
kullanarak kuralabilen altyapıyı tek bir makine üzerinde de hem çok hızlı hem de çok
kolay ayağa kaldırabilme olanağı sağlamıştır. Yine docker-compose için de
dockercompose.yml adını verdiğimiz özel bir dosya türü kullanılmaktadır. Özellikle
dockercompose ürünü, yeni bir geliştirici ekibe dahil olduğunda geliştirme ortamının yeni
kişiye sorunsuz şekilde kurulması amacı ile de kullanılabilmektedir [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ].
      </p>
      <p>Şekil. 4. Docker-compose.yml Örnek Dosya</p>
      <p>Standalone kurulum oluşturma işleminin son aşamasında ise geliştiricinin tamamen
çalışabilir hale getirdiği bu sistemi bir konteynır orkestratör (container orchestrator)
yardımıyla birden fazla makineden oluşan bir gruba kurup çalıştırılması
hedeflenmiştir. Bunun için de oldukça kullanışlı olan bir orkestratör olan Docker
Swarm teknolojisinin kullanılması tercih edilmiştir. Docker Swarm’ün öncelikle
mevcut makinelere tanımlanması sağlanmıştır. Demo ortamımızda 3 adet Linux
makine oluşturulmuştur. Bu makineler yine Docker’ın sağladığı docker-machine
scriptleriyle oluşturulduğundan herhangi bir ek kurulum yapmadan direkt olarak
docker swarm kurulumuna geçilebilmiştir. Docker swarm kurulumu
gerçekleştirildikten sonra mevcut docker-compose.yml dosyası, ona çok yakın bir
biçim olan docker-stack dosyasına dönüştürülmüştür.</p>
      <p>
        Kurulumu yapılan makinelerden herhangi birinde bu stack dosyasını çalıştırarak
uygulamaların kurulumu (deployment) gerçekleştirilmiştir. Tüm servis ve bileşenler 3
makineye docker swarm tarafından dağıtılarak kurulumları gerçekleştirildi. Bu
aşamada gelen istekleri (request) bu makinelere dağıtan bir yük dengeleme (Load
Balancer) ayarı yapılmıştır. Docker Swarm Orchestrator ilgili servis başka bir
makinede bile olsa bu isteği alıp ilgili servise arka planda bir üst katman sanal ağ
(overlay/ingress network) üzerinden gönderip cevabını alıp bize gönderme yeteneğine
sahiptir. Dolayısıyla servisin hangi makinede çalışır durumda olduğu bizim için bir
önem arzetmemektedir [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ] (Service discovery).
      </p>
      <p>
        Bunların dışında yine Docker Swarm sağlamış olduğu sağlık kontrolü
(healthcheck) ve yeniden başlama (auto-restart) özellikleri sayesinde herhangi bir
servis işlev dışı kaldığında bunu otomatik olarak algılayarak servisi yeniden
başlatmaktadır. Bu özellikler sayesinde standalone kurulum yaptığımız kurum sistemi
üzerindeki bakım maliyetleri de minimize edilmiş oldu [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ]. Aynı zamanda Docker
swarm kolay ölçeklendirme özellikleriyle uygulamanın ölçeklendirilmesinin rahatça
gerçekleştirilmesi [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ] (Auto Scaling), belirli sayıda servisin sürekli çalışır durumda
kalmasını sağlaması (Desired state reconciliation) ve bileşenlerin güncellemelerinin
sistemde herhangi bir durma olmadan sağlaması (Zero Downtime Deployment) gibi
ek özellikler ile de fayda sağlamıştır [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ]. Uygulama içerisinde bir bileşene ait çalışan
konteynır (Container) sayısını belli bir seviyenin altına düşürmek istenmediğinde
veya ilgili bileşene anlık olarak çok fazla istek (request) geldiğinde sadece o bileşenin
çalışan konteynır (container) sayını otomatik olarak arttırmak istediğimizde ya da
yeni bir sürüm yüklediğimizde (deploy) hizmet kesintisi olmaksızın istekleri yeni
sürüme taşımak istediğimizde Docker Swarm teknolojisinin getirdiği bu özellikler
sayesinde bu işlemler rahatlıkla gerçekleştirilebilmektedir.
      </p>
      <p>
        Şekil. 5. Docker Swarm Altyapısı [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ]
4
      </p>
    </sec>
    <sec id="sec-3">
      <title>Sonuç ve Değerlendirmeler</title>
      <p>Docker ve Docker Teknolojilerini kullanarak oldukça zor olan bağımsız (standalone)
kurulum işlemlerini oldukça basite indirgenmesi ve standart hale getirilmesi
sağlanmıştır. Aynı zamanda bakım maliyetleri düşürülmüş, projenin bakım ve idame
ihtiyaçları da minimize edilmiştir. Bu şekilde mevcut bulut ortamlarımının
zorlanmadan bağımsız (standalone) halinde sunulabilmesi aynı zamanda şirketimize
yeni ve önemli bir iş sahasının kapılarını açmıştır.</p>
      <p>
        Sonuç olarak standalone kurulum problemine çözüm sunmak amacıyla kullanılan
Docker ve Docker teknolojileri aynı zamanda aşağıdaki ek faydaları getirmiştir:
• Kaynak kullanımı verimliliği (Hardware Utilization): İlk bölümde bahsedilen [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ]
nedenlerle Şekil2 ve Şekil5’te de göründüğü gibi 15 makine’den oluşan bir sistem,
bileşen sayısı, mimarisi ve performans değişikliği olmadan 3 makinede çalışabilir
hale indirgenebilmiştir.
• Çalıştırılabilen bir dokümantasyon oluşturabilme (Infrastructure as Code): 3.
      </p>
      <p>
        Bölümde bahsedilen Dockerfile ve Docker-Compose.yml dosyalarıyla systemin
tüm bileşenleri hem tek bir dosyada tanımlanmış ve dokümante edilmiştir. Hem de
bu dokümantasyon istenildiği takdirde geliştirici bilgisayarında veya sunucuda
çalıştırılabilmektedir.
• Kolay kurulum (Ease of Deployment): Docker Swarm bileşeni sayesinde kurulum
ortamı kaç sunucudan oluşursa oluşsun bunlar bir kümeye (cluster)’a dahil
edilebilmekte ve tüm altyapı tek bir makine gibi davranmaktadır. Yeni bir sürümü
yüklemek için sadece tek bir dosyayı değiştirmek ve tek bir komut çalıştırmak
yeterli olmaktadır [
        <xref ref-type="bibr" rid="ref15">15</xref>
        ].
• Bakım ve yönetim kolaylığı (Maintainability): Docker Swarm’da kümeyi (cluster)
yönetmek, izlemek, makinelerdeki hata durumlarına karşı önlem almak için
makinelerin köle-efendi (master-slave) yetkilendirmesini ayarlamak gibi bir çok
işlem çok hızlı ve kolay bir şekilde gerçekleştirilebilmektedir. Gerektiğinde
yazılım geliştirici bile kendisi kümeyi yönetebilmektedir [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ].
• Sağlık Kontrolü ve Otomatik Yeniden Başlatma (Healthcheck and Auto-Restart):
Docker Swarm kapanan konteynırları farkedip kendisi yeniden başlatabilmektedir.
Bunun için sağlık kontrolü (Healthcheck) mekanizmasına neyi kontrol edeceği
tanımlanabilmektedir [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ].
• Otomatik Ölçeklendirme (Auto Scaling): Zaman zaman sistem bileşenlerindeki bir
takım alt servislerin yükü diğer servislere oranla daha fazla artabilmektedir. Bu
gibi durumlarda yazılacak bir takım basit betikler (script) ile Docker Swarm’ın bu
bileşenleri otomatik olarak ilgili servislerin çalışan ortam sayısını yüke ya da
izlenen bir kuyruk sistemindeki bekleyen iş sayısına göre arttırıp azaltılması
sağlanabilmektedir. Yine istediği takdirde kümeye yeni makineler de otomatik
olarak eklenebilmektedir. Bu durum hizmet kalitesinin düşmemesini sağladığı gibi
makine sayıları optimal tutulduğu için aynı zamanda maliyet açısından da fayda
sağlamaktadır [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ].
• İstenen Durum Uyumlaştırma (Desired State Reconciliation): Docker Swarm
içerisindeki mekanizmalar sayesinde her zaman hedeflenen durumu
gerçekleştirmeye çalışır. Bunun için anlık durumu sürekli kontrol ederek
hedeflenen durumun dışına çıkıldığında bu duruma tekrar ulaşılması için gerekli
işlemleri kendisi otomatik olarak gerçekleştirir. Örneğin, bir servis’in çalışan
konteynır sayısı 3 olarak ayarlanmış ancak anlık çalışan servis sayısı 2 olmuş ise
sistem otomatik olarak yeni bir konteynır ayağa kaldırır. Böylece hedeflenen
duruma ulaşmış olur [
        <xref ref-type="bibr" rid="ref17">17</xref>
        ].
• Hizmet Kesintisiz Uygulama Güncelleme (Zero Downtime Deployment): Docker
Swarm üzerinde bir uygulamanın yeni bir sürümü kurulmak istendiğinde herhangi
bir hizmet kesintisi olmadan bu kurulum hızlı bir şekilde
gerçekleştirilebilmektedir. Kullancılar sürüm 1’i kullanırken kurulum sürüm 2
kurulduğunda sistem 2. sürüm istekleri kabul edebilene kadar istekleri 1.sürüm’e
iletmeye devam eder. 2.sürüm ayağa kalktığında ise 1.sürüm’e giden istekleri
yavaş yavaş 2. Süreme aktarmaya başlar. Daha sonra tümü aktarıldığında 1.sürümü
devre dışı bırakır [
        <xref ref-type="bibr" rid="ref18">18</xref>
        ].
• Hızlı geliştirme ortamı kurulumu (Faster Local Dev. Environment Creation):
Geliştirme ekibine yeni biri katıldığında onlarca bileşeni kurmak ve konfigüre
etmek yerine sadece tek bir komut çalıştırarak tüm ortamı bilgisayarında ayağa
kaldırabilmektedir. Hızlı bir şekilde geliştirme süreçlerindeki ihtiyaçlara
odaklanabilmektedir [
        <xref ref-type="bibr" rid="ref19">19</xref>
        ].
      </p>
      <p>Bu bağlamda edinilen bu deneyimlerden ve kazanımlardan benzer projelerde
faydalanılması planlanmaktadır.
5</p>
      <p>Teşekkür
Bildirinin hazırlanması sırasında gerek içerik gerek dil yönünden yaptıkları önemli
katkı ve kritikler ile desteklerini esirgemeyen değerli çalışma arkadaşlarım ve
yöneticilerim Gürkan Karahan, Anıl Doğan, Özgür Devrim Orman, Nurettin Mert
Aydın, Can Peker, Uğur Çakır ve Fatih Orhan’a desteklerinden ötürü teşekkür ederim.</p>
    </sec>
    <sec id="sec-4">
      <title>Referanslar</title>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          1.
          <string-name>
            <given-names>LXC</given-names>
            <surname>Wikiwand</surname>
          </string-name>
          , https://www.wikiwand.com/en/LXC, last accessed
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          2.
          <article-title>Containers vs. Virtual Machines (VMs): What's the Difference?</article-title>
          , https://blog.netapp.com/blogs/containers-vs-vms/,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          <article-title>3. Evaluation of Docker containers based on hardware utilization</article-title>
          , https://ieeexplore.ieee.org/document/7432984/, last accessed
          <year>2018</year>
          /11/07 (
          <string-name>
            <surname>Preeth E N</surname>
            ,
            <given-names>F. J. P.</given-names>
          </string-name>
          <string-name>
            <surname>Mulerickal</surname>
            ,
            <given-names>B.</given-names>
          </string-name>
          <string-name>
            <surname>Paul</surname>
            and
            <given-names>Y.</given-names>
          </string-name>
          <string-name>
            <surname>Sastri</surname>
          </string-name>
          ,
          <article-title>"Evaluation of Docker containers based on hardware utilization,"</article-title>
          <source>2015 International Conference on Control Communication &amp; Computing India (ICCC)</source>
          , Trivandrum,
          <year>2015</year>
          , pp.
          <fpage>697</fpage>
          -
          <lpage>700</lpage>
          . doi:
          <volume>10</volume>
          .1109/ICCC.
          <year>2015</year>
          .
          <volume>7432984</volume>
          )
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          4. But, it works on my machine. - Hacker
          <string-name>
            <surname>Noon</surname>
          </string-name>
          , https://hackernoon.com/but-it-works-on
          <source>-mymachine-74b6875ab4e7, last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          5.
          <article-title>Advantages of Using Docker for Microservices</article-title>
          , https://rubygarage.org/blog/advantagesof
          <article-title>-using-docker-for-microservices</article-title>
          ,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          6. Infrastructure as Code: A Reason to Smile | ThoughtWorks, https://www.thoughtworks.com/insights/blog/infrastructure-code
          <string-name>
            <surname>-</surname>
          </string-name>
          reason-smile,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          7.
          <string-name>
            <given-names>Using</given-names>
            <surname>Docker</surname>
          </string-name>
          <article-title>Compose for Development Environment Dependencies</article-title>
          , https://vsupalov.com
          <article-title>/flask-docker-compose-development-dependencies/</article-title>
          ,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          8.
          <article-title>Service discovery with Docker Swarm</article-title>
          , https://blog.scottlogic.com/
          <year>2016</year>
          /06/17/dockerswarm.html,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          9. Docker health checks - Dots and Brackets: Code Blog, https://codeblog.dotsandbrackets.com/docker-health-check/,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          10.
          <article-title>Auto-scaling a Docker Swarm</article-title>
          , https://scene-si.org/
          <year>2017</year>
          /05/02/auto-scaling
          <article-title>-a-dockerswarm/</article-title>
          ,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          11.
          <article-title>Swarm mode overview | Docker Documentation</article-title>
          , https://docs.docker.com/engine/swarm/,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          12. What is a Container | Docker, https://www.docker.com/resources/whatcontainer#/package_software,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          13.
          <article-title>Use swarm mode routing mesh | Docker Documentation</article-title>
          , https://docs.docker.com/engine/swarm/ingress/#
          <article-title>publish-a-port-for-tcp-only-or-udp-only</article-title>
          ,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          14. Use volumes | Docker Documentation, https://docs.docker.com/storage/volumes/#choosethe--v-or--
          <string-name>
            <surname>-</surname>
          </string-name>
          mount-flag,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          15.
          <string-name>
            <surname>Viktor</surname>
            <given-names>Farcic</given-names>
          </string-name>
          ,
          <source>The DevOps 2</source>
          .1 ToolKit: Docker Swarm, pp.
          <fpage>159</fpage>
          -
          <lpage>165</lpage>
          . Packt Publishing,
          <string-name>
            <surname>Birmingham</surname>
          </string-name>
          (
          <year>2017</year>
          )
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          16.
          <article-title>Administer and maintain a swarm of Docker Engines</article-title>
          , https://docs.docker.com/engine/swarm/admin_guide/,
          <source>last accessed</source>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          17.
          <string-name>
            <surname>Viktor</surname>
            <given-names>Farcic</given-names>
          </string-name>
          ,
          <source>The DevOps 2</source>
          .1 ToolKit: Docker Swarm, pp.
          <fpage>58</fpage>
          -
          <lpage>62</lpage>
          . Packt Publishing,
          <string-name>
            <surname>Birmingham</surname>
          </string-name>
          (
          <year>2017</year>
          )
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          18.
          <string-name>
            <surname>Srdjan</surname>
            <given-names>Grubor</given-names>
          </string-name>
          ,
          <source>Deployment with Docker</source>
          , pp.
          <fpage>272</fpage>
          -
          <lpage>277</lpage>
          ,
          <string-name>
            <surname>Pact</surname>
            <given-names>Publishing</given-names>
          </string-name>
          , Birmingham - Mumbai (
          <year>2017</year>
          )
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          19.
          <string-name>
            <surname>How</surname>
          </string-name>
          <article-title>Docker can improve your development environmentsi https://medium.com/phytochemia-tech-blog/how-docker-can-improve-your-developmentenvironments-731cdfda0b9a, last accessed</article-title>
          <year>2018</year>
          /11/07
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>