Setup Deployment ke PaaS

Pada artikel sebelumnya, kita telah mengotomasi proses build dari aplikasi kita. Langkah selanjutnya adalah mendeploy aplikasi kita tersebut ke server yang bisa diakses orang banyak, supaya bisa dilakukan testing oleh manusia.

Ada banyak provider server yang bisa digunakan, ada yang berbayar dan ada yang gratisan. Di antara yang gratisan adalah Openshift dan Heroku. Openshift menyediakan tiga aplikasi yang dapat diinstal tanpa bayar. Sedangkan Heroku membatasi aplikasi gratisnya hanya bisa jalan 18 jam sehari.

Paket gratis ini cukup memadai untuk keperluan testing. Sedangkan nanti bila aplikasi kita sudah digunakan di production, kita bisa menggunakan paket berbayar atau sewa server sendiri baik VPS maupun colocation.

Kedua provider ini mendukung deployment menggunakan git push, jadi kita tidak perlu upload file jar atau war berukuran besar. Cukup push saja source code, nanti dia akan melakukan build dan deployment.

Mari kita mulai …

Heroku

Pada dasarnya, deployment ke Heroku tidak jauh berbeda caranya dengan Openshift. Satu-satunya perbedaan yang cukup signifikan adalah paket gratisan Heroku cuma menyediakan database PostgreSQL. Tidak terlalu merepotkan karena kita menggunakan JPA. Tinggal mengubah tiga baris konfigurasi dan script migrasi database saja.

Struktur Folder Aplikasi

Kita kerjakan dulu script migrasi database. Struktur folder kita yang asli hanyak mengakomodasi satu jenis database. Karena kita ingin ada dua script yang berbeda, kita perlu mengubah foldernya menjadi seperti ini

Struktur Folder Migrasi

Karena perubahan tersebut, kita harus memberi tahu Flyway di mana harus mencari scriptnya. Tambahkan konfigurasi berikut pada file src/main/resources/application.properties

flyway.locations=classpath:db/migration/mysql

Dengan demikian, lokasi default script ada di folder src/main/resources/db/migration/mysql.

Membuat Aplikasi Heroku

Selanjutnya, kita buat aplikasi di Heroku. Login dulu ke Heroku sehingga dapat membuka management console seperti ini

Heroku Dashboard

Klik New App di pojok kanan atas untuk membuat aplikasi baru

New App

Isikan nama aplikasi yang ingin kita buat, misalya aplikasibelajar. Setelah klik OK, kita akan mendapati halaman administrasi aplikasi kita.

Settings

Perhatikan nilai Git URL pada tab Settings. Kita akan membutuhkan nilainya untuk melakukan deployment nanti.

Klik tab Resources, dan tambahkan add-ons PostgreSQL

Add PostgreSQL

Pilih saja paket Hobby yang gratis

Pilih paket

Database PostgreSQL sudah berhasil ditambahkan.

Database PostgreSQL

Klik titik tiga di kanannya untuk mengetahui detail konfigurasinya agar bisa kita pasang di aplikasi.

Daftar Database

Pada halaman di atas terlihat daftar database yang kita miliki, hanya ada satu di sana. Klik nama databasenya untuk melihat detail konfigurasinya

Database Setting

Di situ kita bisa melihat informasi koneksi database. Informasi ini akan kita pasang di konfigurasi aplikasi.

Konfigurasi Aplikasi

Seperti pada Openshift, kita akan membuat konfigurasi terpisah untuk koneksi database Heroku. Tambahkan file application-heroku.properties di dalam folder src/main/resources. Isinya sebagai berikut

spring.datasource.url=jdbc:postgresql://ec2-54-83-198-159.compute-1.amazonaws.com:5432/d1sjircg9n9989
spring.datasource.username=oxfyfvocxwboqn
spring.datasource.password=1fpn8BZHFIKAALWnvLAUAPBByt

flyway.locations=classpath:db/migration/postgresql

Nilai konfigurasi tersebut didapatkan dari setting database yang disediakan Heroku seperti pada screenshot sebelumnya.

Selanjutnya, kita buat script migrasi untuk database PostgreSQL. Sebetulnya tidak terlalu jauh berbeda karena tabel kita cuma satu dan tidak rumit. Berikut isi file V0.0.1.20160222__Skema Awal.sql yang diletakkan di dalam folder src/main/resources/db/migration/postgresql.

