Working with Database and Container Storage

Published at: April 3, 2018, 6:40 a.m. in the Documentation

All running APIs work inside the Docker-container.
Thus, the data is stored in RAM and lost when the container with your API is rebuilt.

Smappi provides the ability to use permanent data storage, at the moment the amount of space is 512 MB.
You can use this space to place files of the Database or any other files.

But for this you need to activate this option, about this below.

How to activate Container Storage

To activate this storage, go to "Settings > Container storage" and click on the "Use container storage" checkbox.


The absolute path to the storage in the container is "/home/container/storage", but you can use the relative "./storage" to not specify different absolute paths for local development and the Smappi container versions.

After you click on "Save", your container will restart with the Container Storage mounted in it.

Example of working with the Container Storage and SQLite

For example, create an API that has two methods:

  • Create an item
  • Obtain a list of names of all items

In the Database there will be one table with the following contents:

ColumnType
idINTEGERPRIMARY KEYAUTOINCREMENT
nameTEXTUNIQUENOT NULL
created_atDATETIME

Go to the directory with your local project and install sqlite3:

$ npm install --save sqlite3

Create a directory "storage":

$ mkdir storage

Edit "api.js":

const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('storage/database.db');

(function init (db) {
    // Init tables
    db.serialize(() => {
        db.run(
            `CREATE TABLE IF NOT EXISTS items (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL UNIQUE,
                created_at DATETIME)`
        )
    });
})(db);

/**
 * Add item
 *
 * @param {String} name
 *
 * @example
 *   addItem("first")
 *   // => true
 */
function addItem (name) {
    var self = this;
    db.run(`INSERT INTO items (name, created_at) VALUES (?, datetime('now'))`, [name], (err) => {
        if (err) {
            console.log('INSERT Error', err.message);
            return self.return(false);
        }
        console.log('Last ID', this.lastID);
        self.return(true);
    });
}

/**
 * Get items
 *
 * @example
 *   addItem("one")
 *   addItem("two")
 *   getItems()
 *   // => [{"name":"one"},{"name":"two"}]
 */
function getItems () {
    var self = this;
    db.all('SELECT name FROM items ORDER BY id', [], (err, items) => {
        if (err) throw err;
        self.return(items);
    });
}

module.exports = { addItem, getItems }

Check locally how the data is stored in our Database:

$ smappi run

Make several test requests:

$ curl "http://localhost:8000/addItem?name=first"
true

$ curl "http://localhost:8000/addItem?name=second"
true

$ curl "http://localhost:8000/addItem?name=last"
true

$ curl "http://localhost:8000/getItems"
[{"name":"first"},{"name":"second"},{"name":"last"}]

Stop "smappi run" and start again, then make a request to get list of items:

$ curl "http://localhost:8000/getItems"
[{"name":"first"},{"name":"second"},{"name":"last"}]

And make sure that everything works correctly.

Now save all changes and send to the server:

$ git commit -am "SQLite database support added"
$ git push

Now your data will not be lost after the container is restarted.

Additionally