Deploya nodeJS-applikationer på Cloud Application Platform - Cygate
Cystore

Deploya nodeJS-applikationer på Cloud Application Platform

I den här guiden kommer vi ta upp hur man deployar en NodeJS applikation på Cygate Cloud Application Platform som bygger på Apcera. Det innebär att vi kommer deploya applikationen i så kallade containers (även kallat ”jobs” i Apcera).

Applikationen som vi kommer använda är ett WebGL spel utvecklat i Javascript som klient och en NodeJS (Javascript) server som backend för att hantera spelresultat. Backenden kommer att använda sig av en MySQL databas för att spara ner spelresultat till. Spelet heter Saving Nemo och är utvecklat av författaren till den här guiden (Magnus Persson).

Versionen av spelet har modifierats en aning för att visa skalningen av spelet på containers. Det skriver ut namnet på containern som klienten servas från. Den sparar även ner namnet på containern som man spelade på i databasen. Detta för att få en överblick över hur det lastbalanseras då man skalar upp applikationen. Utöver detta har ingen modifiering gjort på spelet som inte är generiskt för containrar (Docker etc.).

Ovan är resultatet av den här guiden om allt går som det ska.

Kom igång

För att genomföra den här guiden behövs följande verktyg:

  • Git klient – För att hantera källkoden i exemplet.
    • Ubuntu/Debian: apt-get install git
  • Apc klient – För att mangera Apcera klustret.

Git är inget måste för att köra applikationer i Apcera, men i den här guiden hämtar vi ner exempelkoden från github med git klienten.

Vill man även exekvera applikationen på sin lokala dator behövs även en MySQL server samt NodeJS installerat.

Förutom det ovan behövs ett konto på vår plattform. Det går att få ett gratis demo konto här: https://register.demo.cygate.io

Hämta ner exempelkoden

Först måste vi hämta ner exempelkoden som finns på github:

$ git clone git@github.com:Lallassu/SavingNemoMySQL

$ cd SavingNemoMySQL

$ ls

LICENSE      css          index.html   libs         node_modules promo.png    sounds

README.md    fonts        js           models       package.json server.js    textures

Notera att inga filer i katalogen är specifika för Apcera. Vår NodeJS server är ”server.js” och kan exekveras med node. Servern kommer dock inte starta om man inte har en MySQL-databas på sin dator som man konfigurerat i server.js.

Förutom node_modules, server.js samt package.json så är alla filer endast för klienten (javascript/css/font/html filer) och därmed inga filer att bry sig om i det här exemplet.

Den mest intressanta filen är package.json. Om vi tittar i den:

$ cat package.json

{

”name”: ”saving-nemo-server”,

”version”: ”0.0.1”,

”scripts”: {

”start”: ”node server.js”

},

”dependencies”: {

”sqlite3”: ”2.0.18”,

”socket.io”: ”1.0.6”,

”dblite”: ”0.4.1”,

”mysql”: ”2.4.1”

}

}

Så ser vi att dependencies specificeras. Det är vilka beroende som finns för spelet. Notera att sqlite3 inte används i den här versionen som istället använder MySQL.

Sedan specificerar vi start-kommandot ”node server.js”. Det säger egentligen bara hur man startar servern. Så start-kommandot samt specificerade beroenden är det man behöver tänka på både i och utanför Apcera miljön. Det vill säga, det är inget Apcera specifikt. Men det är package.json som Apcera kommer läsa för att veta hur den ska starta (”stage:a”) applikationen.

Det enda som skiljer sig i koden från att köra lokalt mot i en container är hur databasen pekas ut i server.js samt porten för applikationen.

Porten sätts automatiskt via en miljövariabel (PORT):

var port = process.env.PORT

Databassträngen sätts via en annan miljövariabel (MYSQL_URI):

var connurl = process.env.MYSQL_URI

På samma sätt fungerar det i Docker att applikationen får portar och databas-information via miljövariabler. Så det är en vedertagen standard för containrar.

Logga in i apcera

När du installerat ’apc’ klienten så kan du logga in på följande sätt med den användare du valt.

Har du glömt ditt lösenord kan du få ett nytt här: https://register.demo.cygate.io/resetpassword

Först måste vi sätta target, vilket kluster vi ska logga in på (i det är fallet Cygate CAP Demo):

$ apc target demo.cygate.io

