How To Deploy Your xApp On Linux

User-Contributed Article

This article has been submitted by Peter Jagielski.

If you wish to provide any feedback regarding this article please post your comments on the Morfik Discussion Forums under the documentation category.


Introduction

When deploying a Morfik 2.x (M2) application, a Morfik developer has 2 target operating system options available: Windows and Linux. From what I've read in the Morfik discussion forums, it appears that Windows is the more popular choice. Nevertheless, Linux remains the premier OS for web servers due to its stability and cost (free). The Morfik staff has made available a deployment how-to for both Windows and Linux [Morfik Application Deployment on Linux], but when I attempted my first Linux deployment, I ran into a few problems. It took me a couple days to figure it all out, and I hope you'll find this article helpful. This article explains, step by step, how to deploy your M2 app on Linux. But it also provides what I feel is other crucial information, including selecting a Linux hosting provider, Linux security, Firebird security and general maintenance.

I'd like to note here that Morfik (the company) offers a hosting service, and that it is Windows-based. Apparently, the Deployment wizard built into the Morfik IDE only works with this service, thus making deployment to Linux a bit more complicated.

Finally, I make no claim that this is the only way to deploy your M2 app on Linux. It's simply what worked for me, using a specific hosting service and Linux distro. Hopefully, with little or no change to my instructions, it will work for you too. Note to Linux newbies: This is going to look like rocket science. Don't despair, and be brave - it's not as hard as it first seems, which is usually the case regarding most things in life that are worth accomplishing.

At the time I wrote this article (Jan 2009), I used Morfik 2.0.5.18, Firebird 32-bit Superserver 2.1.1 and Ubuntu 64-bit 8.04 LTS. I plan on keeping this article updated, but any references to versions in the article may need to be replaced with later versions by the reader.

Assumptions and Suggestions

  1. You have little or no experience with Linux. My apologies to any Linux gurus if I've over-simplified, or chose the wrong (yet successful) way of doing something.
  2. Your M2 app is going to reside on the WWW for all to see and use.
  3. You have registered a domain name for your app (ie. www.yourappdomainname.com)
  4. For the purposes of this article, your M2 app is called MyApp and your associated Firebird database is called MYAPP.FDB.
  5. You are using an external Firebird database.
  6. Your Firebird database resides in your M2 app's root folder.
  7. You have set the following Morfik (project) Options for your M2 app as follows:
    1. Application | Domain = www.yourappdomainname.com
    2. Server | HTTP Port = 80
    3. Compiler | Compiler Options = Package Resources checkbox is checked
  8. You have set the following options in the Data Connectors wizard:
    1. Network Protocol = TCP/IP
    2. Connection String = 127.0.0.1:/<your app's root folder>/<your Firebird database file name> (note the use of forward slashes instead of back slashes)
    3. Your Firebird database's password is something other than the default 'masterkey'. If it's 'masterkey', change it!
  9. Your M2 app compiles and executes without problem on your Windows development box.


Preliminary

If you've decided to deploy your M2 app on Linux, the first question you'll be asking yourself is: "Where can I host my M2 app?". There are lots of Linux hosting services available. The key to finding the one that's right for you as a Morfik developer is one that (1) gives you to have full root-level control of your server and (2) allows you to install any software you want. After researching at least 10 Linux hosting providers, I decided to go with SliceHost (www.slicehost.com). I chose their "256 Slice", which is an Ubuntu VPS (virtual private server) that includes 256MB of RAM (after Linux has booted), 10GB of disk space, and 100GB/month of bandwidth, all for only $20/month. I have full root user priviledges to do just about anything I want with my slice, including soft and hard reboots, and installing any software. Their support (both email and discussion forum) has been superb, and their wiki articles are fantastic. This was my 1st experience setting up a VPS, and I found it to be very straightforward.

Now, you may be asking yourself "Wow, only 256MB of RAM? Is that enough?" It is for my M2 app, at least for the time being. This wiki article represents my first experience with hosting an M2 app on Linux, and my sole reason for going with a minimum slice configuration of 256MB was to see how little I could get away with for a fully functional M2 deployment, including the Firebird DB installation. This hardware configuration is going to be an on-going experiment for me, and I'll be updating this article as needed if and when I need to change the configuration. If needed, SliceHost makes it simple to upgrade to more RAM (and diskspace/bandwidth), and of course, there's always the option (elsewhere) to go "all-out" and get a fully-dedicated server. I'm not concerned about scaling at present, but knowing my M2 app currently runs on a bare-bones server provides me with the comfort of knowing that I have MANY upgrade/scaling steps available should I need them.

