Table of contents
Open Table of contents
1. Persiapan Repository (Setting docker-compose file dan Dockerfile)
Dalam tutorial kali ini kita bakal pakai contoh repository mern-app berikut: Mern Boilerplate
Dalam repo tersebut terdapat 2 folder yaitu backend dan frontend, dalam folder backend, berisi kodingan REST-API menggunakan express, sedangkan di frontend berisikan kodingan reactjs.
Pertama-tama kita perlu membuat Dockerfile (tanpa extension) pada root repository:
Penjelasan singkat tentang apa itu Dockerfile. Dockerfile adalah tempat untuk menaruh rangkaian script yang akan kita jalankan pada container docker yang akan kita buat untuk aplikasi kita. Berikut adalah script Dockerfile yang kita butuhkan:
FROM node:16-alpine
WORKDIR /app
COPY ./package.json ./package.json
COPY ./backend ./backend
COPY ./frontend ./frontend
RUN npm install
RUN npm install --prefix frontend
RUN npm run build --prefix frontend
EXPOSE 8000
CMD ["npm","start"]
Akan saya jelaskan satu persatu script di atas.
- Untuk script pertama yaitu FROM adalah script untuk mendefinisikan image apa yang akan dibutuhkan / dipakai oleh aplikasi kita, dalam hal ini kita memakai image node 16 versi alphine. List image yang bisa digunakan bisa kalian check di docker hub: node - Official Image
- Script kedua WORKDIR, script ini berfungsi untuk membuat direktori pada container yang akan kita buat, direktori untuk menyimpan file-file project kita, bisa diisi terserah kalian, pada kasus kali ini kita menamai folder tersebut /app.
- Script selanjutnya adalah COPY, script ini berfungsi untuk meng-copy file dan direktori dari repository kita dan menaruhnya di container docker yang akan kita buat, dalam hal ini kita perlu meng-copy folder /backend /frontend dan file package.json.
- Selanjutnya RUN adalah script yang perlu kita jalankan nanti di container saat container pertama kali dibuat, script ini sama persis dengan yang biasa kita gunakan saat ingin menjalankan aplikasi kita seperti npm install dan npm run build.
- EXPOSE adalah script untuk menentukan di PORT berapa app kita akan berjalan, port yang diexpose ke luar (yang bisa kita akses).
- Terakhir adalah CMD, ini fungsinya mirip dengan RUN namun CMD akan dijalankan setiap kita menjalankan container, dalam hal ini yaitu npm start.
Kurang lebih seperti itu susuan Dockerfile kita, sudah selesai. Sekarang kita akan beralih membuat docker-compose file. Apa itu docker-compose file? docker-compose berfungsi untuk mengeksekusi installasi image beserta configurasinya. Singkatnya, si docker-compose inilah yang akan membuat container docker, sedangkan Dockerfile tadi adalah file configurasi image yang akan kita buat.
Buat file dengan nama docker-compose.yml yang berada pada posisi root folder project. Berikut isi dari docker-compose file:
networks:
local:
external: true
services:
mernapp:
build:
context: .
dockerfile: Dockerfile
ports:
- 8000:8000
depends_on:
- mongo
networks:
- local
environment:
NODE_ENV: production
PORT: 8000
JWT_SECRET: cc7e0d44fd473002f1c42166567ds59001140ec6389b7353f8088f2f59sd32
MONGO_URL: mongodb://mongo/mern_boilerplate
mongo:
image: "mongo:4.4"
networks:
- local
ports:
- 27017:27017
volumes:
- ../mongodb-data:/data
akan saya jelaskan singkat tentang script di atas. yang pertama adalah networks, menentukan network apa yang akan kita pakai, di sini saya memakai network bernama local yang akan dapat diakses secara external. Setelah itu kita mendefinisikan services yang akan kita buat. Terdapat 2 service yang kita butuhkan, pertama adalah service mernapp kita, dan mongodb sebagai database.
Terdapat perbedaan yang jelas dari script 2 service di atas, di service mongo, kita langsung mendefinisikan image: “mongo:4.4” sedangkan di service mernapp kita tidak memakai image, tapi build, ini karena kita tidak memakai image yang disediakan docker hub secara langsung, melainkan kita mensettingnya terlebih dulu di Dockerfile kita, jadi kita perlu mem-build ulang image node:16-alphine yang kita pakai.
2. Create VM di VPS Service (ex: DigitalOcean)
Login ke penyedia layanan VPS kalian, di sini saya memakai DigitalOcean. Setelah login ke dashboard, pilih Create Droplet (VM), sesuaikan setting spesifikasi VM sesuai yang kalian mau, setelah itu tekan Create Droplet.
Setelah membuat Droplet / VM, kalian akan mendapatkan ip public, ip inilah yang akan kita pakai untuk mengakses VM tersebut via ssh.
3. Setting DNS di Cloudflare
Untuk DNS managementnya kita akan memakai Cloudflare, Cloudflare ini selain untuk DNS management, kita juga bisa memanfaatkannya sebagai CDN, yang akan membantu site kita bisa diakses lebih cepat menggunakan caching data. Cloudflare juga menyedia SSL certification, namun pada tutorial kali ini, kita hanya akan fokus pada DNS managementnya saja.
Silahkan login ke akun cloudflare kalian di https://dash.cloudflare.com/ jika belum memiliki akun, silahkan daftar terlebih dahulu. Oh iya, pastikan juga untuk punya domain nya terlebih dahulu ya, karena di tutorial ini, berasumsi kalian sudah punya domain.
Setelah login di cloudflare, kalian bisa menambahkan domain kalian dengan cara klik tombol add site.
Setelah berhasil add site, step selanjutnya yang perlu kalian lakukan adalah mengganti name server domain kalian ke name server cloudflare. Caranya adalah kalian login ke website penyedia domain kalian, lalu ubah name server domain kalian di sana, ini adalah contoh cara mengubahnya jika kalian beli domainnya di idwebhost:
isikan name server cloudflare yang tertera di halaman DNS Cloudflare seperti berikut:
Setelah selesai mengubah nameserver, kita akan menambahkan record pada DNS Cloudflare, buka menu berikut:
Tambahkan record dengan cara klik add record isi type nya dengan A, dan name nya isi dengan @ untuk mengarah ke domain default kalian, lalu isi IPv4 Address dengan IP Droplet / VM yang telah kalian buat tadi, lalu save.
pada kasus kali ini, kita akan deploy mernapp kita ke subdomain, bukan di domain utama, maka dari itu, kita perlu untuk menambah record baru lagi, isi type dengan CNAME, isi name dengan nama subdomain yang diinginkan, lalu isi target dengan @, lalu save.
Oke. setting DNS Cloudflare sudah selesai, kita akan beralih ke setting server kita.
4. login VM via SSH
Selanjutnya kita akan mengakses VM / Droplet kita via ssh, untuk di windows bisa memakai putty untuk mengakses ssh, namun kali ini saya memakai linux, jadi bisa langsung menggunakan command ssh di terminal seperti di bawah ini
masukkan password yang sudah kalian setting tadi, lalu kita bisa login ke VM.
5. Installasi Docker
Jalankan script berikut untuk menginstall docker:
sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
Jalankan semua script di atas satu-persatu, dan docker akan terinstall. Untuk info lebih detail kalian bisa melihat tutorial installasi docker di sini: https://docs.docker.com/engine/install/ubuntu/
6. installasi Nginx
Sekarang kita perlu menginstall Nginx, berikut langkah-langkahnya:
sudo apt update
sudo apt install nginx
setelah menginstall nginx, kita perlu settting firewall menggunakan ufw, jalankan script berikut:
sudo ufw allow 'Nginx HTTP'
sudo ufw allow ssh
dengan ini, web server kita akan bisa diakses melalui http dan juga ssh, jangan melewatkan proses ini, karena jika kalian melewatkan proses ini, maka kalian tidak akan bisa mengakses VM kalian lagi via SSH setelah menginstall nginx (seperti saya 🤣).
Setelah itu, kalian bisa mengecek status web server kalian apakah sudah berjalan atau belum dengan cara jalankan command berikut
systemctl status nginx
jika sudah berjalan, maka akan muncul status seperti ini:
jika belum aktif, kalian perlu menjalankan command berikut:
systemctl start nginx
Saat ini kalian seharusnya sudah bisa mengakses ip VM kalian di browser, maka akan muncul seperti ini:
7. Git Clone Repo
Sekarang kita akan membuat folder untuk subdomain kita:
sudo mkdir -p /var/www/mern-build-test.ferigalung.com/html
Setelah itu, atur permissionnya seperti ini:
sudo chown -R $USER:$USER /var/www/mern-build-test.ferigalung.com/html
sudo chmod -R 755 /var/www/mern-build-test.ferigalung.com
lalu change directory ke folder html yang berada di dalam folder subdomain
cd /var/www/mern-build-test.ferigalung.com**/**html
setelah itu, clone repo yang sudah kalian siapkan tadi
git clone https://github.com/ferigalung/mern-boilerplate.git .
8. Docker Compose Up
setelah itu, jalankan docker compose up untuk mem-build image dan membuat container docker
docker compose up -d
Jika terdapat error network, maka perlu membuat network terlebih dahulu, lalu jalankan docker compose up lagi
docker network create local
Ok, sampai di sini seharusnya kita sudah bisa mengakses aplikasi kita melalui IP dan port yang sudah kita setting di docker-compose file kita, silahkan coba buka di browser kalian
Oke, panjang banget ya prosesnya, dan sampe sekarang mungkin kalian bertanya-tanya, kog aksesnya masih pake IP address, engga pakai subdomain? nah, masih ada proses terakhir yang bakal bikin kita bisa akses lewat subdomain, sabar yah.
9. Setting Nginx Config dan Proxypass
Untuk menghindari kemungkinan masalah memori yang dapat timbul dari penambahan name server, perlu untuk menyesuaikan satu value di file /etc/nginx/nginx.conf. Buka file:
sudo nano /etc/nginx/nginx.conf
lalu hapus # di depan line server_names_hash_bucket_size
...
http {
...
server_names_hash_bucket_size 64;
...
}
...
setelah itu kita membuat server block sesuai nama domain/subdomain kita seperti berikut:
sudo nano /etc/nginx/sites-available/mern-build-test.ferigalung.com
paste script di bawah ini, lalu tekan Ctrl+X, ketik y, lalu enter
server {
listen 80;
listen [::]:80;
root /var/www/mern-build-test.ferigalung.com/html;
index index.html index.htm index.nginx-debian.html;
server_name mern-build-test.ferigalung.com www.mern-build-test.ferigalung.com;
location / {
proxy_pass http://127.0.0.1:8000;
}
}
script di atas berfungsi supaya ketika seseorang mengakses subdomain kita, maka dia akan diarahkan ke port 8000 yaitu port dari docker container kita, sama seperti mengarahkannya ke IP yang barusan kita akses http://165.22.249.96:8000
Setelah itu, link file server block tadi ke folder site-enabled, dengan cara jalankan command ini:
sudo ln -s /etc/nginx/sites-available/mern-build-test.ferigalung.com /etc/nginx/sites-enabled/
setelah semuanya selesai, restart server nginx kita:
sudo systemctl restart nginx
Selesai, sekarang coba akses aplikasi kalian menggunakan subdomain
Seperti itulah proses deploy aplikasi dari 0 sampai selesai menggunakan docker, nginx, dan juga cloudflare di VPS, selamat mencoba 😁.