Docker ile Mean Stack Oluşturmak
MEAN
ifadesini mutlaka duymuşsunuzdur. MongoDB
, Express
, Angular
ve Node.JS
'in baş harflerinin birleşmesi ile oluşuyor efenim.
Zaman zaman bu stack'i kullanarak projelerimizi geliştiriyoruz. Geliştiriyoruz, geliştiriyoruz da geliştirme ortamını hazırlarken çok çileler çekiyoruz. İşte bu makalede bu çektiklerimizden kurtulmak adına bir Docker
container'ı hazırlayacağız. Bu container sayesinde tek komutla MEAN
stack üzerinde geliştirme yapmaya başlayabileceğiz.
Öncelikle bir ayıp edip daha önce Docker
'ı kurmadıysak hemen şuradan kuralım. Kurulumu tamamladığımıza inanıyorsak şu komutla emin olalım.
docker -v
Docker version 17.12.0-ce, build c97c6d6
Başlayalım
Herhangi dizinde root dizininizi oluşturun. Örneğin ben, masaüstündeki app
klasörüne docker-ile-mean-stack-olusturmak
adıyla bir dizin oluşturuyorum. Tüm çalışmalarımı bu dizin altında yapacağım.
mkdir ~/Desktop/app/docker-ile-mean-stack-olusturmak
cd ~/Desktop/app/docker-ile-mean-stack-olusturmak
1.Angular Client Kurulumu
Angular'ın komut satırı arayüzü bilgisayarınızda kurulu değilse aşağıdaki komut ile kuralım.
npm install -g @angular/cli
Angular client için root folder'ı daha önce oluşturduğumuz docker-ile-mean-stack-olusturmak
dizininin içine oluşturalım.
mkdir angular-client
cd angular-client
Angular projemizi, oluşturmuş olduğumuz angular-client
klasörüne kuralım.
ng new my-app --directory ./
- my-app parametresi proje adını belirler. Siz istediğinizi yazabilirsiniz.
- --directory kısmı ise proje dosyalarının nereye kurulacağını belirler. Biz " ./ " ifadesi ile aynı dizine kurmasını istedik.
Her şey tamamsa, Angular projesini ayağa kaldıralım.
ng serve
http://localhost:4200 adresine gidelim. Her şey yolunda gittiyse aşağıdaki gibi bir ekranla karşılaşacaksınız.
Şimdi Ctrl+C
ile bu çalışmayı durdurun.
Angular Client Dockerizing
Angular uygulamamızı kendi bilgisayarımızda çalıştırıyoruz sorun yok evet. Şimdi bu uygulamayı kendi bilgisayarımızdan değil de bir docker container'ı aracılığı ile nasıl çalıştıracağımıza bakalım.
angular-client
klasörunde Dockerfile
adında bir dosya oluşturun ve içeriğini şöyle değiştirin.
# Dockerhub üzerinden resmi Node 8 image'ını temel alarak bir image oluştur
FROM node:8
# Uygulamamızın bulunacağı klasörü oluştur
RUN mkdir -p /var/www/app
# Komutlarımızın çalıştırılacağı dizini seç
WORKDIR /var/www/app
# package.json dosyamızı çalışma dizinine kopyala
COPY package.json /var/www/app
# Bağımlılıkları kur
RUN npm install
# Tüm proje dosyalarını docker image'ına kopyala
COPY . /var/www/app
# Uygulamanın çalışacağı port
EXPOSE 4200
# Projeyi ayağa kaldıracak komutu çalıştır
CMD ["npm", "start"]
Docker Ignore
NPM
bağımlılıklarımızın bulunduğu node_modules
klasörünün docker image'ı içerisine gönderilmesini engellemek için .dockerignore
adında bir dosya oluşturup içeriğini şöyle yapalım.
node_modules/
Start Script'i
Son olarak package.json
dosyasındaki start script'ini şöyle değiştirelim.
"start": "ng serve -H 0.0.0.0"
Docker Build & Run
Aşağıdaki komut ile docker imaj'ımızı build edelim.
docker build -t angular-client:dev .
sonra ayağa kaldıralım
docker run -d --name angular-client -p 4200:4200 angular-client:dev
http://localhost:4200 adresine gidelim. Her şey yolunda gittiyse aşağıdaki gibi bir ekranla karşılaşacaksınız.
Ne değişti? Az önce de bu ekranla karşılaşmıştık? Evet ama diğerini kendi bilgisayarından çalıştırmıştın, burada ise docker container'ın çalışıyor.
Angular container'ı tamam. Geçelim Express'e.
2.Express Server Kurulumu
Express server'ın bulunacağı kök dizini oluşturalım.
cd ~/Desktop/app/docker-ile-mean-stack-olusturmak
mkdir express-server
Express generator'ı kuralım.
sudo npm install -g express-generator
Express projesini oluşturup ayağa kaldıralım.
express .
npm install
http://localhost:3000 adresine gidelim. Her şey yolunda gittiyse aşağıdaki gibi bir ekranla karşılaşacaksınız.
Şimdi Ctrl+C
ile bu çalışmayı durdurun.
Express Server Dockerizing
# Dockerhub üzerinden resmi Node 8 image'ını temel alarak bir image oluştur
FROM node:8
# Uygulamamızın bulunacağı klasörü oluştur
RUN mkdir -p /var/www/app
# Komutlarımızın çalıştırılacağı dizini seç
WORKDIR /var/www/app
# package.json dosyamızı çalışma dizinine kopyala
COPY package.json /var/www/app
# Bağımlılıkları kur
RUN npm install
# nodemon'u kur
RUN npm install -g nodemon
# Tüm proje dosyalarını docker image'ına kopyala
COPY . /var/www/app
# Uygulamanın çalışacağı port
EXPOSE 3000
# Projeyi ayağa kaldıracak komutu çalıştır
CMD ["npm", "start"]
Docker Ignore
NPM
bağımlılıklarımızın bulunduğu node_modules
klasörünün, docker image'ı içerisine gönderilmesini engellemek için .dockerignore
adında bir dosya oluşturup içeriğini şöyle yapalım.
node_modules/
Start Script'i
Son olarak package.json
dosyasındaki start script'ini şöyle değiştirerek nodemon
kullanmak istediğimizi belirtelim.
"start": "nodemon ./bin/www"
Docker Build & Run
Aşağıdaki komut ile docker imaj'ımızı build edelim.
docker build -t express-server:dev .
sonra ayağa kaldıralım
docker run -d --name express-server -p 3000:3000 express-server:dev
http://localhost:3000 adresine gidelim. Her şey yolunda gittiyse aşağıdaki gibi bir ekranla karşılaşacaksınız.
Yine aynı şekilde bir şey değişmemiş gibi görünüyor. Öyle de olması gerekiyor zaten. Yaptığımız değişikliğin amacı, uygulamanın bilgisayarımızdan çalışması yerine docker container'ı üzerinden çalışmasını sağlamaktı. Her şey yolunda efem.
MongoDB container
Bu noktada herhangi dockerfile
oluşturmaya ihtiyacımız yok. Zaten Docker Hub üzerinde bulunan görüntüyü alıp kullanacağız.
docker run -d --name mongodb -p 27017:27017 mongo
Docker Compose
Angular, Express ve MongoDB container'larımızı ayrı ayrı oluşturduk. Peki bunları nasıl bir çatı altında toplayıp birbirleriyle iletişim kurabilir hale getireceğiz? El-cevap: Docker Compose
.
Kurulum için sizi şöyle alalım.
docker-compose -v
docker-compose version 1.11.2, build dfed245
Öncelikle daha önce ayağa kaldırdığımız docker containerlar ile çakışma olmaması için container'larımızı durduralım.
docker stop angular-client && docker stop express-server && docker stop mongodb
Şimdi kök dizinimize gidelim.
cd ~/Desktop/app/docker-ile-mean-stack-olusturmak
Ve burada docker-compose.yml
adlı dosyayı oluşturalım.
touch docker-compose.yml
İçeriğini aşağıdaki gibi yapalım.
version: '2'
services: # Tüm Docker container'larımız 'services' altında olacak
angular: # Angular client için tanımlama
build: angular-client # imaj adı
ports: # port yönlendirmeleri
- '4200:4200'
volumes:
- ./angular-client/:/var/www/app
express: # Express server için tanımlama
build: express-server # imaj adı
ports: # port yönlendirmeleri
- '3000:3000'
volumes:
- ./express-server/:/var/www/app
links:
- database
database: # Mongo server için tanımlama
image: mongo # imaj adı
ports: # port yönlendirmeleri
- '27017:27017'
Yukarıdaki tanımlamada açıklamadığımız iki kısım var; volumes:
Container'ı ayağa kaldırdıktan sonra yazdığınız kodlar neyse öyle kalır. Yani kodunuzda bir değişiklik yaptığınızda bu değişikliği göremezsiniz. Bu durum değiştirmiş olduğunuz dosyanın bilgisayarınızdaki dizinden docker içine kopyalanmadığı için oluşuyor. Volumes
tanımlaması ile bilgisayarınızdaki ve docker içerisindeki proje dizinlerini birbirine eşitlemiş oluyorsunuz. Böylece herhangi değişiklik yaptığınızda bu değişim hemen yansıyor.
links:
Container'ların birbiri ile haberleşebilmesi için kullanılır. Biz burada express-server'ın mongodb'ye de erişebilmesini istediğimiz için bu tanımlamayı yaptık.
Şimdi komutu verelim ve kurduğumuz yapıyı ayağa kaldıralım.
docker-compose up
Komutu çalıştırdıktan sonra şöyle loglar üretiyor.
Eveeeeeeet. Oldu da bitti maşallah.
Teset edelim bakalım. Angular Client şurada http://localhost:4200 Express Server ise şurada http://localhost:3000
Projemizde herhangi bir değişiklik yapmadığımız için yine aynı çıktıyı göreceksiniz.
Şimdi Angular tarafında birkaç değişiklik yapalım bakalım.
angular-client/src/app/app.component.html
<div style="text-align:center">
<h1>Welcome to Docker MEAN Stack</h1>
<img
width="300"
alt="Angular Logo"
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="
/>
<div>
<div class="info">Created by <strong>Mehmet Seven</strong></div>
<a href="https://github.com/meseven" target="_blank">
<img
src="https://assets-cdn.github.com/images/modules/logos_page/GitHub-Mark.png"
class="logo"
/>
@meseven
</a>
<a href="https://twitter.com/mehmeteseven" target="_blank">
<img
src="https://www.sketchappsources.com/resources/source-image/twitterlogo_1x.png"
class="logo"
/>
@mehmeteseven
</a>
</div>
</div>
angular-client/src/app/app.component.css
* {
font-family: Arial;
}
a {
color: #000;
text-decoration: none;
font-weight: 600;
font-size: 13px;
}
.info {
margin-bottom: 25px;
}
.logo {
width: 30px;
vertical-align: middle;
margin-left: 20px;
}
Hemen bakalım: http://localhost:4200
Evet. Cillop!
Node.JS MongoDB Bağlantısı
Sorun yaşayabileceğinizi düşündüğüm bu konuyu da izah etmek istiyorum
express-server/
dizinine gidelim ve
npm install mongoose
diyerek mongoose'u kuralım.
Ardından express-server/app.js
dosyasına şu kodları ekleyelim.
var mongoURI = 'mongodb://database/my-db';
mongoose.connect(mongoURI, function (err) {
if (err) console.log('db connection err');
console.log('mongodb: connected');
});
Evet, bu şekilde veritabanımıza bağlanıyoruz. Ancak şu mongoURI
değişkeninde database
diye bir şey var. Neyin nesidir? Hani docker-compose.yml
dosyamızda database
diye bir tanımlama yapmıştık ya. Ha işte, bu ona karşılık geliyor. En sondaki my-db
ifadesi ise veritabanı adınızı belirtiyor.
Dockerfile dosyalarınızda bir değişiklik yaptığınızda, değişikliklerin yansıması için
docker-compose up --build
komutunu çalıştırabilirsiniz.
Amma bık bık konuştun kardeşim, yeter, bana direkt stack'i ver dersen de hazırladığımız stack şu GitHub reposunda. Alıp tüm projelerinizde gönül rahatlığıyla kullanmaya başlayabilirsiniz. Pull Requestleriniz baş tacımızdır. Bekleriz efem.
Konuyu bir de videolu olarak anlattım.
Kapanış
Mevzu bittiğine göre bana yine yol göründü.
Bu arada, o gemi bir gün gelecek.