-- tabel Product --
create table product (
    id varchar(36) primary key,
    code varchar(10) not null unique,
    name varchar(255) not null,
    price decimal(19,2) not null
);

Terakhir, jangan lupa menambahkan dependensi untuk driver PostgreSQL di pom.xml

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>

Setelah selesai, jangan lupa commit ke repo lokal.

git add .
git commit -m "konfigurasi database PostgreSQL di Heroku"

Deployment

Agar Heroku paham cara menjalankan aplikasi kita, buat sebuah file bernama Procfile. Isinya sebagai berikut

web: java $JAVA_OPTS -jar -Dspring.profiles.active=heroku target/*.jar --server.port=$PORT

File tersebut menunjukkan bahwa aplikasi kita adalah aplikasi web, dijalankan dengan perintah

java -jar target/*.jar -Dspring.profiles.active=heroku

Selebihnya $JAVA_OPTS dan $PORT adalah variabel yang disediakan Heroku.

Deployment dilakukan dengan cara git push, sama seperti Openshift. Untuk itu, kita daftarkan url git Heroku yang telah kita dapatkan di laman administrasi di atas.

git remote add heroku https://git.heroku.com/aplikasibelajar.git

Selanjutnya, kita lakukan deployment

git push heroku master

Sama dengan Openshift, Heroku juga membuatkan file-file template untuk deployment. Kita bisa menimpa repository yang dibuatkan Heroku dengan opsi --force sehingga perintahnya menjadi

git push heroku master --force

Untuk memantau apakah aplikasi kita berhasil terdeploy dengan baik, kita bisa menampilkan log aplikasi dengan cara mengklik tombol titik tiga di kanan atas laman administrasi

View Log Button

Selanjutnya, kita bisa lihat apakah ada error yang terjadi di log aplikasi

Log Aplikasi

Bila semuanya lancar, kita dapat mengakses aplikasi kita dengan URL yang tercantum di laman administrasi

Output Heroku

Openshift

UPDATE !!!

Pada saat artikel ini ditulis, Openshift masih menjalankan versi lama. Saat ini OpenShift versi lama sudah tidak menerima pendaftaran baru. Sedangkan OpenShift versi baru hanya menyediakan akun trial yang aplikasi berikut datanya akan terhapus setelah satu bulan. Oleh karena itu, bagian Openshift ini sudah obsolete dan tidak bisa dijadikan referensi lagi.

Untuk bisa mendeploy ke Openshift, terlebih dulu kita harus mendaftar. Cara pendaftaran sudah pernah saya bahas di artikel sebelumnya. Langsung saja ke websitenya dan mendaftar.

Pembuatan Aplikasi di Openshift

Setelah login, kita akan melihat daftar aplikasi yang kita miliki.

Daftar Aplikasi

Ada tombol Add Application untuk menambah aplikasi baru. Klik tombol tersebut. Kita akan mendapati daftar cartridge (template aplikasi) yang disediakan Openshift untuk mendeploy aplikasi kita. Aplikasi web java biasanya menggunakan cartridge Tomcat, JBoss, atau application server lainnya. Akan tetapi, karena Spring Boot sudah menyertakan (embedded) Tomcat, kita tidak perlu lagi menggunakan cartridge yang sudah ada. Gunakan cartridge DIY (Do It Yourself), karena kita akan mengkonfigurasi aplikasi kita secara manual.

Pilih DIY

Selanjutnya, kita akan melihat form pembuatan aplikasi. Cukup isikan saja nama aplikasi yang akan dibuat, misalnya belajar.

Nama Aplikasi

Klik OK di bagian paling bawah, dan aplikasi kita akan sukses dibuat.

Sukses

Kita bisa klik ke halaman Application Overview untuk melihat setting aplikasi kita.

Halaman Settings

Karena aplikasi kita membutuhkan database, tambahkan cartridge MySQL dengan cara klik tombol ‘Add MySQL 5.5’. Kita akan disajikan halaman konfirmasi.

Menambahkan MySQL Cartridge

Klik Add Cartridge

Konfigurasi MySQL

Database kita sudah dibuatkan oleh Openshift. Tidak perlu menghafalkan nilai konfigurasinya, karena kita nanti akan menggunakan variabel yang sudah disediakan oleh openshift, yaitu OPENSHIFT_MYSQL_DB_HOST, OPENSHIFT_MYSQL_DB_PORT, OPENSHIFT_APP_NAME, OPENSHIFT_MYSQL_DB_USERNAME, dan OPENSHIFT_MYSQL_DB_PASSWORD.

Konfigurasi di Aplikasi

Aplikasi kita perlu dikonfigurasi supaya bisa diproses dengan baik oleh Openshift. Ada beberapa file yang perlu kita sediakan:

  • .openshift/settings.xml : konfigurasi Maven yang akan dipakai dalam Openshift
  • .openshift/action_hooks/build : script yang dijalankan untuk melakukan proses build
  • .openshift/action_hooks/start : script yang dijalankan untuk menyalakan aplikasi kita
  • .openshift/action_hooks/stop : script yang akan dijalankan untuk mematikan aplikasi kita

Mari kita buat dulu struktur file dan foldernya. Lakukan command berikut dalam folder aplikasi

mkdir -p .openshift/action_hooks
touch .openshift/settings.xml
touch .openshift/action_hooks/{build,start,stop}
chmod +x .openshift/action_hooks/*

Perintah di atas bisa dijalankan di Linux dan MacOSX. Bila Anda menggunakan Windows, silahkan gunakan Windows Explorer untuk membuat file dan foldernya. Untuk mengeset permission menjadi executable, gunakan perintah berikut

git update-index --chmod=+x .openshift/action_hooks/build

Berikut isi dari file settings.xml

<settings>
  <localRepository>${OPENSHIFT_DATA_DIR}/m2/repository</localRepository>
</settings>

Dan ini adalah isi file build yang berada dalam folder .openshift/action_hooks

#!/bin/bash

set -x

if [ ! -d $OPENSHIFT_DATA_DIR/m2/repository ]
then
    cd $OPENSHIFT_DATA_DIR
    mkdir m2/repository                
fi

if [ ! -d $OPENSHIFT_DATA_DIR/logs ]
then
    cd $OPENSHIFT_DATA_DIR
    mkdir logs
fi

if [ ! -d $OPENSHIFT_DATA_DIR/jdk1.8.0_20 ]
then
    cd $OPENSHIFT_DATA_DIR
    wget http://www.java.net/download/jdk8u20/archive/b17/binaries/jdk-8u20-ea-bin-b17-linux-x64-04_jun_2014.tar.gz
    tar xvf *.tar.gz
    rm -f *.tar.gz
fi

if [ ! -d $OPENSHIFT_DATA_DIR/apache-maven-3.3.9 ]
then
    cd $OPENSHIFT_DATA_DIR
    wget http://www-us.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz
    tar xvf *.tar.gz
    rm -f *.tar.gz
fi

export M2=$OPENSHIFT_DATA_DIR/apache-maven-3.3.9/bin
export MAVEN_OPTS="-Xms384m -Xmx412m"
export JAVA_HOME=$OPENSHIFT_DATA_DIR/jdk1.8.0_20
export PATH=$JAVA_HOME/bin:$M2:$PATH

cd $OPENSHIFT_REPO_DIR
mvn -s .openshift/settings.xml clean package -DskipTests=true

Pada script build di atas, kita mengunduh dan menginstall Java SDK versi 8 dan Maven versi 3.3.3. Jangan lupa mengupdate URL download sesuai dengan versi terbaru yang tersedia pada waktu kita mendeploy.

Setelah itu, kita mengeset environment variable. Terakhir, kita jalankan proses kompilasi tanpa menjalankan test. Hasilnya adalah file *.jar di dalam folder target yang siap dijalankan.

Berikut isi file start

#!/bin/bash

export JAVA_HOME=$OPENSHIFT_DATA_DIR/jdk1.8.0_20
export PATH=$JAVA_HOME/bin:$PATH

cd $OPENSHIFT_REPO_DIR
nohup java -Xms384m -Xmx412m -jar -Dspring.profiles.active=openshift target/*.jar --server.port=${OPENSHIFT_DIY_PORT} --server.address=${OPENSHIFT_DIY_IP} &

Script start di atas hanya mengatur environment variable dan menjalankan aplikasi. Kita menggunakan profile openshift agar Spring Boot membaca file konfigurasi yang sesuai. Isi file ini akan kita bahas di bawah.

Ini adalah isi file stop

#!/bin/bash
source $OPENSHIFT_CARTRIDGE_SDK_BASH
PID=$(ps -ef | grep java.*\.jar | grep -v grep | awk '{ print $2 }')
if [ -z "$PID" ]
then
    client_result "Application is already stopped"
else
    kill $PID
fi

Pada script start di atas, kita menyuruh Spring untuk menggunakan profile openshift. Dengan fitur profile ini, kita bisa membedakan konfigurasi koneksi database antara setting di komputer kita dan di server Openshift. Untuk itu, kita buat file application-openshift.properties di dalam folder src/main/resources. File ini akan dibaca apabila profile openshift aktif. Lebih lanjut mengenai profile bisa dibaca pada artikel terdahulu.

Berikut isi file application-openshift.properties

spring.datasource.url=jdbc:mysql://${OPENSHIFT_MYSQL_DB_HOST}:${OPENSHIFT_MYSQL_DB_PORT}/${OPENSHIFT_APP_NAME}
spring.datasource.username=${OPENSHIFT_MYSQL_DB_USERNAME}
spring.datasource.password=${OPENSHIFT_MYSQL_DB_PASSWORD}

Deployment ke Openshift

Deployment dilakukan dengan cara git push. Untuk itu kita perlu mendapatkan alamat repository git yang berada di Openshift. Informasinya ada di halaman setting aplikasi kita di Openshift.

Openshift Git URL

Copy alamat repository tersebut, kemudian daftarkan sebagai remote repository di project kita.

git remote add openshift ssh://abcdefghijklmn1234567890@belajar-endymuhardin.rhcloud.com/~/git/belajar.git

Terakhir, lakukan push

git push openshift master

Bila kita melakukan push di repository yang kita buat sendiri (bukan hasil clone dari Openshift), perintah di atas akan menimbulkan error. Ini disebabkan karena repository yang dibuatkan Openshift telah memiliki file di dalamnya, bukan repository kosong. File-file yang dibuatkan Openshift ini adalah file contoh/template konfigurasi untuk memudahkan deployment. Akan tetapi, karena kita sudah buat sendiri file-file tersebut (misalnya file build, start, dan stop), maka kita tidak membutuhkan lagi file yang dibuatkan Openshift.

Untuk itu, kita bisa langsung saja menimpa repository yang dibuatkan Openshift dengan opsi --force. Perintahnya menjadi sebagai berikut

git push openshift master --force

Aplikasi kita bisa diakses di alamat yang sudah disediakan Openshift

Alamat Aplikasi

Bila kita coba mengaksesnya, kita akan mendapatkan response JSON.

Output

Deployment Subfolder

Project yang kita kerjakan tidak selalu hanya terdiri dari satu aplikasi. Adakalanya project kita terdiri dari aplikasi web dan mobile yang bekerja sama. Untuk itu, biasanya di dalam repository kita akan ada dua folder untuk masing-masing aplikasi web dan aplikasi mobile, seperti terlihat pada screenshot di bawah.

Screenshot Project Multi Aplikasi

Pada situasi seperti ini, kita tidak bisa langsung push begitu saja ke Heroku dan Openshift, karena mereka mengasumsikan project kita berada di top level folder. Mereka mengharapkan ada file pom.xml di root folder. Sedangkan bila project kita terdiri dari aplikasi web dan mobile, pom.xml akan berada dalam subfolder web seperti pada screenshot di atas.

Solusinya adalah menggunakan fitur subtree yang ada di Git. Bila kita ingin mendeploy folder belajar-ci-web di screenshot di atas, perintahnya adalah sebagai berikut

git subtree push --prefix belajar-ci-web openshift master

Tentunya sebelumnya kita harus mendaftarkan dulu lokasi repository openshift seperti penjelasan di atas. Sama seperti penjelasan sebelumnya, repository yang dibuatkan Openshift dan Heroku biasanya sudah ada isinya, sehingga kita timpa menggunakan opsi --force. Akan tetapi, untuk perintah git subtree ini, pemakaian opsi --force ini agak sedikit berbeda. Kita harus menggunakan format lengkap dari push, yaitu seperti ini:

git push namaremote namabranchdilokal:namabranchdiremote --force

Nama branch di lokal diganti dengan isi subfolder, kita bisa ambil dengan perintah git subtree split --prefix belajar-ci-web. Sedangkan di tujuan (yaitu di Openshift), nama branch tujuannya adalah master. Perintah yang kita jalankan menjadi seperti ini

Untuk mendeploy subfolder ke Heroku caranya sama. Tinggal ganti saja tujuan remotenya.

Penutup

Demikianlah cara deployment aplikasi ke penyedia layanan PaaS di cloud. Setelah kita bisa melakukannya secara manual, pada artikel berikutnya kita akan otomasi deployment ini menggunakan Travis CI. Stay tuned ……