需求:
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! sqlite3@4.2.0 install: `node-pre-gyp install --fallback-to-build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the sqlite3@4.2.0 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 sqlite3@4.2.0 and node@10.20.1 (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 容器无法写数据库(包括创建数据表)。
只要保证数据库文件相同,跨容器可以操作数据库。