In order to get through the deployment steps below, there are 2 utility (Windows) programs you're going to need. First, you'll need an SSH client program in order to login to your server and execute commands via the command-line. I recommend Putty (http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html). It's free and easy to use. Second, you'll need a way to transfer files between your development box and server. I recommend FileZilla (http://filezilla-project.org). Again, free and easy to use.

For you Linux newbies, here are some basic linux commands you'll be using:

  • cd (change directory)
  • cp (copy)
  • chmod (changes file/directory access level)
  • chown (change file/directory ownership)
  • sudo (allows root-level command execution)
  • ls-l (list the contents of a directory)
  • mkdir (make a directory)

Note that command-line Linux is case-sensitive, so be careful with directory and file names.

Finally, although this article is based on my experience with SliceHost and Ubuntu Linux, I believe my instructions should be generic enough to enable deployment on other Linux hosting services and Linux distros with little or no changes. For example, with SliceHost, you need to configure the firewall yourself, whereas some other Linux hosting services may do this for you by default. As you'll see in my instructions below, all Linux activity is done via the command-line, and from that vantage point, there really isn't any difference between Linux distros using the same Linux kernel version.


Step-By-Step

I'm going to start by giving you the usual Good News/Bad News setup. First, the Bad News, which isn't so bad: There are a lot of steps to follow, and you won't be done in 5 minutes. If you're doing this for the first time, plan on anywhere between 2-3 un-rushed hours. There are other instructions that are specific to, and provided by, SliceHost to ease and complete your installation. I've included the time to read and implement those instructions in the 2-3 hour time frame.

Now for the Good News: you'll have your M2 app deployed on Linux in 2-3 hours instead of the almost 2 days it took me to figure it all out, which includes some Linux trouble-shooting and education that has nothing to do with M2 deployment.

The steps below are broken down into 6 parts:

  • Part 1 - Hosting Setup
  • Part 2 - Extra Linux Stuff
  • Part 3 - Install Firebird
  • Part 4 - Install Your M2 App
  • Part 5 - Start Your M2 App
  • Part 6 - Updating Your M2 App

Let's begin!


Part 1 - Hosting Setup

If you already have a hosting provider, you may skip this step. You may also skip Step 2, but I recommend you read it, as you may find some helpful information there.

  1. Go to http://www.slicehost.com
  2. Sign up for the 256 Slice.
  3. Follow all instructions that are emailed to you.
  4. Go to http://articles.slicehost.com/ubuntu-hardy and implement the instructions in Ubuntu Hardy Setup Page 1 and Page 2. Yes, I know - it's kind of lengthly, and if you don't know anything about Linux, kind of scary as well. But it's all basic, essential stuff that you'll need to know if you're going to be managing a Linux box.
  5. You may need to update your DNS settings. You can do this entirely through the SliceHost control panel. Help on this is available on their website.
Note:

- "Hardy" is the build name for Ubuntu 8.04. Ubuntu changes the build name for each new version of their distro.

- Don't worry about the firewall stuff in the iptables section of Page 1 - I'll show you an easier way to setup a firewall below.

- Finally, don't worry about messing things up - if you end up accidentally doing something that makes a mess of your slice, you can always reboot or re-initialize your slice via the SliceHost control panel.

- If you have any problems with the above, contact SliceHost's support - they REALLY know their stuff and are VERY responsive. I think if you encounter any problems at all with the instructions in this wiki article, it's going to be with the purely Linux stuff above.

Part 2 - Extra Linux Stuff

Currently, every port on your new slice is open, thus making it almost completely insecure. We're going to configure the firewall so that it accomplishes the following:

  • Allows SSH traffic on standard port 22 - this is the standard SSH port. If you changed this value to port 30000 (or some other value) as instructed in the SSH config section of Page 1, then be sure to change the value accordingly in Step 6 below.
  • Allows HTTP traffic on standard port 80. This is the standard HTTP port used by the public to access your M2 app.
  • Allows traffic on port 3050, but ONLY from your workstation and your M2 app. Firebird uses port 3050 (default, but can be changed) for communication with client programs, both internally (your M2 app) and externally (your Firebird management tool running on your home/office computer). The point here is that you don't want your Firebird server simply open to the entire Internet. A hacker who is familiar with Firebird could quite easily compromise your Firebird server and database(s). To counter this threat, this technique limits access to port 3050 to prevent any unauthorized access. Of course, if your home/office IP address is constantly changing, this technique will not work well. I'll leave it to the reader to investigate general Firebird security, of which much has been written and is availble for free - just Google for it, or visit the Yahoo Groups Firebird Support Forum (http://tech.groups.yahoo.com/group/firebird-support/).
  • Close all other ports. Note that if you need other ports open for some reason, issue the appropriate additional UFW commands as described below.

Let's now configure the firewall with a method that's way more simple than messing with iptables as discussed in the iptables section of Page 1:

  1. If you're not logged in to your server, please do so now (with Putty or another SSH client).
  2. Install UFW (Uncomplicated Firewall) with the command: sudo apt-get install ufw
  3. Then issue the following commands (notes follow in parenthesis):
  4. sudo ufw enable (start UFW)
  5. sudo ufw default deny (block all incoming traffic on all ports)
  6. sudo ufw allow 22/tcp (allow SSH traffic on standard port 22)
  7. sudo ufw allow 80/tcp (allow HTTP traffic on standard port 80)
  8. sudo ufw allow proto tcp from <your home/office PC ip address> to <your slice's ip address> port 3050 (allow Firebird to accept an outside connection *only* from my computer)
  9. Finally, perform some cleanup work:
  10. Update existing Ubuntu files with the command: apt-get update
  11. Upgrade existing files with the command: apt-get upgrade
  12. Install strace utility for possible debugging purposes later: apt-get install strace
  13. Install dnsutils: sudo aptitude install dnsutils
  14. Edit the /etc/hostname file to change your server's host/domain name. The default will be set to the name of your slice. For example, if your slice is named "MySlice" and the domain name for your M2 app is "www.mymorfikapp.com", change it to "MySlice.mymorfikapp.com". To edit the file, you can use nano editor: sudo nano /etc/hostname

That's it for the Linux side of things! Again, if you are using a Linux distro other than Ubuntu, and/or a hosting service other than SliceHost, you may have had to make some adjustments to 1 or more of the steps above.


Part 3 - Install Firebird

Since the version of Ubuntu used by SliceHost is the 64-bit version, I initially tried using the 64-bit version of Firebird 2.1.1. Even though it installed without a problem, I could not get my M2 app to successfully communicate with Firebird. This is probably due to a difference between various 32-bit and 64-bit files. I'll investigate this further at a future time, but for now, we'll be installing the 32-bit version of Firebird. Interestingly, while developing my M2 app on my Windows XP 64-bit box, my M2 app had no problems connecting to the 64-bit Windows version of Firebird I had installed, which is what led me to attempt the 64-bit Firebird install on my slice.

Again, assuming you're still logged in to your server (notes follow in parenthesis):

  1. Go to the root folder: cd /root
  2. Install library files needed by Firebird: sudo apt-get install libstdc++5 (I'm not sure why the Firebird installer doesn't do this automatically)
  3. Download 32-bit Firebird Superserver for Linux: wget http://downloads.sourceforge.net/firebird/FirebirdSS-2.1.1.17910-0.nptl.i686.tar.gz
  4. Unpack the downloaded file: sudo tar -xzf FirebirdSS-2.1.1.17910-0.nptl.i686.tar.gz
  5. Go to the Firebird folder created in /root by the unpacking process: cd FirebirdSS-2.1.1.17910-0.i686
  6. Install Firebird: sudo ./install.sh (when prompted, use the same password you specified for the database connection in your M2 app, which should be something other than 'masterkey')
  7. Verify that Firebird is running: top -b -n1 | grep fb (should see fbserver & fbguard listed; Firebird will automatically start when you reboot your slice)
  8. Upload (via FileZilla or equivalent) the Morfik-supplied MFKUDF.dll located in your Morfik installation to your slice's /opt/firebird/UDF folder
  9. Set access rights for MFKUDF.dll: chmod 654 /opt/firebird/UDF/MFKUDF.dll


Part 4 - Install Your M2 App

We're now finally ready to install your M2 app. As noted earlier, assuming your M2 app is called MyApp and your Firebird database is called MYAPP.FDB:

  1. Create a directory for your M2 app: mkdir /myapp (important: use the same directory structure as you have on your development box, since the path to your Firebird database is hard-coded within your M2 project!)
  2. Give the firebird group (created by the Firebird installer) access to the /myapp folder: chown root.firebird /myapp
  3. Upload (via FileZilla or equivalent) your basic M2 app files to /myapp (MyApp, MyApp.Mxd, MyApp.Mxp, MyApp.Mxr, and MyApp.wsdl if you're using web services)
    1. Also upload any other custom files your app may need, such as graphics, css files, etc.
  4. Set the MyApp (your Linux executable) file rights to executable: chmod 755 MyApp
  5. Set the file rights for your MyApp.Mxd file to read/write: chmod 666 MyApp.Mxd
  6. Set the file rights for your MyApp.Mxp file to read/write/execute: chmod 755 MyApp.Mxp
  7. Set the file rights for your MyApp.Mxr file to read/write/execute: chmod 755 MyApp.Mxr
  8. Upload (via FileZilla or equivalent) the Morfik-supplied libhttpd.so to /usr/lib
  9. Set the file rights for libhttpd.so to executable: chmod 755 /usr/lib/libhttpd.so
  10. Now it's time to copy your M2 app's Firebird database from your development box to your slice. DO NOT simply copy the MYAPP.FDB from your development box to your slice, as you risk possible file corruption! Existing Firebird documentation makes it very clear that you should do a backup/restore process to accomplish this task! If you're using a Windows-based GUI Firebird management tool such as Firebird Maestro, Database Workbench or similar, simply use that tool to create a backup called MYAPP.fbk. Otherwise, open up a Windows command-prompt box, go to the folder that contains your M2 app's Firebird database, and type in the following (assumes C:\Program Files\Firebird\Firebird_2_1\bin is in your Windows path): gbak -USER sysdba -PAS <yourpassword> -B -T MYAPP.FDB MYAPP.fbk
  11. Upload (via FileZilla or equivalent) MYAPP.fbk to your slice's \myapp folder.
  12. Back on your slice, restore your M2 app's database with either your Firebird management tool or the command-line: sudo /opt/firebird/bin/gbak -USER sysdba -PAS <yourpassword> -REP MYAPP.fbk MYAPP.FDB
  13. Set the file rights for your Firebird database file to read/write: chmod 666 MYAPP.FDB
  14. Set the file ownership rights for your Firebird database file to the firebird group: chown firebird.firebird MYAPP.FDB
  15. The next step needs a little explanation. In your Morfik development box installation, there's a set of Linux .so library files in the ..\PlatformCompilers\fp\cross\i386-linux\lib folder. When you start your M2 app on Linux, your M2 app is going to be looking for these files. These files already exist on your Ubuntu slice, but the problem is that they are newer versions of the these files, and have slightly different names. Your M2 app will fail to start because it can't find the files with the original names. There are 2 possible solutions to this problem, both quite simple. The first, which I didn't try, is to simply copy the files from your Morfik installation to your slice's /lib folder. The second, which is the method I chose and describe below, is to create symlinks (symbolic links) between the files your M2 app is looking for and their newer counterparts.

The .so files your M2 app will need, but are missing from the /lib folder, are:

  • libc.so
  • libcrypt.so
  • libdl.so
  • libpthread.so
  • librt.so
  • libuuid.so

However, newer versions of these files DO exist in /lib (note that versions of Ubuntu after the Hardy build may have renamed these files again):

  • libc.so.6
  • libcrypt.so.1
  • libdl.so.2
  • libpthread.so.0
  • librt.so.1
  • libuuid.so.1 -> libuuid.so.1.2 (already a symlink)

Create the required symlinks with the following sequence of commands:

  1. cd /lib
  2. ln -s libc.so.6 libc.so
  3. ln -s libcrypt.so.1 libcrypt.so
  4. ln -s libdl.so.2 libdl.so
  5. ln -s libpthread.so.0 libpthread.so
  6. ln -s librt.so.1 librt.so
  7. ln -s libuuid.so.1.2 libuuid.so


Part 5 - Start Your M2 App

Finally, the big moment you've been waiting for! Time to start your M2 app for the first time!

  1. Go back to your /myapp folder: cd /myapp
  2. Start your application: sudo ./MyApp

If your app starts successfully, you're going to see output similar to this:

Compiled for *nix

00002AE8:F7BA36F0 calling StartupProc...

00002AE8:F7BA36F0 Running under root! Apache "user" directive will point "nobody".

00002AE8:F7BA36F0 Running under root group! Apache "group" directive will point "nogroup".

00002AE8:F7BA36F0 XApp starting...

00002AE8:F7BA36F0 loading Application Resources (MXR)...

00002AE8:F7BA36F0 loading Modules catalog data...

00002AE8:F7BA36F0 loading Table/Query catalog data...

00002AE8:F7BA36F0 loading browser debug modules...

00002AE8:F7BA36F0 loading Documents catalog data...

00002AE8:F7BA36F0 loading Service Connectors catalog data...

00002AE8:F7BA36F0 loading Control Adapters catalog data...

00002AE8:F7BA36F0 loading RSS Feed catalog data...

00002AE8:F7BA36F0 loading configuration from ini file...

00002AE8:F7BA36F0 catalog initialization complete

00002AE8:F7BA36F0 server cache validated

00002AE8:F7BA36F0 [rmMaster] loading plugin XApps...

00002AE8:F7BA36F0 [rmMaster] generating Apache configuration file...

00002AE8:F7BA36F0 [rmMaster] launching master Apache DLL...

Launch Apache...

Done launching Apache.

In thread

About to call apache main

WARNING: ThreadsPerChild of 500 exceeds compile time limit of 256 threads, 
lowering ThreadsPerChild to 256.  To increase, please see the 
HARD_SERVER_LIMIT define in src/includehttpd.h.

You may at this point close your Putty window, and your application will remain running. You're done! Congratulations!

If on the other hand, you don't see the output above, but instead see what amounts to 1 or more ugly Linux error messages, then there's obviously a problem, and the problem is most likely 1 or more missing files and/or you do not have access rights set correctly for 1 or more files. Fortunately, there are 2 ways that I know of (there may be more) to figure out what file(s) are missing or do not have their access rights set correctly.

The first and easier method you should try is to use a utility called getlibs. getlibs is a Linux script that you can use to launch your M2 (or any) application, and it will report back any files your M2 app is looking for but can't find at startup. Make sure you're in your /myapp folder (cd /myapp), then download getlibs:

wget http://www.boundlesssupremacy.com/Cappy/getlibs/getlibs

Then set the rights for the getlibs script to executable: chmod +x getlibs

Finally, use getlibs to start your M2 app: sudo ./getlibs /myapp/MyApp

Carefully look at the output, and look for the missing file(s). You can then use getlibs to download the missing file: sudo ./getlibs -l <missing file name>

As I have no idea what file(s) you may be missing, it will be up to you to figure out in which folder the missing file needs to be placed after you have downloaded it. This is where Google is your friend - with a little bit of searching, you should be able to figure it out. Sorry I can't be of more assistance here.

The second method you can use to determine what's causing your M2 app to fail at startup is to use the Linux strace utility. We installed this utility back in Part 2, Step 12. Here's how to run an strace on your M2 app:

sudo strace -f -o myfile.log -s 255 ./MyApp

The output of strace is sent to the text file called myfile.log. You can simply download this file to your development box and open it up in your favorite text editor, or open it with the nano editor on your slice (sudo nano myfile.log). If you're a Linux newbie, looking through this file may prove to be daunting, as it will probably not only be lengthly, but rather terse, and you won't know what to be looking for. I can only suggest 2 things for the Linux newbie: search for the word "ERROR", and ask for help on the SliceHost or other various Linux discussions forums (I recommend www.linuxquestions.org). Don't bother asking SliceHost support about Morfik - they don't know what it is, and thus won't be able to help you. If you signed up to be a Morfik Pioneer, then please behave like one!

Part 6 - Updating Your Morfik Application

So, you're M2 app has been up and running for days/weeks/months, but it's time for an update: you've added new features, fixed some bugs, changed/added some database tables and stored procedures, and now you need to update your running app. With your typical non-Morfik web site running Apache, it's usually as easy as uploading and overwriting existing .html files, scripts, graphics, etc., all while the web server (ie. Apache or other) continues running during the update. With Morfik, it's a bit more complicated. Like a Windows program .exe that cannot be overwritten if the program is running, the same applies to Linux. Your application must be shut down, new files uploaded, the old files overwritten, the database updated and the application restarted. If your M2 app has a lot of 24/7 users, you face the very real problem of downtime, which could result in angry users (either asked to logoff or forced off) and lost revenue. So to minimize downtime, I've taken the following approach:

  1. Upload (via FileZilla or equivalent) updated M2 app files to a backup folder (/myapp/backup)
  2. Shut down the app: kill <pid> (see comment below)
  3. Copy the new files over the old: cp /myapp/backup/* /myapp
  4. Update (if necessary) the database
  5. Restart the app: sudo ./MyApp

With my M2 app, I've found that the upload process takes the longest amount of time. Since there's no point in including the upload time in the final downtime, I leave my M2 app running while I do the upload (Step 1). Steps 2, 3 and 5 can then be done in about 15 seconds. If Step 4 is necessary, the amount of time needed to make the changes depends solely on what needs to be changed, and how the change is implemented. Changes to the database can be done either manually or with a Firebird SQL script, depending on what needs to be accomplished.

Regarding Step 2 above, the <pid> is the process id. To determine what the <pid> for your running M2 app is, execute the following:

ps aux | grep ./MyApp

The 1st column of the output you'll see contains the name of the user that owns the process. The 2nd column contains the pid of the process, which is an integer number. The output will most likely contain more than 1 row of processes. The pid you're interested in, and will specify in Step 2, is the one where the user name is root.

It should be noted that shutting down your running M2 app is required anyway if you make any changes to your M2 app's Firebird database. Changes made to a Firebird database are invisible to all currently connected clients, such as your M2 app, until the clients disconnect and reconnect. It all has to do with the way Firebird handles database integrity, which is a whole other topic unto itself.

Closing Notes

If after having followed my instructions you've met with success, congratulations! It wasn't THAT bad, now was it? If on the other hand, you're M2 app still fails to start, keep your cool, be patient, and retrace your steps. Chances are good you may have accidentally skipped a step. If you get to a point where you feel you're completely stuck, you have a few options:

  1. Post a message in the Morfik discussion forum. I'm there almost daily, and will help if I can, as will Morfik tech support.
  2. Post a message in the SliceHost discussion forum.
  3. Post a message in the www.linuxquestions.org discussion forum.

If you decide to go with SliceHost, please feel free to use my email address (pjagielski@gmail.com) as your reference during the signup process.

Finally, there are other related topics with which you should familiarize yourself, some of which would make fine Wiki articles unto themselves. These topics include:

  • Staging/Testing Environments: Is your live M2 app *really* ready for an update? Your updated M2 app may run fine on your development box, but you would be wise to perhaps purchase another SliceHost slice and stage/test your updates there before actually going live.
  • Backups: SliceHost can backup your slice daily (for an additional fee), but there's also the important issue of managing backups of your Firebird databases. How often? Offsite storage?
  • Starting your M2 app automatically during Slice boot-up: You've been starting your app manually, but you will probably want to consider having it start automatically when your slice re-boots.
  • Warning messages displayed when starting your M2 app: You may have noticed in Part 5, Step 2, when you started your app that there appeared some interesting messages about Apache and ThreadsPerChild. Although I haven't noticed any negative ramifications in my own M2 application because of these messages, I don't know enough about the messages at this point to figure out what's causing them, if they're actually a problem that needs to be fixed, and if so, how to fix them.
  • SSL: At the time I wrote this article, Morfik's SSL implementation was not functional. Morfik is aware of the problem, and they've promised a fix soon. As I know I will eventually need SSL support, I will update this article when Morfik has SSL operational. Hopefully, the implementation will be simple, and only a few extra steps will need to be added to this article.
  • Linux in General: Now that you're married to Linux :), there are many books and online resources available. Lots to learn, so little time :)

Related Topics


Back to top