我的docker隨筆27:基於容器的sqlite測試

需求:
sqlite 常用於嵌入式平臺,本文使用容器進行測試。選用環境有 nodejs 和 python,主要目的是測試在容器運行的情況,及數據共享。測試代碼源自網絡,但有修改。

nodejs 環境

創建工程目錄。
運行容器:

sudo docker run -itd --rm --name node -v $PWD:/home/node node:alpine sh

sudo docker exec -it node sh

查看容器的 node 版本爲 14.2.0,在宿主機上安裝指定的版本:

sudo npm i -g n
sudo n 14.2.0

安裝 sqlite:

sudo npm install sqlite3

寫數據庫核心代碼:

/*
注1:node爲異步,不能按順序創建表、插入數據,可能會提示表不存在。
注2:
*/
var sqlite3 = require('sqlite3').verbose();

var db;
db = new sqlite3.Database("db.db", function(err) {
  if (err) throw err;
});

console.log("db: ", db)
db.run(`create table IF NOT EXISTS user (id INT,name VARCHAR,password VARCHAR)`, function(
  err
) {
  if (err) throw err;
  console.log("Create Table Success!");
});

// Run Insert Data
db.run(`insert into user values (666,"admin","admin")`, function(err) {
  if (err) throw err;
  console.log("Insert Data Success!");
});

db.close(function(err) {
  if (err) throw err;
});

注意,由於 nodejs 是異步的,所以可能會提示 user 表不存在,多次執行即可。本文僅演示,不做實踐指導。

查詢數據庫核心代碼:

var sqlite3 = require('sqlite3').verbose();

var db;
db = new sqlite3.Database("db.db", function(err) {
  if (err) throw err;
});

function show() {
console.log("inside....")
db.all("select * from user", function(err, rows) {
  if (err) throw err;
  console.log(rows);
});

setTimeout(show, 1000);
}

show();

/*
db.close(function(err) {
  if (err) throw err;
});
*/

解釋:間隔 1 秒查詢數據庫並打印數據。

測試結論:
宿主機寫、讀數據庫,通過。
宿主機寫數據庫,容器讀數據庫,通過。
容器寫數據庫,宿主機查詢,失敗。在容器中執行提示段錯誤Segmentation fault。嘗試在純 docker 目錄中執行,亦然。

nodejs arm 環境

此處僅描述環境的搭建。需求:在 arm 平臺實現 nodejs 容器,內含 koa、sqlite3。
在 x86 運行 arm 容器。

docker pull arm32v7/node:10-slim

docker run -itd --rm -v $PWD:/home/node -p 3000:3000 --name nodejsbuild arm32v7/node:10-slim sh  
docker exec -it nodejsbuild sh

安裝:

npm install sqlite3

出錯:

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-pre-gyp install --fallback-to-build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

分析:

node-pre-gyp WARN Using needle for node-pre-gyp https download 
node-pre-gyp WARN Tried to download(403): https://mapbox-node-binary.s3.amazonaws.com/sqlite3/v4.2.0/node-v64-linux-arm.tar.gz 
node-pre-gyp WARN Pre-built binaries not found for [email protected] and [email protected] (node-v64 ABI, glibc) (falling back to source compile with node-gyp)  // !! arm 平臺沒有預編譯,需要從源碼安裝
gyp ERR! find Python   // !! 未安裝python
gyp ERR! find Python Python is not set from command line or npm configuration
gyp ERR! find Python Python is not set from environment variable PYTHON

gyp ERR! build error 
gyp ERR! stack Error: not found: make // !! 未安裝編譯所需工具

解決:

apt-get install python3
ln -s /usr/bin/python3 /usr/bin/python  // 做鏈接
apt-get install build-essential

製作備忘:

cd /home/latelee/nodejs/node_arm/node
docker build -t nodejsapp .

docker tag nodejsapp registry.cn-hangzhou.aliyuncs.com/latelee/nodejsapp:armweb
docker push registry.cn-hangzhou.aliyuncs.com/latelee/nodejsapp:armweb

docker run -itd --rm -p 9000:3000 --name nodejsapp1 nodejsapp

docker run -itd --rm -p 3000:3000 --name nodejsapp1 registry.cn-hangzhou.aliyuncs.com/latelee/nodejsapp:armweb

docker load -i nodejsapp.img 
docker run -itd --rm -p 3000:3000 -v /mnt/data:/mnt/data --name nodejsapp1 registry.cn-hangzhou.aliyuncs.com/latelee/nodejsapp:armweb


docker run -itd --rm -p 3000:3000 -v /mnt/aaa/nodejsapp/node:/home/node -v /mnt/data:/mnt/data --name  nodejs nodebase

docker run -itd --rm -p 3000:3000 -v /mnt/data:/mnt/data --name nodejsapp nodejsapp

docker run -itd --rm -p 9000:3000 -v $PWD/data:/mnt/data --name nodejsapp nodejsapp
(注:導出3000端口,方便其它主機訪問。掛載/mnt/data以便訪問數據庫。

python 環境

運行容器:

docker run -itd --rm --name python -v $PWD:/home/python python:3.5-slim-stretch sh
docker exec -it python sh

注:該鏡像已經包含了 sqlite3 庫,無須額外安裝。

寫數據庫核心代碼:

import sqlite3

conn = sqlite3.connect("db.db")
cursor = conn.cursor()
cursor.execute("insert into user values (777,\"python11\",\"adminpython\")")

cursor.close()
conn.commit()
conn.close()

查詢數據庫:

import sqlite3

conn = sqlite3.connect("db.db")
cursor = conn.cursor()
cursor.execute("select * from user")
values = cursor.fetchall()
print(values)

cursor.close()
conn.commit()
conn.close()

結論:
同上,但在容器中可以寫數據庫。
另外,python 容器中寫數據庫,nodejs 容器中查詢數據庫,正常。

小結

sqlite 只需數據庫文件即可。適用於小型系統。本文測試發現 nodejs 容器無法寫數據庫(包括創建數據表)。
只要保證數據庫文件相同,跨容器可以操作數據庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章