Docker bilindiği gibi, bir dosya sisteminde içerisinde sadece çalıştırılmak istenen uygulamanın ihtiyaç duyduğu kod, sistem araçları, sistem kütüphaneleri gibi yapıları barındıran bir sanallaştırma platformudur. Docker’ın bana göre en önemli özelliği çalıştırdığınız Docker kontaynerının her zaman aynı durumda, environment’dan bağımsız bir şekilde çalışacağını garanti etmesi.
Ben de bu blog yazısında Docker ile mini bir wiki uygulaması olan ruby ile yazılmış gollum’un nasıl çalıştırılacağı ve sisteminizde nasıl ve ne şekilde kullanabileceğinizi anlatacağım.
Ön Bilgiler ve Gereksinimler
Ben bu blog yazısında geliştirme ortamı olarak Debian Jessie 8.1 seçtim.
Docker versiyonu olarak : Docker version 1.6.2, build 7c8fca2 kullandım.
Bu blog yazısını takip edilebilmesi ve anlaşılabilmesi için Docker’ın çalışma mantığına hakim olmak, Dockerfile makrolarını bilmek vb. gerekecektir.
Kurulu ve düzgün çalışan docker’ı sisteminize kurmanız yeterli. Blogun devamında Docker’ı düzgün çalıştırdığınızı varsayarak ilerleyeceğim.
Gollum için Dockerfile Hazırlanması
Sisteminize docker’ı kurduktan sonra, çalışma dizininizde bir yere ilgili Dockerfile dosyasını aşağıdaki içerikle oluşturun :
Not: Makroların ne anlama geldiğini hemen altta belirteceğim :
$ vim Dockerfile
FROM ruby
RUN apt-get -y update && apt-get -y install libicu-dev git
ENV APP gollum
RUN git clone https://github.com/gollum/gollum
WORKDIR $APP
RUN bundle install
CMD ["bundle", "exec", "/gollum/bin/gollum", "/gollum/wiki", "--port", "80"]
EXPOSE 80
FROM : DockerHub servisinden getirilen docker imajı. Docker’da Ruby uygulaması koşturacağım için Docker’ın Official ruby imajını kullandım.
RUN : Sistem komutlarını çalıştırmak için kullanılan makro (e.g apt-get etc)
ENV : Değişken tanımlamak için kullanılan makro
WORKDIR : Çalışma dizinini değiştirmek için kullanılan makro (e.g. cd )
CMD : Argüman vererek çalıştırılması gereken komutlar için kullanılan makro (Aşağıdaki linkte RUN vs CMD farkının ne olduğunu detaylı bir şekilde okuyabilirsiniz)
EXPOSE : Uygulamanın sunulduğu portun dışarı açılması için kullanılan makro (e.g. HTTP -> 80 veya tomcat -> 8080)
Diğer makrolar için buradan.
Aslında standart bir ruby uygulaması için neler yapılıyorsa, aynısını bunun docker imajı içersinde yapılmasını bu şekilde sağlıyoruz (bkz: bundle install)
Oluşturduğumuz Dockerfile’ı, dosyanın bulunduğu dizinde aşağıdaki komutla build edip, içerisinde gollum çalışan bir docker imajı üretmiş olacağız :
$ sudo docker build -t gollum .
Docker ilk önce DockerHub’dan ruby imajını indirecek ve sizin Dockerfile’da tanımladığınız makrolara göre sisteminizde gollum isminde yeni bir imaj üretecek.
Bu gollum imajında da sadece ve sadece gollum’un gereksinim duyduğu gemler vb. yer alacak.
Sisteminizde kurulu imajları aşağıdaki şekilde görebilirsiniz :
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
gollum latest 7dcd1736337d 2 days ago 878.8 MB
419a67a3a1e1 2 days ago 878.8 MB
0971cd625b7d 2 days ago 878.8 MB
9a45bb9712e1 2 days ago 791.6 MB
fc083ae2e085 2 days ago 791.6 MB
dd0c5f48c124 2 days ago 791.6 MB
632c1a5a9efd 2 days ago 766.1 MB
2de79b937395 2 days ago 766.1 MB
3cc8ed623ab8 13 days ago 717.8 MB
ruby latest 7559e00e6e8b 13 days ago 717.8 MB
cd42401de2df 13 days ago 717.8 MB
702b6afaf1de 13 days ago 716.7 MB
782b0a3e2a91 13 days ago 716.7 MB
5afe9ee8266d 13 days ago 716.7 MB
c46d297cf2ed 13 days ago 716.7 MB
e38c962d885f 13 days ago 606.2 MB
3869eb4b56f4 13 days ago 606.2 MB
c314b7cf3e15 13 days ago 606.2 MB
3802d6035798 13 days ago 606.2 MB
df231b622270 13 days ago 606.2 MB
a3d4ddaffb90 2 weeks ago 606.2 MB
d63502d4fbd8 2 weeks ago 291.6 MB
f9fffdafe16d 2 weeks ago 169.4 MB
6845b83c79fb 2 weeks ago 125.1 MB
575489a51992 2 weeks ago 125.1 MB
<none> olarak görülen imajlar ruby imajının üretilmesi için üretilmiş pre-build imajlar, günün sonunda bu imajlar ruby altında merge ediliyor, ruby’den de bizim henüz ürettiğimiz gollum imajı build ediliyor.
Üretilen Docker imajından Docker Container’ının Ateşlenmesi
Gollum’un çalışması için, wikilerin markdown formatında tutulduğu bir wiki git repository’si gerekli. Ben bu dokümanları host sistemimde /opt/gollum altında tutmayı tercih ettim.
$ sudo mkdir /opt/gollum
$ cd /opt/gollum && git init
Boş wiki repository’sini oluşturduktan sonra aşağıdaki komutla ürettiğimiz gollum docker imajından bir gollum_wiki isimli bir docker container’ını ateşliyoruz :
$ pwd
/opt/gollum
$ sudo docker run -v `pwd`:/gollum/wiki -p 8080:80 --name=gollum_wiki gollum
Docker’ın davranışını anlamak için bu komut’un anatomisini inceleyelim :
docker run -> Bir Docker imajından bir Docker container’ı çalıştırmak için verdiğimiz komut
-v pwd
:/gollum/wiki -> -v host sisteminden bir dizini(bu örnekte /opt/gollum) konteynır içerisinde bir yere ( bu örnekte /gollum/wiki) mount etmek için kullanılan parametre,
-p 8080:80 -> Sistemde Docker container içerisinde çalışan uygulamanın nereden sunulacağı (Bu örnekte host’un 8080 portunu, Docker container’ın 80. portuna proxy)
–name -> Container’ın isminin ne olacağı, bunu vermezseniz Docker size tatlı tatlı konteynır isimleri üretecek
gollum -> Üretilecek Docker container’ının hangi Docker imajından üretileceği
Bu komut sonucunda içerisinde gollum çalışan bir docker container’ı çalıştırmış oluyorsunuz. Web tarayıcınızda localhost:8080 ‘de uygulamanın arayüzünü görebilirsiniz.
Çalışan konteynırları görmek için
aydintd@sirius:~/workspace/gollum$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e954e7cb7c86 gollum:latest "bundle exec /gollum 2 days ago Up 58 minutes 0.0.0.0:8080-80/tcp gollum_wiki
Lovely 🙂
Docker Container’ının Sistem Her Açıldığında Up Edilmesi
Ben bunu systemd ile çözdüm. Docker konteynırları; yazının başında da belirttiğim gibi, host sisteminiz (bu örnekte benim kişisel bilgisayarım) kapansa dahi her zaman aynı kalacağını garanti ediyor. Bir önceki başlığın sonundaki sudo docker ps -a
çıktısında konteynırın ismi gollum_wiki (bkz: run komutu)
Bu konteynırı her sistem açıldığında up etmek için docker start
ı kullanacağız.
/usr/lib/systemd/system
altında gollum için bir service file’ı oluşturalım :
[Unit]
Description=Gollum Wiki Container
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a gollum_wiki
ExecStop=/usr/bin/docker stop -t 2 gollum_wiki
[Install]
WantedBy=multi-user.target
Dosyayı kaydettikten sonra artık bu konteynır bir servise dönüştü sistemimizde.
$ sudo systemctl start gollum.service
$ ps ax | grep gollum
5471 ? Ssl 0:00 /usr/bin/docker start -a gollum_wiki
5484 ? Ssl 0:01 ruby /gollum/bin/gollum /gollum/wiki --port 80
6057 pts/1 S+ 0:00 grep --color=auto gollum
Sistem açılışına ekleyin :
$ sudo systemctl enable gollum.service
Created symlink from /etc/systemd/system/multi-user.target.wants/gollum.service to /usr/lib/systemd/system/gollum.service.
systemd’de gollum’u görmek için :
aydintd@sirius:~/workspace/gollum$ sudo systemctl status gollum.service
● gollum.service - Gollum Wiki Container
Loaded: loaded (/usr/lib/systemd/system/gollum.service; enabled)
Active: active (running) since Fri 2015-11-06 14:54:45 EET; 1h 10min ago
Main PID: 5471 (docker)
CGroup: /system.slice/gollum.service
└─5471 /usr/bin/docker start -a gollum_wiki
Nov 06 14:54:50 sirius docker[5471]: http://localhost:8080/Home -> /javascript/editor/gollum.editor.js
Nov 06 14:54:50 sirius docker[5471]: 172.17.42.1 - - [06/Nov/2015:12:54:50 UTC] "GET /javascript/gollum.dialog.js HTTP/1.1" 304 0
Nov 06 14:54:50 sirius docker[5471]: http://localhost:8080/Home -> /javascript/gollum.dialog.js
Nov 06 14:54:50 sirius docker[5471]: http://localhost:8080/Home -> /javascript/jquery-1.7.2.min.js
Nov 06 14:54:50 sirius docker[5471]: 172.17.42.1 - - [06/Nov/2015:12:54:50 UTC] "GET /css/template.css HTTP/1.1" 304 0
Nov 06 14:54:50 sirius docker[5471]: 172.17.42.1 - - [06/Nov/2015:12:54:50 UTC] "GET /javascript/gollum.placeholder.js HTTP/1.1" 304 0
Nov 06 14:54:50 sirius docker[5471]: http://localhost:8080/Home -> /javascript/gollum.placeholder.js
Nov 06 14:54:50 sirius docker[5471]: http://localhost:8080/Home -> /css/template.css
Nov 06 14:54:50 sirius docker[5471]: 172.17.42.1 - - [06/Nov/2015:12:54:50 UTC] "GET /images/icon-sprite.png HTTP/1.1" 304 0
Nov 06 14:54:50 sirius docker[5471]: http://localhost:8080/css/gollum.css -> /images/icon-sprite.png
Troubleshooting
Üretilen container’ı up ettikten sonra içerisini incelemek isterseniz aşağıdaki şekilde container’ın dosya sistemini görebilirsiniz :
aydintd@sirius:~/workspace/gollum$ sudo docker exec -it gollum_wiki bash
root@e954e7cb7c86:/gollum/wiki# ls -l
total 80
-rw-r--r-- 1 root root 8335 Jan 31 2015 ES-Calisma-Notlari.md
-rw-r--r-- 1 root root 1553 Jan 31 2015 ElasticSearch-ayarlari.md
-rw-r--r-- 1 root root 837 Jan 31 2015 Elasticsearch-1-dot-4-x-Kurulumu.md
-rw-r--r-- 1 root root 105 Dec 25 2014 Erisim-Bilgileri.md
-rw-r--r-- 1 root root 20430 Nov 5 13:21 Gitlab-Kurulumu.md
-rw-r--r-- 1 root root 4896 Dec 25 2014 HISTORY.md
-rw-r--r-- 1 root root 445 Nov 4 11:40 Home.md
-rw-r--r-- 1 root root 600 Jan 31 2015 MongoDB-Kurulumu.md
-rw-r--r-- 1 root root 9316 Dec 25 2014 README.md
-rw-r--r-- 1 root root 274 Dec 25 2014 Roketsan-Router.md
-rw-r--r-- 1 root root 140 Jan 21 2015 TSPB-Routing.md
exec ile diğer linux sistem komutlarını da çalıştırabilirsiniz, bash doğası gereği size bir shell sunacak. Yukarıdaki md dosyaları yoktan var olmuyor tabiki, ben kendi dokümanlarımı gollum’da tutmak istediğim için
kurulum esnasında oluşturduğum wiki git deposunun içine daha önceden yazdığım dokümanları kopyalamıştım.
Sanal makineler falan tarih olacak bir kaç yıla, valla bak. Demedi demeyin. Buraya da yazıyorum. 🙂
Bunun dışında daha fazla troubleshooting vermeyeceğim, birileri denerse ve sorunla karşılaşırsa bu blog-post’a comment olarak girebilir.
Hepsi bu kadar!
Aydın Bey bu yararlı paylaşımınız için size minnetlerimi sunarım, keşke herkes sizin gibi yaptığı işi benimseyip bilginin paylaştıkça anlam kazandığı gerçeğini görebilse. saygılar
Teşekkür ederim Aykut bey. Özgür Yazılım Felsefesi de tam olarak bunu gerektiriyor zaten.
Saygılar benden. 🙂