Docker
Docker
Docker 1
Böylece, her makinede tutarlı test sonuçları elde edilir ve sürüm öncesi sorunlar
minimuma indirilir.
Docker 2
Verimlilik: Geliştirme, test ve dağıtım süreçleri kolaylaşır ve
otomatikleştirilebilir.
Docker 3
[Link] : Veri Tabanı : mongoDB
İlerleyen süreçte ExpressJs ‘in en son sürümüne geçmeniz gerekiyor fakat en son
sürüme geçerseniz mongoDB ‘de ki bazı alanlarınızı da güncellemek zorunda
kalacaksınız. Çünkü mongoDB, express’in eski versiyonunda çalışan bazı
özellikleri barındırıyor. İşte burada Docker ‘ın en önemli özelliği devreye giriyor. Siz
container yapısında bu teknolojileri çalıştırdığınız için şöyle diyebilirsiniz :
[Link] ‘ım da ki mongoDB, ExpressJS ‘in eski sürümde çalışsın, [Link]
‘da ki ExpressJS en son sürüme güncellensin. Birbirinden izole şekilde çalışan
container ‘lar ile artık bir güncellemenin peşinden sürüklenen diğer
güncellemelerden kurtulmuş olursunuz.
Ayrı bir işletim sistemine gerek duymaksınız çalışan Docker container ları bu
nedenle sanal makinelere göre daha az RAM, CPU, Depolama ile daha
performanslı işlemler gerçekleştirebilir.
Docker Image
Uygulamanızın ve onun çalışması için gereken her şeyin (kod, runtime,
kütüphaneler, bağımlılıklar, ayarlar) paketlenmiş halidir. Bir Docker image, bir ya da
daha fazla katmandan oluşur ve bu katmanlar bir araya gelerek uygulamanızın
çalıştığı container'ı oluşturur. Docker image'ları, belirli bir işletim sistemi, yazılım
sürümleri ve uygulama yapılandırmaları dahil olmak üzere her şeyin tam bir anlık
görüntüsünü içerir.
Docker 4
Docker Image: Bir Docker container oluşturmak için kullanılan salt-okunur bir
şablondur. Image'lar, bir uygulamanın ve onun bağımlılıklarının anlık
görüntüsünü temsil eder. Docker image'ları, bir Dockerfile kullanarak
oluşturulur.
Image ‘leri bir template olarak düşünebiliriz. Günün sonunda container ‘ların nasıl
çalışacağı, hangi adımları izleyeceğini ve hangi şekle bürüneceğini planlayan
yapılardır. Kabaca bir React uygulamasında kaynak kodlarına Docker Image dersek
sunucuya yüklenmiş ve çalıştırılmış, bir domain ile giriş yaptığımızda karşımıza
çıkan projenin çalışır son haline ile Docker Container diyebiliriz.
# Bağımlılıkları yükle
RUN yarn install
Docker 5
# Uygulamanın dinleyeceği portu belirt
EXPOSE 3000
Docker Hub
Docker imajlarını depolamak, paylaşmak ve dağıtmak için kullanılan merkezi bir
platformdur. Docker Hub, geliştiricilerin ve ekiplerin kendi Docker imajlarını
oluşturup diğer kullanıcılarla paylaşmasını sağlar. Aynı zamanda, popüler yazılım
imajlarının resmi sürümlerini bulabileceğiniz bir kaynaktır. Birçok popüler yazılımın
(örneğin, MySQL, Nginx, Redis) resmi Docker imajları Docker Hub'da bulunabilir.
npm ‘de nasıl geliştiriciler paket oluşturur ve yayınlar, ardından biz bu paketleri
yarn add, npm install .vb komutlar kullanarak kendi bilgisayarımıza indirip entegre
ediyorsak benzer bir mantıkla DockerHub ‘da geliştiriciler tarafından yayınlanan
Docker image deposu diyebiliriz.
Kitaplık Örneği
Kitaplık Metaforu:
Mantığı:
1. Kitap Oluşturma (Docker İmajı Oluşturma): Bir yazar (geliştirici), bir kitap
(Docker imajı) yazar.
Docker 6
Örnek:
Yazar: Alice
Alice, "[Link] ile Web Geliştirme" adlı kitabını (Docker imajını) yazar ve bu kitabı
(Docker imajını) Docker Hub'da (dijital kitaplıkta) paylaşır. Bob ve diğer
geliştiriciler, bu kitabı (Docker imajını) Docker Hub'dan indirip kullanabilirler.
Docker pull
İlgili image ‘in yükleme dosyasını Docker Hub ‘dan indirir. Docker Hub sitesinden
tüm image lere göz atabilirsin.
Docker 7
docker images
Docker run
Docker ps
Çalışan container ‘ları listeler.
docker ps
docker container ls
Docker ps -a
Geçmişte çalıştırılmış tüm container ‘ları listeler.
docker ps -a
Docker container ls -a
Docker ps -a ile aynıdır, geçmiş çalıştırılan container ları listeler.
docker container ls -a
Docker 8
💡 Docker ‘da çalıştırılan her container rastgele isimlendirilir ve her kapatılıp
açılmada bu isim değişir. docker run ubuntu ile container ‘ı çalıştırıp
docker ps ile çalışan container ‘ın ismini görüntüleyebilirsin.
Container isimlendirmek
💡 Her docker run işleminde aslında bir tema oluştururuz. Bu container ‘ları
isimlendirmeden çalıştırmak aslında geçici tema oluşturmak demektir.
Tekrar aynı tema ile bir container çalıştırmak istediğimizde bir daha aynı
kod satırını yazmamız gerekir.
Docker 9
💡 // tüm kullanılmayan image ve container 'ları siler
docker system prune -a
Docker start
Bir container ‘ı çalıştırmak için kullanılır.
Docker stop
Çalışan container ‘ın çalışmasını durdurmak için kullanılır
💡 docker run ile oluşturulan her container bellek ‘de yer kaplar.
Kullanılmayan container ‘ın silinmesi gerekir.
Docker 10
docker container prune -f
Docker Hub ile bir image ‘nin belirli bir sürümünü indirmek (tags)
Tag ‘ları yani versiyonları Docker Hub sayfasından öğrenebiliriz. Eğer bir sürüm
belirtmezsek latest olan en son sürümü indirir.
Detach Mode
Konsolda bir docker image ‘i çalıştırdığımızda, image çalışır ve o konsol ‘da
herhangi bir işlem yapmamız bloklanır, işlem yapabilmek için Ctrl + C yaparak
çalışmayı durdurmamız gerekir. Detach mode ile çalıştırdığımız image ‘e
arkaplanda çalışmasını söylersek konsol ‘da işlem yapmaya devam edebiliriz.
Docker 11
💡 Sürekli olarak konsola log atan container yapılarının arkaplanda (detach
mode) çalıştırılması daha uygundur, çünkü sürekli log atmak bellekte yer
kaplar belleğin şişmesine neden olabilir.
Attach Mode
Detach mode ile arkaplanda çalışmaya zorlanan container ‘ı attach mode ile
tekrardan konsola loglaması gerektiğini belirtmek içindir.
// veya
docker container logs {container_name veya id}
Docker run ile çalıştırılan uygulama standart giriş akışını (STDIN) terminale
bağlamaz. Varsayılan olarak standart çıkış (STDOUT) ve standart hata (STDERR)
akışlarını bağlar ve biz sadece çıktı ve hata loglarını konsolda görebiliriz. Eğer
uygulama bir giriş bekliyor ise (Örn 28. satırda bir şifre girdisi bekliyor), imajı -i
komutu ile çalıştırarak standart giriş akışını terminale bağlayıp artık giriş
yapabiliriz.
// Aşağıdaki metot bizden bir yeni parola girdisi bekler ama biz
// için girdi veremeyiz ve container çalışıp hemen ardından hata
docker run ubuntu passwd root
Docker 12
Terminal (-t)
Docker network
mongo-server isminde mongo imajı ile yenir bir container oluşturdum ve yukarıda
oluştruduğum custom-network üzerinden çalışmasını belirttim.
history
Geçmişte çalıştırdığın komut satırlarını listeler.
history
Docker 13
// nodejs 'in istediğim versiyonunu indiriyorum
curl -sL [Link] | bash
Dockerfile
İmaj oluşturmak amacıyla kullanılan bir betik dosyasıdır. Dockerfile'da çeşitli
komutlar kullanılarak, bir baz imajdan başlayarak, gerekli yazılım paketleri yüklenir,
dosyalar kopyalanır, ortam değişkenleri tanımlanır ve çalıştırılacak komutlar
belirtilir. Terminalde çalıştırdığımız komutları bir Dockerfile dosyasına döküp,
süreci otomatikleştiriyoruz.
Docker 14
Dockerfile dosyası oluşturmadan önce temel komutları görelim , zaten biliyorsan
Dockerfile örneğine geçebilirsin.
FROM
RUN
komutlarını çalıştırır.
COPY
dizinine kopyalar.
ADD
WORKDIR
Docker 15
CMD
ENTRYPOINT
ENV
EXPOSE
VOLUME
Docker 16
// terminalde sırası ile komutlarımı çalıştırıyorum
// ubuntu güncelleniyor, curl indiriyorum, curl ile nodejs indir
RUN apt-get update
RUN apt-get install curl -y
RUN curl -sL [Link] | bash
RUN apt-get install nodejs -y
Docker 17
Layer
Docker layer (katman), Docker imajlarının oluşturulmasında kullanılan bir
mekanizmadır. Her Docker imajı, bir dizi katmandan oluşur ve her katman bir
önceki katmanın üzerine eklenir.
Örneğin run apt-get update komutu bir kere çalıştırdığında bunun için bir layer
oluşturur ve cache ‘de saklar. Tekrar aynı komutu çalıştırdığında bu işlemi tekrar
etmek yerine cache ‘den alır ve o adamı atlayarak bir sonraki adıma geçer. Bu
sayede çok daha hızlı işlemleri gerçekletirir.
alpine
Docker imajları için kullanılan hafif ve minimal bir Linux dağıtımı olan Alpine Linux'u
ifade eder. Standart bir Ubuntu imajı 100MB'tan büyük olabilirken, bir Alpine Linux
imajı genellikle 5MB civarındadır. Bu, daha hızlı indirme ve daha az disk kullanımı
anlamına gelir.
💡 Docker hub ‘dan edineceğin imajın açıklama sayfasında alpine, slim gibi
taglar ile hazırlanmış Dokerfile sürümlerini görebilirsin.
FROM node
WORKDIR /opt/node-app
COPY . .
ENV PORT=8000
CMD [ "node","[Link]"]
Çalıştığı zaman yaklaşık 1GB ‘a yakın bi dosya boyutunu ulaşır. Fakat alpine linux
tabanlı bir imaj kullanmak boyutu ve hızı kat ve kat arttırır. Çünkü daha az
bağımlılık ve daha az ek yazılım bileşeni içerir.
Docker 18
ENV PORT=8000
CMD [ "node","[Link]"]
Nodejs uygulaması
// [Link]
const express = require("express");
const app = express();
const PORT = [Link] || 3000;
[Link](PORT, () => {
[Link](`Server ${PORT} portunda dinleniyor.`);
});
// Dockerfile
FROM node:14-slim
WORKDIR /opt/node-server
COPY . .
RUN npm install
CMD [ "node","[Link]" ]
.dokerignore
node_modules
Docker 19
// ilk port localhost:... ile erişeceğim port, ikinci port app.j
// node serverimi dinlediğim port.
docker run -p 3000:3000 simple-node-server
FROM node:14-slim
WORKDIR /opt/node-server
COPY . .
EXPOSE 3000 // 3000. portta çalışacağını belirtiyoruz.
RUN npm install
CMD [ "node","[Link]" ]
// [Link]
const Mongoose = require("mongoose");
[Link] = {
TodoModel: [Link]("todo", todoSchema),
};
//[Link]
"dependencies": {
Docker 20
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"mongoose": "^5.11.13"
},
"devDependencies": {
"nodemon": "^2.0.7"
}
// Dockerfile
FROM node:16-slim
WORKDIR /opt/node-todo-app
COPY . .
EXPOSE 3000
RUN yarn install
CMD [ "node","[Link]" ]
[Link]
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
const { TodoModel } = require("./TodoModel");
const Mongoose = require("mongoose");
const PORT = [Link] || 3000;
[Link]([Link]());
[Link]([Link]({ extended: true }));
[Link](cors());
Docker 21
});
todo
.save()
.then((savedTodo) => [Link](200).json(savedTodo))
.catch((e) => [Link](400).json(e));
});
Önce mongodb container ‘ımı ayağa kaldırıyorum. Mongo imajını Docker Hub ‘dan
ediniyorum. Loglara ihtiyacım olmadığı için detech mode ‘da çalıştırıyorum.
Nodejs imajım node-server adında hazır ama container ‘ı çalıştırmadan önce diğer
container olan mongo-server ile iletişim kurabilmesi için --link ile bir alias
belirtmem gerekiyor.
Docker 22
📌 Önemli : Birden fazla container arası iletişim sağlamak için, iletişime
geçecek container ‘ı çalıştırırken link belirmem gerekiyor. --link için ;
ilk değer iletişime geçeceğim container adı
ikinci değer ise bu container ‘ı içeride hangi isimde kullanacağım.
CMD override
Örneğin Dockerfile dosyanızda CMD [”sleep”,”3”] şeklinde ibare mevcut. Buda
ubuntu ‘yu 3 saniye uyutuyor. eğer komut satırında container ‘ı ayağa kaldırırken
container adından sonra bir komut belirtirsen docker bunu Dockerfile ‘ında CMD
olsa bile ezip, CMD yerine kullanacaktır.
ENTRYPOINT
Docker imajının veya konteynerinin çalıştırıldığında varsayılan olarak başlatacağı
ana işlemi belirlemek için kullanılır.
Docker 23
CMD komutu bir executable yani çalıştırılabilir bir metot ve ikinci parametre olarak
isteğe bağlı bir arguman (girdi) alır. Örneğin
CMD ["node","[Link]"]
// ENTRYPOINT olmadan
CMD ["node","[Link]"]
// ENTRYPOINT ile
ENTRYPOINT ["node"]
CMD ["[Link]"]
// node [Link] çalışır
// Dockerfile
FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]
// terminal
docker build -t ubuntu-test . // imajı önce build ediyorum
Docker 24
// sleep 10 çalışacak, eğer 10 değerini göndermez isem CMD 'deki
docker run ubuntu-test 10
Python app
// [Link]
from flask import Flask
server = Flask(__name__)
@[Link]("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
[Link](host='[Link]')
// [Link]
Flask
Jinja2==3.0.3
//Dockerfile
FROM python:3.8-slim
Docker 25
// localimdeki [Link] dosyamı WORKDIR ile belirttiğim
// içerisine kopyalıyorum
COPY [Link] .
[Link]
Docker Compose
Docker tarafından sunulan ve çoklu container uygulamalarını tanımlamak,
çalıştırmak ve yönetmek için kullanılan bir araçtır. Uygulamanızın servislerini (web
sunucusu, veritabanı, önbellek vb.) bir YAML dosyasında tanımlayabilir ve bu
servisleri tek bir komutla oluşturabilir ve çalıştırabilirsiniz.
Docker Compose ile, bir komutla tüm uygulamanızı başlatabilir, durdurabilir,
yeniden başlatabilir veya güncelleyebilirsiniz.
Docker 26
// [Link]
{key}: {value}
// eğer bir işlemin alt işlemleri varsa alt satırda bir tab bıra
services:
web:
image: node:14-alpine
command: npm start
# [Link]
version: "3.8"
...
# [Link]
version: "3.8"
servicess:
service-test-1:
service-test-2:
...
Docker 27
version: '3.8'
services:
web:
image: node:14-alpine
command: npm start
ports:
- "3000:3000"
volumes:
- ./app:/app
environment:
MONGO_URL: mongodb://db:27017/mydatabase
depends_on:
- db
db:
image: mongo:latest
ports:
- "27017:27017"
volumes:
- mongodb_data:/data/db
volumes:
mongodb_data:
image: Docker container'ı için kullanılacak olan Docker imajını belirtir. Örneğin,
image: node:14-alpine [Link]'in 14-alpine sürümünü kullanır.
Docker 28
command: Docker container başlatıldığında çalıştırılacak komutu belirtir.
Örneğin, command: npm start bir [Link] uygulamasını başlatmak için kullanılır.
ports: Host makinedeki bir portu Docker container içindeki bir porta bağlar.
Örneğin, ports: - "3000:3000" host 3000 portunu Docker container 3000 porta
yönlendirir.
volumes: Host makinesindeki bir dizini Docker container içindeki bir dizine
bağlar. Örneğin, volumes: - ./app:/app hosttaki "./app" dizini Docker
containerdaki "/app" dizinine bağlar.
// [Link]
const express = require("express");
const app = express();
const PORT = [Link] || 3000;
[Link](PORT, () => {
[Link](`Example app listening at [Link]
});
// Dockerfile
FROM node:14-slim
Docker 29
WORKDIR /opt/node-server
COPY . .
RUN npm install
CMD ["node", "[Link]"]
# [Link]
version: "3.8"
services:
node-app:
# Container isimlendirmek isteğe bağlıdır, isim vermez i
# ismi ile kendi otomatik bir isim oluşturur.
container_name: node-app-container
# uygulamamda Dockerfile dosyam olduğu için custom bir i
# build . ile mevcut uygulamamdaki Dockerfile dosyası il
# bu sayade mevcut Dockerfile dosyamı kullanmış oluyorum
build: .
# birden fazla port tanımı yapabiliriz.
ports:
- 3000:3000
Docker 30
// terminalden proje dizinene geçiyorum
docker-compose down
# [Link]
version: "3.4"
services:
mongodb:
image: mongo
ports:
- 27017:27017
# mongodb servisimle aynı hizada volume tanımlıyorum. ilk de
# ikinci değer barındıracağım yer. (mongodb default olarak /
volumes:
- todo-app-data:/data/db
# yukarıda tanımladığım volumelerin isimlerini en dış scope 'da
volumes:
todo-app-data:
# [Link]
version: '3.8'
Docker 31
services:
node-app:
image: node:14-alpine
command: npm start
ports:
- "3000:3000"
volumes:
- ./app:/app
environment:
MONGO_URL: mongodb://db:27017/mydatabase
depends_on:
- mongodb # node-app çalıştırılmadan önce mongodb adlı con
mongodb:
image: mongo:latest
ports:
- "27017:27017"
volumes:
- mongodb_data:/data/db
volumes:
Docker 32
// yes diyerek adımları onaylıyorum ve parolamı giriyorum.
// artık uzak sunucumun terminaline bağlandım.
Docker 33
// htop indiriyoruz. daha okunaklı verileri listeler.
sudo apt install htop
// terminale yazıyoruz
htop
Docker 34
// ngnix yoksa yükleyin
apt install nginx
unlink /etc/nginx/sites-enabled/default
Ardından gerekli düzenlemeleri yaptıktan sonra Ctrt + C ile instert modu kapat.
server_name alanına domain adresinin ismini gir ve ardından [Link] ‘den sonra
uygulamanı çalıştırdığın portu belirt.
server {
listen 80;
listen [::]:80;
server_name [Link]; // domain ismi
server_name_in_redirect off;
access_log /var/log/nginx/[Link];
error_log /var/log/nginx/[Link];
location / {
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwar
proxy_set_header Host $host;
proxy_pass [Link] // dışarıya aktar
Docker 35
}
}
ln -s /etc/nginx/sites-available/[Link] /etc/nginx/s
nginx -t
systemctl restart nginx
systemctl status nginx
Docker 36