既不建议生产Bun和LiteFS,所以我认为在fly.ioð p>
- 但是为什么?
最重要的是,Sqlite周围的景观作为托管解决方案几乎没有像Fly.io
面包非常擅长:
fly.io的litefs非常擅长:
项目树
- litefs 文件夹而不是实际安装的 litefs 路径,每当我们在本地进行测试和/或不在生产中进行测试。让我们只在目录中键入
mkdir litefs
,我们想用来通过bun run start
(或bun start
甚至npm start
)来测试此设置,如果存在节点并可用bun) -
.dockerignore
文件包含我们不应该推到docker 的所有可能的东西
-
Dockerfile
包含bun’s official alpine based docker image(总计s〜100mb)加上一些命令来引导服务器 -
fly.toml
包含脚手架Nodejs和LiteFS准备的示例的混合物看起来像 -
litefs.js
文件将数据库连接作为唯一模块输入点处理,以及一些基于模板的实用程序 -
package.json
用于提供start
命令和可选依赖项 -
serve.js
文件只是启动服务器演示,该演示显示一些欢迎和虚拟/示例中的所有行Sqlite数据库
所有文件也将与其内容一起显示。
在我们开始之前
The easiest way to scaffold a fly.io project is to use fly apps create
, which will generate a unique YOUR_FLY_APP_NAME
(see fly.toml later on) and it will give you indications of regions you can use要部署您的应用程序,然后您需要使用最接近的免费位置来进行create your LiteFS volume。
P.S。如果您不知道从哪里或如何开始,请使用LiteFS example,因为它最近已更新,并且在开始时确实可以使用(但是它使用GO (dehihi)在ð
之后完成此操作后,列表中的每个文件都是强制性的,这就是我作为每个文件内容所拥有的:
.dockerignore
.git
litefs
node_modules
.dockerignore
bun.lockb
Dockerfile
fly.toml
Dockerfile
### GLOBALS ###
ARG GLIBC_RELEASE=2.34-r0
### GET ###
FROM alpine:latest as get
# prepare environment
WORKDIR /tmp
RUN apk --no-cache add unzip
# get bun
ADD https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64.zip bun-linux-x64.zip
RUN unzip bun-linux-x64.zip
# get glibc
ARG GLIBC_RELEASE
RUN wget https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_RELEASE}/glibc-${GLIBC_RELEASE}.apk
### IMAGE ###
FROM alpine:latest
# install bun
COPY --from=get /tmp/bun-linux-x64/bun /usr/local/bin
# prepare glibc
ARG GLIBC_RELEASE
COPY --from=get /tmp/sgerrand.rsa.pub /etc/apk/keys
COPY --from=get /tmp/glibc-${GLIBC_RELEASE}.apk /tmp
# install glibc
RUN apk --no-cache --force-overwrite add /tmp/glibc-${GLIBC_RELEASE}.apk && \
# cleanup
rm /etc/apk/keys/sgerrand.rsa.pub && \
rm /tmp/glibc-${GLIBC_RELEASE}.apk && \
# smoke test
bun --version
#######################################################################
RUN mkdir /app
WORKDIR /app
# NPM will not install any package listed in "devDependencies" when NODE_ENV is set to "production",
# to install all modules: "npm install --production=false".
# Ref: https://docs.npmjs.com/cli/v9/commands/npm-install#description
ENV NODE_ENV production
COPY . .
RUN bun install
LABEL fly_launch_runtime="bun"
WORKDIR /app
ENV NODE_ENV production
CMD [ "bun", "run", "start" ]
fly.toml
app = "YOUR_FLY_APP_NAME"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[env]
PORT = "8080"
[experimental]
auto_rollback = true
enable_consul = true
[mounts]
source = "litefs"
destination = "/var/lib/litefs"
[[services]]
http_checks = []
internal_port = 8080
processes = ["app"]
protocol = "tcp"
script_checks = []
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"
[[services.ports]]
force_https = true
handlers = ["http"]
port = 80
[[services.ports]]
handlers = ["tls", "http"]
port = 443
[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"
litefs.js
import {existsSync} from 'node:fs';
import {join} from 'node:path';
import {Database} from 'bun:sqlite';
import createSQLiteTags from 'better-tags';
// use mounted point on production, use local folder otherwise
const litefs = join(
process.env.NODE_ENV === 'production' ? '/var/lib' : '.',
'litefs'
);
// if litefs folder doesn't exist get out!
if (!existsSync(litefs)) {
console.error('Unable to reach', litefs);
process.exit(1);
}
// shared db + template literals based utilities
const {db, get, all, values, exec, run, entries, transaction} =
createSQLiteTags(new Database(join(litefs, 'db')));
export {db, get, all, values, exec, run, entries, transaction};
///////////////////////////////////////////////////////////////
// FOR DEMO SAKE ONLY - EXECUTED ON EACH DEPLOY
///////////////////////////////////////////////////////////////
// some table schema
exec`
CREATE TABLE IF NOT EXISTS persons (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
phone TEXT NOT NULL,
company TEXT NOT NULL
)
`;
// some table entry
exec`
INSERT INTO persons
(name, phone, company)
VALUES
(${
crypto.randomUUID()
}, ${
('+' + (Date.now() * Math.random())).replace(/[^+\d]/, ' ')
}, 'fly.io')
`;
package.json
{
"name": "flying-bun",
"description": "A Bun & LiteFS love 💘 affair",
"type": "module",
"scripts": {
"start": "bun serve.js"
},
"dependencies": {
"better-tags": "^0.1.2"
}
}
服务
import {serve} from 'bun';
// grab the db or some utility
import {all} from './litefs.js';
// grab the port and start the server
const port = process.env.PORT || 3000;
serve({
fetch(request) {
const greeting = "<h1>Hello From Bun on Fly!</h1>";
const results = `<pre>${JSON.stringify(
all`SELECT * FROM persons ORDER BY id DESC`, null, '\t')
}</pre>`;
return new Response(greeting + '<br>' + results, {
headers: {'Content-Type': 'text/html; charset=utf-8'}
});
},
error(error) {
return new Response("Uh oh!!\n" + error.toString(), { status: 500 });
},
port
});
console.log(`Flying Bun app listening on port ${port}!`);
在litefs上部署面包
这几乎是这样,一旦您拥有唯一的应用程序名称,您可以访问的LiteFS已安装目录以及提供的代码,则可以在本地进行bun run start
,也许是在bun install
或npm install
之后,最后可以fly deploy
到fly deploy
到请参阅您的 Hello bun
如果一切顺利,您应该能够到达https://YOUR_FLY_APP_NAME.fly.dev
并查看页面中显示的至少一张记录。
一些指标
仅使用 bun 和 glibc 的基本高山图像,以及项目文件,应在允许的232 MB中消耗不超过40MB的RAM,但是 fly.io 的酷部分是,当您计划缩放CPU,RAM,重复数据库或同时,我们总是可以选择付费LL设法达到1 GB的 litefs 文件大小限制。 how to manage fly volumes can be found here的详细指南。
这就是所有人ð¥³
恭喜!您了解了如何在云上部署下一个BUN项目以及免费的数据库解决方案,该解决方案将免费托管GB,而不是仅限于单个DB,因此每个DB分开关注也是一种可能性(1对于IP地理位置,1用于博客文本,用户为1个,1 for管理。)
SQLITE作为数据库中最低估的部分,除了是地球上存在的最酷的嵌入式数据库外,没有秘密的用户和密码会泄漏,并且fly.io安装的文件系统也已被加密,因此整个课程都是这样。安全问题会自动从共享代码的人的所有方程式和责任中自动删除,就像我只是在此处完成ð
一样