Targeted [http://demo.cygate.io]

$ apc login –ldap-basic

Connecting to http://demo.cygate.io…

Username: magnus

Password: ********

Login successful.

Deploya applikationen

Nu har det blivit dags att deploya applikationen. I det här exemplet låter vi allt vara default utom ramminne som vi sätter till 50MB (vilket räcker gott och väl för en instans av spelet).

$ apc app create nemo-demo

Deploy path [/Users/nergal/Work/blogposts/SavingNemoMySQL]:

Instances [1]:

Memory [256MB]: 50

╭───────────────────────────────────╮

│                       Application Settings                       │

├───────────────────┬──────────────┤

│              FQN: │ job::/sandbox/magnus::nemo-demo              │

│        Directory: │ /Users/nergal/Work/blogposts/SavingNemoMySQL │

│        Instances: │ 1                                            │

│          Restart: │ always                                       │

│ Staging Pipeline: │ (will be auto-detected)                      │

│              CPU: │ 0ms/s (uncapped)                             │

│           Memory: │ 50                                           │

│             Disk: │ 1024MB                                       │

│          Network: │ 5Mbps                                        │

│           Netmax: │ 0Mbps (uncapped)                             │

│         Route(s): │ nemo-demo.magnus.sandbox.demo.cygate.io      │

│  Startup Timeout: │ 30 (seconds)                                 │

│     Stop Timeout: │ 5 (seconds)                                  │

╰───────────────────┴─────────────╯

Is this correct? [Y/n]: y

….

Creating app ”nemo-demo”… done

Start Command: node server.js

App may be started with:

> apc app start nemo-demo

Success!

Nu har vi deployat applikationen. Som man ser så installeras och hanteras alla paket automatiskt av stagern för nodejs som finns i Apcera. Man får med andra ord mycket hjälp av Apceras process.

Vi kan inte starta applikationen än eftersom vi behöver en databas också. Det skapar vi i nästa steg. Skulle vi starta aplikationen redan nu så kommer den fela då den inte kommer åt någon databas.

Skapa en databas-service

Demomiljön från Cygate har en MySQL provider som tillhandahåller access mot en MySQL databas. Vi behöver dock skapa en service som nyttjar MySQL providern och som vi även vill binda mot applikationen för att den ska få databas åtkomst.

Vilka services som Cygate tillhandahåller kan ses genom att lista dem i /production namespace.

$ apc provider list –namespace /production

Working in ”/production”

╭───────────────────────┬───────┬─────────────┬────────────────╮

│ Name                  │ Type  │ Namespace   │ Description    │

├───────────────────────┼───────┼─────────────┼────────────────┤

│ apcfs                 │ nfs   │ /production │ Apcera FS v1.0 │

│ mysql-cygate-provider │ mysql │ /production │                │

╰───────────────────────┴───────┴─────────────┴────────────────╯

Det är mysql-cygate-provider vi vill skapa en service mot och binda mot applikationen. Det gör vi genom att utföra följande kommando:

$ apc service create nemo-demo-mysql -provider provider::/production::mysql-cygate-provider –job nemo-demo

╭────────────────────────────────────────────────────────────────╮

│                   Service Creation Settings                    │

├─────────────────┬──────────────────────────────────────────────┤

│        Service: │ service::/sandbox/magnus::nemo-demo-mysql    │

│       Provider: │ provider::/production::mysql-cygate-provider │

│ Job to bind to: │ nemo-demo                                    │

│        Binding: │ (will be auto-generated)                     │

╰─────────────────┴──────────────────────────────────────────────╯

Is this correct? [Y/n]: y

Creating service… done

Binding service ”nemo-demo-mysql” to ”nemo-demo”…

Success!

Det vi säger med kommandot ovan är att vi vill skapa en service kallad nemo-demo-mysql och som använder sig av providern /production::mysql-cygate-provider och att den ska binda till jobbet nemo-demo (som vi skapade tidigare).

Starta applikationen

Nu när vi deployat och bundit vår applikation mot en MySQL service så kan vi starta den:

$ apc app start nemo-demo

Waiting for the job to start…

[stdout] ===================================

[stdout] Server for Saving Nemo

[stdout] Author: nergal

[stdout] Version: 0.1

[stdout] ===================================

[stdout] 16 Nov 09:45:25 – Started server on port 4000

Job should be accessible at ”http://nemo-demo.magnus.sandbox.demo.cygate.io”

Success!

Som outputen säger så kan vi nå vår applikation på länken http://nemo-demo.magnus.sandbox.demo.cygate.io. Länken varierar beroende på du har för användarnamn på plattformen.

Om allt gått rätt så bör du få upp följande på länken. Och testa gärna att spela för att se så data lagras i databasen:

nodejs-2

Skala applikationen

Nu kan vi se att vår applikation är i gång och hur många instanser som körs genom att lista alla applikationer:

$ apc app list

Working in ”/sandbox/magnus”

│ nemo-demo  │ /sandbox/magnus │ started │ 1/1       │ http://nemo-demo.magnus.sandbox.demo.cygate.io  │

Här ser vi att den är igång samt att det körs en instans av applikationen. Vi vill nu öka upp antal instanser från 1 till 5. Detta görs enkelt genom att exekvera följande:

$ apc app update nemo-demo -i 5

╭────────────────────────╮

│  Job Update Settings   │

├────────────┬───────────┤

│      Name: │ nemo-demo │

│ Instances: │ 5         │

╰────────────┴───────────╯

Is this correct? [Y/n]: y

Application instances updated from 1 to 5 successfully.

Applying update… done

Start Command: node server.js

Success!

Listar vi nu applikationer igen så kan vi se att det körs 5 instanser av applikationen:

$ apc app list

Working in ”/sandbox/magnus”

│ SavingNemo │ /sandbox/magnus │ started │ 5/5       │ http://savingnemo.magnus.sandbox.demo.cygate.io │

Om vi nu går till vårt spel igen via länken som i vårt fall är http://nemo-demo.magnus.sandbox.demo.cygate.io/ och laddar om sidan flera gånger så kan man se att texten längst upp ändrar vilken instans man spelar på. Det är inte säkert att den ändras, klienten kan faktiskt servas av samma container igen.

Övrigt

Lite övriga kommandon som är bra att känna till:

Lista alla applikationer: $ apc app list

Lista alla services: $ apc service list

Kolla loggar som applikationen spottar ur sig:

$ apc app logs <app_name>

Kolla information om applikationen samt miljövariabler som den har tillgång till:

$ apc app show <app_name>

Notera även att många delar går att utföra via det webgränssnitt som finns. https://console.demo.cygate.io.

Nyttiga länkar

Fler WebGL spel med öppen källkod: https://github.com/lallassu

Webgränssnittet för Cygate CAP: https://console.demo.cygate.io

Skapa gratis konto: https://register.demo.cygate.io

Glömt lösenord: https://register.demo.cygate.io/resetpassword

En kort ”kom-igång” guide: http://register.demo.cygate.io/howto

En mer komplett guide med policy hantering: http://register.demo.cygate.io/example2

Apcera dokumentation: https://docs.apcera.com