Bu yazıda MEVN Stack için Docker kullanımından bahsedeceğim. MEVN Stack; MongoDB, Express.js, Vue.js ve Node.js'in birleşiminden oluşmaktadır. Docker ile ilgili detaylı bilgiye de buradan ulaşabilirsiniz.
Yapacağımız örnek proje ile amacımız, MEVN Stack için geliştirme ortamını bir Docker container'ı üzerinde ayağa kaldırmak olacaktır.
İlk olarak istediğimiz bir dizine gidip mevn-stack-docker adında bir klasör oluşturuyoruz (elbette siz farklı isimde oluşturabilirsiniz):
mkdir mevn-stack-docker
Sonrasında bu klasörün içine gidip backend ve frontend adında iki klasör daha oluşturuyoruz:
cd mevn-stack-docker
mkdir backend
mkdir frontend
Backend
Şimdi de backend klasörü içine giderek Express.js projemizi oluşturuyoruz:
cd backend
express .
Gerekli bağımlılıkları kuruyoruz:
npm install
MongoDB bağlantısı için gerekli paketi kuruyoruz:
npm install mongoose --save
app.js dosyasını açarak MongoDB bağlantısı için gerekli kodları ekliyoruz:
var mongoose = require('mongoose');
var mongoUrl = 'mongodb://database/db';
mongoose.connect(mongoUrl, function(err){
if (err)
console.log('mongodb connection error');
else
console.log('mongodb connected');
});
Projemizi ayağa kaldırıyoruz:
npm start
Şimdi backend projemiz için Docker image'ini oluşturalım. backend dizinindeyken Dockerfile dosyasını oluşturuyoruz:
touch Dockerfile
Node.js projesi için Dockerfile dosyasının nasıl olması gerektiğine dair bilgilere şuradan ulaşabilirsiniz. Biz de bu bilgileri kullanıp üzerinde ufak değişiklikler yapacağız. Dockerfile dosyamız şu şekilde olacak;
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Buradaki kodlar bize şunu ifade ediyor;
- FROM node:14 => Image'i Docker Hub üzerindeki node'un 14 versiyonunu temel alarak oluştur
- WORKDIR /usr/src/app => Projenin bulunacağı ve komutların çalıştırılacağı dizin olarak (çalışma dizini) /usr/src/app dizinini seç
- COPY package*.json ./ => Local'de bulunan package.json ve package-lock.json dosyalarını projenin çalışma dizinine kopyala (./ şeklinde yazılan dizin çalışma dizinini ifade ediyor, yani burada tekrar /usr/src/app yazmamıza gerek yok)
- RUN npm install => Çalışma dizininde npm install komutunu çalıştır
- COPY . . => Local'de bulunan tüm proje dosyalarını çalışma dizinine kopyala
- EXPOSE 3000 => Projenin çalışacağı port olarak 3000'i belirle
- CMD ["npm", "start"] => Çalışma dizininde npm start komutunu çalıştır (RUN kısmından farklı olarak CMD kısmında yazılan komut Container ayakta olduğu sürece çalışmaya devam eder)
Local'de bulunan node_modules klasörünün Docker image'ine gitmesini istemediğimiz için .dockerignore şeklinde bir dosya oluşturuyoruz:
touch .dockerignore
.dockerignore dosyamızın içeriği;
node_modules
Artık backend tarafı için Docker image'ini oluşturabiliriz:
docker build -t backend-for-mevn-stack .
Frontend
Şimdi de frontend klasörü içine giderek Vue.js projemizi oluşturuyoruz:
cd ../frontend
vue create .
Gerekli bağımlılıkları kuruyoruz:
npm install
Projemizi ayağa kaldırıyoruz:
npm run serve
Şimdi frontend projemiz için Docker image'ini oluşturalım. frontend dizinindeyken Dockerfile dosyasını oluşturuyoruz:
touch Dockerfile
Vue.js projesi için Dockerfile dosyasının nasıl olması gerektiğine dair bilgilere şuradan ulaşabilirsiniz. Biz de bu bilgileri kullanıp üzerinde ufak değişiklikler yapacağız. Dockerfile dosyamız şu şekilde olacak (backend tarafında yaptıklarımıza çok benzer);
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD ["npm", "run", "serve"]
Buradaki kodlar bize şunu ifade ediyor;
- FROM node:14 => Image'i Docker Hub üzerindeki node'un 14 versiyonunu temel alarak oluştur
- WORKDIR /usr/src/app => Projenin bulunacağı ve komutların çalıştırılacağı dizin olarak (çalışma dizini) /usr/src/app dizinini seç
- COPY package*.json ./ => Local'de bulunan package.json ve package-lock.json dosyalarını projenin çalışma dizinine kopyala (./ şeklinde yazılan dizin çalışma dizinini ifade ediyor, yani burada tekrar /usr/src/app yazmamıza gerek yok)
- RUN npm install => Çalışma dizininde npm install komutunu çalıştır
- COPY . . => Local'de bulunan tüm proje dosyalarını çalışma dizinine kopyala
- EXPOSE 8080 => Projenin çalışacağı port olarak 8080'i belirle
- CMD ["npm", "run", "serve"] => Çalışma dizininde npm run serve komutunu çalıştır (RUN kısmından farklı olarak CMD kısmında yazılan komut Container ayakta olduğu sürece çalışmaya devam eder)
Local'de bulunan node_modules klasörünün Docker image'ine gitmesini istemediğimiz için .dockerignore şeklinde bir dosya oluşturuyoruz:
touch .dockerignore
.dockerignore dosyamızın içeriği;
node_modules
Artık frontend tarafı için de Docker image'ini oluşturabiliriz:
docker build -t frontend-for-mevn-stack .
Final
Sıra geldi en önemli kısma. Oluşturduğumuz Docker image'lerini birlikte çalışır hale getirip tek bir komutla ayağa kaldıracağız. Bunun için ana dizinimize gidiyoruz ve docker-compose.yml dosyamızı oluşturuyoruz:
cd ..
touch docker-compose.yml
docker-compose.yml dosyamızın içeriği şu şekilde;
version: '2'
services:
backend:
image: backend-for-mevn-stack
ports:
- "3000:3000"
volumes:
- ./backend/:/usr/src/app
links:
- database
database:
image: mongo
ports:
- "27017:27017"
frontend:
image: frontend-for-mevn-stack
ports:
- "8080:8080"
volumes:
- ./frontend/:/usr/src/app
Bu kodlar da bize şunu ifade ediyor;
- backend, database ve frontend adında container'lar oluştur
- backend container'ı için backend-for-mevn-stack image'ini kullan. Çalışacağı port olarak 3000'i belirle (Burada "3000:3000" yazmamızın sebebi şu; soldaki 3000 ile projeye local ortamımızda hangi porttan erişmek istediğimizi, sağdaki 3000 ile projeye Docker üzerinde hangi porttan erişildiğini belirtiyoruz.
- volumes kısmında Local'de bulunan backend dizini ile Docker üzerinde bulunan /usr/src/app dizinini birbirine eşitliyoruz. Böylece yaptığımız değişiklikler Docker'a da yansımış oluyor.
- links kısmında backend container'ının database container'ına bağlı olduğunu belirtiyoruz.
- database container'ı için Docker Hub üzerinde bulunan mongo image'ini kullan. Çalışacağı port olarak 27017'yi belirle
- frontend container'ı için frontend-for-mevn-stack image'ini kullan. Çalışacağı port olarak 8080'i belirle. Yine aynı şekilde volumes kısmında dizinler için eşitlemeyi yaptık.
Son olarak gerekli komutu yazıp container'larımızı ayağa kaldırıyoruz:
docker-compose up
Konsola düşen yazılardan gördüğümüz üzere backend, database ve frontend container'larımız çalışıyor:
Docker Desktop programı üzerinden de container'ların çalışıp çalışmadığını kontrol edebiliriz:
Tarayıcıdan da aynı şekilde çıktılarımıza bakıyoruz: