May still have some issues, will figure them out along the waypull/442/head
parent
0195001e93
commit
0ba1806418
|
@ -29,10 +29,9 @@ jobs:
|
||||||
cache: npm
|
cache: npm
|
||||||
cache-dependency-path: desktop/package-lock.json
|
cache-dependency-path: desktop/package-lock.json
|
||||||
- name: Setup Deno
|
- name: Setup Deno
|
||||||
# uses: denoland/setup-deno@v1
|
|
||||||
uses: denoland/setup-deno@d4873ceeec10de6275fecd1f94b6985369d40231
|
uses: denoland/setup-deno@d4873ceeec10de6275fecd1f94b6985369d40231
|
||||||
with:
|
with:
|
||||||
deno-version: v1.32.5
|
deno-version: v1.33
|
||||||
- name: Build SilverBullet
|
- name: Build SilverBullet
|
||||||
run: deno task build
|
run: deno task build
|
||||||
- name: Create SilverBullet bundle
|
- name: Create SilverBullet bundle
|
||||||
|
@ -76,4 +75,3 @@ jobs:
|
||||||
desktop/out/**/*.nupkg
|
desktop/out/**/*.nupkg
|
||||||
desktop/out/**/*.rpm
|
desktop/out/**/*.rpm
|
||||||
desktop/out/**/*.zip
|
desktop/out/**/*.zip
|
||||||
dist/silverbullet.js
|
|
||||||
|
|
|
@ -2,10 +2,11 @@ name: Docker
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ["main"]
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker-build-push:
|
docker-build-push-release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
@ -15,12 +16,12 @@ jobs:
|
||||||
- name: Setup Deno
|
- name: Setup Deno
|
||||||
uses: denoland/setup-deno@d4873ceeec10de6275fecd1f94b6985369d40231
|
uses: denoland/setup-deno@d4873ceeec10de6275fecd1f94b6985369d40231
|
||||||
with:
|
with:
|
||||||
deno-version: v1.32.5
|
deno-version: v1.33
|
||||||
|
|
||||||
- name: Run bundle build
|
- name: Run bundle build
|
||||||
run: |
|
run: |
|
||||||
deno task build
|
deno task build
|
||||||
deno task bundle
|
deno task compile
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
|
@ -33,4 +34,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
tags: zefhemel/silverbullet:latest
|
tags: |
|
||||||
|
zefhemel/silverbullet:latest
|
||||||
|
zefhemel/silverbullet:${{ github.ref.split('/').last() }}
|
|
@ -0,0 +1,38 @@
|
||||||
|
name: Server
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["main", "compile"]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Setup repo
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup Deno
|
||||||
|
uses: denoland/setup-deno@d4873ceeec10de6275fecd1f94b6985369d40231
|
||||||
|
with:
|
||||||
|
deno-version: v1.33
|
||||||
|
|
||||||
|
- name: Build bundles
|
||||||
|
run: |
|
||||||
|
deno task build
|
||||||
|
|
||||||
|
- name: Compile for all platforms
|
||||||
|
run: |
|
||||||
|
deno task server:dist:linux-x86_64
|
||||||
|
deno task server:dist:darwin-x86_64
|
||||||
|
deno task server:dist:darwin-aarch64
|
||||||
|
deno task server:dist:windows-x86_64
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
draft: true
|
||||||
|
files: |
|
||||||
|
silverbullet-*.zip
|
|
@ -11,3 +11,7 @@ publish-data.db
|
||||||
.idea
|
.idea
|
||||||
deno.lock
|
deno.lock
|
||||||
node_modules
|
node_modules
|
||||||
|
*.zip
|
||||||
|
silverbullet-*
|
||||||
|
silverbullet.*
|
||||||
|
silverbullet
|
|
@ -17,7 +17,6 @@ tasks:
|
||||||
- name: Setup
|
- name: Setup
|
||||||
init: |
|
init: |
|
||||||
deno task build
|
deno task build
|
||||||
deno task install
|
|
||||||
gp sync-done setup
|
gp sync-done setup
|
||||||
- name: Server watcher
|
- name: Server watcher
|
||||||
init: |
|
init: |
|
||||||
|
|
13
Dockerfile
13
Dockerfile
|
@ -1,4 +1,7 @@
|
||||||
FROM denoland/deno:alpine-1.28.3
|
FROM frolvlad/alpine-glibc:alpine-3.17
|
||||||
|
|
||||||
|
RUN apk add tini
|
||||||
|
RUN adduser -D -H -u 1000 silverbullet
|
||||||
|
|
||||||
# The volume that will keep the space data
|
# The volume that will keep the space data
|
||||||
# Create a volume first:
|
# Create a volume first:
|
||||||
|
@ -8,14 +11,14 @@ FROM denoland/deno:alpine-1.28.3
|
||||||
VOLUME /space
|
VOLUME /space
|
||||||
|
|
||||||
# Copy the bundled version of silverbullet into the container
|
# Copy the bundled version of silverbullet into the container
|
||||||
ADD ./dist/silverbullet.js /silverbullet.js
|
ADD ./bin/silverbullet /silverbullet
|
||||||
|
|
||||||
# Make sure the deno user has access to the space volume
|
# Make sure the deno user has access to the space volume
|
||||||
RUN mkdir -p /space
|
RUN mkdir -p /space
|
||||||
RUN chown -R deno:deno /space
|
RUN chown -R silverbullet /space
|
||||||
|
|
||||||
# deno user id is 1000 in alpine image
|
# deno user id is 1000 in alpine image
|
||||||
USER deno
|
#USER silverbullet
|
||||||
|
|
||||||
# Expose port 3000
|
# Expose port 3000
|
||||||
# Port map this when running, e.g. with -p 3002:3000 (where 3002 is the host port)
|
# Port map this when running, e.g. with -p 3002:3000 (where 3002 is the host port)
|
||||||
|
@ -23,4 +26,4 @@ EXPOSE 3000
|
||||||
|
|
||||||
# Run the server, allowing to pass in additional argument at run time, e.g.
|
# Run the server, allowing to pass in additional argument at run time, e.g.
|
||||||
# docker run -p 3002:3000 -v myspace:/space -it zefhemel/silverbullet --user me:letmein
|
# docker run -p 3002:3000 -v myspace:/space -it zefhemel/silverbullet --user me:letmein
|
||||||
ENTRYPOINT ["/tini", "--", "deno", "run", "-A", "--unstable", "/silverbullet.js", "--hostname", "0.0.0.0", "/space"]
|
ENTRYPOINT ["tini", "--", "/silverbullet", "--hostname", "0.0.0.0", "/space"]
|
||||||
|
|
|
@ -17,7 +17,7 @@ export function serveCommand(options: any, folder: string) {
|
||||||
|
|
||||||
if (hostname === "127.0.0.1") {
|
if (hostname === "127.0.0.1") {
|
||||||
console.log(
|
console.log(
|
||||||
`_Note:_ SilverBullet will only be available locally (via http://localhost:${port}), to allow outside connections, pass --host 0.0.0.0 as a flag.`,
|
`_Note:_ SilverBullet will only be available locally (via http://localhost:${port}), to allow outside connections, pass --hostname 0.0.0.0 as a flag.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,74 @@
|
||||||
import { version } from "../version.ts";
|
import { version } from "../version.ts";
|
||||||
|
import { dirname } from "https://deno.land/std@0.186.0/path/mod.ts";
|
||||||
|
|
||||||
|
const silverBulletReleases =
|
||||||
|
"https://github.com/silverbulletmd/silverbullet/releases";
|
||||||
|
|
||||||
export async function upgradeCommand() {
|
export async function upgradeCommand() {
|
||||||
console.log("Now going to attempt an upgrade...");
|
console.log("Now going to attempt an upgrade...");
|
||||||
|
|
||||||
const p = Deno.run({
|
const resp = await fetch(`${silverBulletReleases}/latest`, {
|
||||||
cmd: ["deno", "cache", "--reload", Deno.mainModule],
|
redirect: "manual",
|
||||||
});
|
});
|
||||||
const exitCode = await p.status();
|
const versionedUrl = resp.headers.get("location")!;
|
||||||
if (!exitCode.success) {
|
const latestVersion = /([^\/]+)$/.exec(versionedUrl);
|
||||||
console.error("Something went wrong there...");
|
if (!latestVersion) {
|
||||||
Deno.exit(1);
|
console.error("Could not fetch latest version");
|
||||||
|
}
|
||||||
|
if (version === latestVersion![0]) {
|
||||||
|
console.log("No version available, we're done here!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
console.log(
|
console.log(
|
||||||
"So, that's done. Now let's see if this actually did anything...",
|
"New version available:",
|
||||||
|
latestVersion![0],
|
||||||
|
"which I will now personally download. Hang on...",
|
||||||
);
|
);
|
||||||
const vp = Deno.run({
|
const installDir = dirname(new URL(Deno.mainModule).pathname);
|
||||||
cmd: ["deno", "run", "-A", "--unstable", Deno.mainModule, "version"],
|
|
||||||
stdout: "piped",
|
const tmpDir = Deno.makeTempDirSync();
|
||||||
|
// const zipUrl = "https://github.com/silverbulletmd/silverbullet/releases/download/test-release/silverbullet-server-apple-aarch64.zip";
|
||||||
|
const zipUrl =
|
||||||
|
`${versionedUrl}/download/silverbullet-server-${Deno.build.os}-${Deno.build.arch}.zip`;
|
||||||
|
const zipPath = `${tmpDir}/silverbullet.zip`;
|
||||||
|
const command = new Deno.Command("curl", {
|
||||||
|
args: [
|
||||||
|
"-L",
|
||||||
|
"-o",
|
||||||
|
zipPath,
|
||||||
|
zipUrl,
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const versionStatus = await vp.status();
|
const curlOutput = await command.output();
|
||||||
if (!versionStatus.success) {
|
console.log(
|
||||||
console.error("Could not run version command, something is wrong.");
|
"Now going to replace the existing silverbullet binary in",
|
||||||
Deno.exit(1);
|
installDir,
|
||||||
}
|
);
|
||||||
const rawVersion = await vp.output();
|
if (curlOutput.code !== 0) {
|
||||||
const newVersion = new TextDecoder().decode(rawVersion).trim();
|
console.error(
|
||||||
if (newVersion === version) {
|
"Download failed",
|
||||||
console.log(
|
new TextDecoder().decode(curlOutput.stderr),
|
||||||
`Nope. I hate to tell you this, but it looks like we're still running ${newVersion}. This was a bit of a futile exercise. Let's try again soon some time.`,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.log(
|
|
||||||
`Congrats, we've upgraded you from ${version} to ${newVersion}. Seems like quite a bump, enjoy! https://silverbullet.md/CHANGELOG may give you more hints on what's new.`,
|
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unzipCommand = new Deno.Command("unzip", {
|
||||||
|
args: [
|
||||||
|
"-o",
|
||||||
|
"-d",
|
||||||
|
installDir,
|
||||||
|
`${tmpDir}/silverbullet.zip`,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const zipOutput = await unzipCommand.output();
|
||||||
|
if (zipOutput.code !== 0) {
|
||||||
|
console.error(
|
||||||
|
"Download failed",
|
||||||
|
new TextDecoder().decode(curlOutput.stderr),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await Deno.chmod(`${installDir}/silverbullet`, 0o755);
|
||||||
|
await Deno.remove(zipPath);
|
||||||
|
console.log("And done! Restart your server to get the latest and greatest!");
|
||||||
}
|
}
|
||||||
|
|
12
deno.jsonc
12
deno.jsonc
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"clean": "rm -rf dist dist_bundle",
|
"clean": "rm -rf dist dist_bundle",
|
||||||
"install": "deno install -f -A --unstable --importmap import_map.json silverbullet.ts",
|
|
||||||
"check": "find web common server plugs cmd plug-api plugos -name '*.ts*' | xargs deno check",
|
"check": "find web common server plugs cmd plug-api plugos -name '*.ts*' | xargs deno check",
|
||||||
"test": "deno test -A --unstable",
|
"test": "deno test -A --unstable",
|
||||||
"build": "deno run -A --unstable build_plugs.ts && deno run -A --unstable build_web.ts",
|
"build": "deno run -A --unstable build_plugs.ts && deno run -A --unstable build_web.ts",
|
||||||
|
@ -9,18 +8,21 @@
|
||||||
"watch-web": "deno run -A --unstable --check build_web.ts --watch",
|
"watch-web": "deno run -A --unstable --check build_web.ts --watch",
|
||||||
"server": "deno run -A --unstable --check silverbullet.ts",
|
"server": "deno run -A --unstable --check silverbullet.ts",
|
||||||
"watch-server": "deno run -A --unstable --check --watch silverbullet.ts",
|
"watch-server": "deno run -A --unstable --check --watch silverbullet.ts",
|
||||||
// The only reason to run a shell script is that deno task doesn't support globs yet (e.g. *.plug.yaml)
|
|
||||||
"watch-plugs": "deno run -A --unstable --check build_plugs.ts -w",
|
"watch-plugs": "deno run -A --unstable --check build_plugs.ts -w",
|
||||||
"bundle": "deno bundle silverbullet.ts dist/silverbullet.js",
|
"compile": "mkdir -p bin && deno compile -A --unstable --include plugos/environments/sandbox_worker.ts --include plugos/sqlite/worker.ts -o bin/silverbullet silverbullet.ts",
|
||||||
|
"server:dist:linux-x86_64": "deno compile -A --unstable --target x86_64-unknown-linux-gnu --include plugos/environments/sandbox_worker.ts --include plugos/sqlite/worker.ts silverbullet.ts -o silverbullet && zip silverbullet-server-linux-x86_64.zip silverbullet",
|
||||||
|
"server:dist:darwin-x86_64": "deno compile -A --unstable --target x86_64-apple-darwin --include plugos/environments/sandbox_worker.ts --include plugos/sqlite/worker.ts silverbullet.ts -o silverbullet && zip silverbullet-server-darwin-x86_64.zip silverbullet",
|
||||||
|
"server:dist:darwin-aarch64": "deno compile -A --unstable --target aarch64-apple-darwin --include plugos/environments/sandbox_worker.ts --include plugos/sqlite/worker.ts silverbullet.ts -o silverbullet && zip silverbullet-server-darwin-aarch64.zip silverbullet",
|
||||||
|
"server:dist:windows-x86_64": "deno compile -A --unstable --target x86_64-pc-windows-msvc --include plugos/environments/sandbox_worker.ts --include plugos/sqlite/worker.ts silverbullet.ts -o silverbullet.exe && zip silverbullet-server-windows-x86_64.zip silverbullet.exe",
|
||||||
// Regenerates some bundle files (checked into the repo)
|
// Regenerates some bundle files (checked into the repo)
|
||||||
// Install lezer-generator with "npm install -g @lezer/generator"
|
// Install lezer-generator with "npm install -g @lezer/generator"
|
||||||
"generate": "deno run -A plugos/gen.ts && lezer-generator common/markdown_parser/query.grammar -o common/markdown_parser/parse-query.js",
|
"generate": "lezer-generator common/markdown_parser/query.grammar -o common/markdown_parser/parse-query.js",
|
||||||
// Install npm dependencies for desktop app
|
// Install npm dependencies for desktop app
|
||||||
"desktop:deps": "cd desktop && npm install",
|
"desktop:deps": "cd desktop && npm install",
|
||||||
// Run the desktop app for local development
|
// Run the desktop app for local development
|
||||||
"desktop:run": "cd desktop && npm start",
|
"desktop:run": "cd desktop && npm start",
|
||||||
// Build the desktop app as a package for this platform
|
// Build the desktop app as a package for this platform
|
||||||
"desktop:build": "deno task build && deno task bundle && cd desktop && npm run make",
|
"desktop:build": "deno task build && deno task compile && cd desktop && npm run make",
|
||||||
// Mobile
|
// Mobile
|
||||||
"mobile:deps": "cd mobile && npm install",
|
"mobile:deps": "cd mobile && npm install",
|
||||||
"mobile:clean-build": "deno task clean && deno task plugs && deno run -A --unstable --check build_mobile.ts && cd mobile && npx cap sync",
|
"mobile:clean-build": "deno task clean && deno task plugs && deno run -A --unstable --check build_mobile.ts && cd mobile && npx cap sync",
|
||||||
|
|
|
@ -13,35 +13,10 @@ import { platform } from "node:os";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import decompress from "decompress";
|
import decompress from "decompress";
|
||||||
import { downloadFile } from "./http_util";
|
|
||||||
|
|
||||||
const denoVersion = "v1.29.1";
|
const silverbulletServerExecutable = platform() === "win32"
|
||||||
|
? "silverbullet.exe"
|
||||||
const denoZip: Record<string, string> = {
|
: "silverbullet";
|
||||||
"win32-x64": "deno-x86_64-pc-windows-msvc.zip",
|
|
||||||
"darwin-x64": "deno-x86_64-apple-darwin.zip",
|
|
||||||
"darwin-arm64": "deno-aarch64-apple-darwin.zip",
|
|
||||||
"linux-x64": "deno-x86_64-unknown-linux-gnu.zip",
|
|
||||||
};
|
|
||||||
|
|
||||||
const denoExecutableResource = platform() === "win32"
|
|
||||||
? "resources/deno.exe"
|
|
||||||
: "resources/deno";
|
|
||||||
|
|
||||||
async function downloadDeno(platform: string, arch: string): Promise<void> {
|
|
||||||
const folder = fs.mkdtempSync("deno-download");
|
|
||||||
const destFile = path.join(folder, "deno.zip");
|
|
||||||
const zipFile = denoZip[`${platform}-${arch}`];
|
|
||||||
if (!zipFile) {
|
|
||||||
throw new Error(`No deno binary for ${platform}-${arch}`);
|
|
||||||
}
|
|
||||||
await downloadFile(
|
|
||||||
`https://github.com/denoland/deno/releases/download/${denoVersion}/${zipFile}`,
|
|
||||||
destFile,
|
|
||||||
);
|
|
||||||
await decompress(destFile, "resources");
|
|
||||||
fs.rmSync(folder, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const config: ForgeConfig = {
|
const config: ForgeConfig = {
|
||||||
packagerConfig: {
|
packagerConfig: {
|
||||||
|
@ -51,7 +26,7 @@ const config: ForgeConfig = {
|
||||||
: "SilverBullet",
|
: "SilverBullet",
|
||||||
icon: "../web/images/logo",
|
icon: "../web/images/logo",
|
||||||
appBundleId: "md.silverbullet",
|
appBundleId: "md.silverbullet",
|
||||||
extraResource: [denoExecutableResource, "resources/silverbullet.js", "resources/logo.png"],
|
extraResource: [`resources/${silverbulletServerExecutable}`, "resources/logo.png"],
|
||||||
beforeCopyExtraResources: [(
|
beforeCopyExtraResources: [(
|
||||||
_buildPath: string,
|
_buildPath: string,
|
||||||
_electronVersion: string,
|
_electronVersion: string,
|
||||||
|
@ -59,14 +34,9 @@ const config: ForgeConfig = {
|
||||||
arch: TargetArch,
|
arch: TargetArch,
|
||||||
callback: (err?: Error | null) => void,
|
callback: (err?: Error | null) => void,
|
||||||
) => {
|
) => {
|
||||||
if (fs.existsSync(denoExecutableResource)) {
|
|
||||||
fs.rmSync(denoExecutableResource, { force: true });
|
|
||||||
}
|
|
||||||
Promise.resolve().then(async () => {
|
Promise.resolve().then(async () => {
|
||||||
// Download deno
|
// Copy silverbullet server executable
|
||||||
await downloadDeno(platform, arch);
|
fs.copyFileSync(`../bin/${silverbulletServerExecutable}`, `resources/${silverbulletServerExecutable}`);
|
||||||
// Copy silverbullet.js
|
|
||||||
fs.copyFileSync("../dist/silverbullet.js", "resources/silverbullet.js");
|
|
||||||
fs.copyFileSync("../web/images/logo.png", "resources/logo.png");
|
fs.copyFileSync("../web/images/logo.png", "resources/logo.png");
|
||||||
}).then((r) => callback()).catch(callback);
|
}).then((r) => callback()).catch(callback);
|
||||||
}],
|
}],
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
import axios from "axios";
|
|
||||||
import fs from "node:fs";
|
|
||||||
|
|
||||||
export async function downloadFile(
|
|
||||||
url: string,
|
|
||||||
destFile: string,
|
|
||||||
): Promise<void> {
|
|
||||||
const file = fs.createWriteStream(destFile);
|
|
||||||
let response = await axios.request({
|
|
||||||
url: url,
|
|
||||||
method: "GET",
|
|
||||||
responseType: "stream",
|
|
||||||
});
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
response.data.pipe(file);
|
|
||||||
let error: Error | null = null;
|
|
||||||
file.on("error", (e) => {
|
|
||||||
error = e;
|
|
||||||
reject(e);
|
|
||||||
});
|
|
||||||
file.on("close", () => {
|
|
||||||
if (error) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -32,20 +32,20 @@ type Instance = {
|
||||||
export const runningServers = new Map<string, Instance>();
|
export const runningServers = new Map<string, Instance>();
|
||||||
|
|
||||||
// Should work for Liux and Mac
|
// Should work for Liux and Mac
|
||||||
let denoPath = `${process.resourcesPath}/deno`;
|
let silverBulletServerPath = `${process.resourcesPath}/silverbullet`;
|
||||||
|
|
||||||
// If not...
|
// If not...
|
||||||
if (!existsSync(denoPath)) {
|
if (!existsSync(silverBulletServerPath)) {
|
||||||
// Windows
|
// Windows
|
||||||
if (platform() === "win32") {
|
if (platform() === "win32") {
|
||||||
if (existsSync(`${process.resourcesPath}/deno.exe`)) {
|
if (existsSync(`${process.resourcesPath}/silverbullet.exe`)) {
|
||||||
denoPath = `${process.resourcesPath}/deno.exe`;
|
silverBulletServerPath = `${process.resourcesPath}/silverbullet.exe`;
|
||||||
} else {
|
} else {
|
||||||
denoPath = "deno.exe";
|
silverBulletServerPath = "silverbullet.exe";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Everything else
|
// Everything else
|
||||||
denoPath = "deno";
|
silverBulletServerPath = "silverbullet";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,16 +73,6 @@ export async function openFolder(windowState: WindowState): Promise<void> {
|
||||||
newWindow(instance, windowState);
|
newWindow(instance, windowState);
|
||||||
}
|
}
|
||||||
|
|
||||||
function determineSilverBulletScriptPath(): string {
|
|
||||||
let scriptPath = `${process.resourcesPath}/silverbullet.js`;
|
|
||||||
if (!existsSync(scriptPath)) {
|
|
||||||
console.log("Dev mode");
|
|
||||||
// Assumption: we're running in dev mode (npm start)
|
|
||||||
scriptPath = "../silverbullet.ts";
|
|
||||||
}
|
|
||||||
return scriptPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function spawnInstance(pagePath: string): Promise<Instance> {
|
async function spawnInstance(pagePath: string): Promise<Instance> {
|
||||||
let instance = runningServers.get(pagePath);
|
let instance = runningServers.get(pagePath);
|
||||||
if (instance) {
|
if (instance) {
|
||||||
|
@ -94,11 +84,7 @@ async function spawnInstance(pagePath: string): Promise<Instance> {
|
||||||
portfinder.setHighestPort(3999);
|
portfinder.setHighestPort(3999);
|
||||||
const port = await portfinder.getPortPromise();
|
const port = await portfinder.getPortPromise();
|
||||||
|
|
||||||
const proc = spawn(denoPath, [
|
const proc = spawn(silverBulletServerPath, [
|
||||||
"run",
|
|
||||||
"-A",
|
|
||||||
"--unstable",
|
|
||||||
determineSilverBulletScriptPath(),
|
|
||||||
"--port",
|
"--port",
|
||||||
"" + port,
|
"" + port,
|
||||||
pagePath,
|
pagePath,
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if ! command -v unzip >/dev/null; then
|
||||||
|
echo "Error: unzip is required to install SilverBullet." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $(uname -sm) in
|
||||||
|
"Darwin x86_64") target="darwin-x86_64" ;;
|
||||||
|
"Darwin arm64") target="darwin-aarch64" ;;
|
||||||
|
"Linux aarch64")
|
||||||
|
echo "Error: Official SilverBullet builds for Linux aarch64 are not available." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*) target="linux-x86_64" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "Installing for $target"
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
sb_uri="https://github.com/silverbulletmd/silverbullet/releases/latest/download/silverbullet-server-${target}.zip"
|
||||||
|
else
|
||||||
|
sb_uri="https://github.com/silverbulletmd/silverbullet/releases/download/${1}/silverbullet-server-${target}.zip"
|
||||||
|
fi
|
||||||
|
exe=silverbullet
|
||||||
|
bin_dir=.
|
||||||
|
|
||||||
|
curl --fail --location --progress-bar --output "$exe.zip" "$sb_uri"
|
||||||
|
unzip -d "$bin_dir" -o "$exe.zip"
|
||||||
|
chmod +x "$exe"
|
||||||
|
rm "$exe.zip"
|
||||||
|
|
||||||
|
echo "SilverBullet server was installed successfully to $bin, run it directly via ./$exe or move it to a more convenient place."
|
|
@ -30,20 +30,24 @@ class DenoWorkerWrapper implements WorkerLike {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import workerBundleJson from "./worker_bundle.json" assert { type: "json" };
|
// import workerBundleJson from "./worker_bundle.json" assert { type: "json" };
|
||||||
|
|
||||||
const workerBundle = new AssetBundle(workerBundleJson);
|
// const workerBundle = new AssetBundle(workerBundleJson);
|
||||||
|
|
||||||
|
// import "./sandbox_worker.ts";
|
||||||
|
|
||||||
export function createSandbox(plug: Plug<any>) {
|
export function createSandbox(plug: Plug<any>) {
|
||||||
const workerHref = URL.createObjectURL(
|
// const workerHref = URL.createObjectURL(
|
||||||
new Blob([
|
// new Blob([
|
||||||
workerBundle.readFileSync("worker.js"),
|
// workerBundle.readFileSync("worker.js"),
|
||||||
], {
|
// ], {
|
||||||
type: "application/javascript",
|
// type: "application/javascript",
|
||||||
}),
|
// }),
|
||||||
);
|
// );
|
||||||
const worker = new Worker(
|
const worker = new Worker(
|
||||||
workerHref,
|
// workerHref,
|
||||||
|
// import.meta.resolve("./sandbox_worker.ts"),
|
||||||
|
new URL("./sandbox_worker.ts", import.meta.url),
|
||||||
{
|
{
|
||||||
type: "module",
|
type: "module",
|
||||||
deno: {
|
deno: {
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"worker.js": "data:application/javascript;base64,KCgpID0+IHsgdmFyIG1vZD0oKCk9PntmdW5jdGlvbiBsKHQpe3QoKS5jYXRjaChlPT57Y29uc29sZS5lcnJvcigiQ2F1Z2h0IGVycm9yIixlLm1lc3NhZ2UpfSl9dmFyIGE9Y2xhc3N7Y29uc3RydWN0b3IoZSxuPSEwKXt0aGlzLnByaW50PW4sdGhpcy5jYWxsYmFjaz1lfWxvZyguLi5lKXt0aGlzLnB1c2goImxvZyIsZSl9d2FybiguLi5lKXt0aGlzLnB1c2goIndhcm4iLGUpfWVycm9yKC4uLmUpe3RoaXMucHVzaCgiZXJyb3IiLGUpfWluZm8oLi4uZSl7dGhpcy5wdXNoKCJpbmZvIixlKX1wdXNoKGUsbil7dGhpcy5jYWxsYmFjayhlLHRoaXMubG9nTWVzc2FnZShuKSksdGhpcy5wcmludCYmY29uc29sZVtlXSguLi5uKX1sb2dNZXNzYWdlKGUpe2xldCBuPVtdO2ZvcihsZXQgciBvZiBlKXN3aXRjaCh0eXBlb2Ygcil7Y2FzZSJzdHJpbmciOmNhc2UibnVtYmVyIjpuLnB1c2goIiIrcik7YnJlYWs7Y2FzZSJ1bmRlZmluZWQiOm4ucHVzaCgidW5kZWZpbmVkIik7YnJlYWs7ZGVmYXVsdDp0cnl7bGV0IHM9SlNPTi5zdHJpbmdpZnkocixudWxsLDIpO3MubGVuZ3RoPjUwMCYmKHM9cy5zdWJzdHJpbmcoMCw1MDApKyIuLi4iKSxuLnB1c2gocyl9Y2F0Y2h7bi5wdXNoKCJbY2lyY3VsYXIgb2JqZWN0XSIpfX1yZXR1cm4gbi5qb2luKCIgIil9fTtmdW5jdGlvbiBkKHQpe2xldCBlPWF0b2IodCksbj1lLmxlbmd0aCxyPW5ldyBVaW50OEFycmF5KG4pO2ZvcihsZXQgcz0wO3M8bjtzKyspcltzXT1lLmNoYXJDb2RlQXQocyk7cmV0dXJuIHJ9ZnVuY3Rpb24geSh0LGUpe3JldHVybiBzeXNjYWxsKCJzYW5kYm94RmV0Y2guZmV0Y2giLHQsZSl9ZnVuY3Rpb24gdSgpe2dsb2JhbFRoaXMuZmV0Y2g9YXN5bmMgZnVuY3Rpb24odCxlKXtsZXQgbj1hd2FpdCB5KHQsZSYme21ldGhvZDplLm1ldGhvZCxoZWFkZXJzOmUuaGVhZGVycyxib2R5OmUuYm9keX0pO3JldHVybiBuZXcgUmVzcG9uc2Uobi5iYXNlNjRCb2R5P2Qobi5iYXNlNjRCb2R5KTpudWxsLHtzdGF0dXM6bi5zdGF0dXMsaGVhZGVyczpuLmhlYWRlcnN9KX19dHlwZW9mIERlbm8+InUiJiYoc2VsZi5EZW5vPXthcmdzOltdLGJ1aWxkOnthcmNoOiJ4ODZfNjQifSxlbnY6e2dldCgpe319fSk7dmFyIGc9bmV3IE1hcCxpPW5ldyBNYXA7ZnVuY3Rpb24gbyh0KXt0eXBlb2Ygd2luZG93PCJ1IiYmd2luZG93LnBhcmVudCE9PXdpbmRvdz93aW5kb3cucGFyZW50LnBvc3RNZXNzYWdlKHQsIioiKTpzZWxmLnBvc3RNZXNzYWdlKHQpfXZhciBjPTA7c2VsZi5zeXNjYWxsPWFzeW5jKHQsLi4uZSk9PmF3YWl0IG5ldyBQcm9taXNlKChuLHIpPT57YysrLGkuc2V0KGMse3Jlc29sdmU6bixyZWplY3Q6cn0pLG8oe3R5cGU6InN5c2NhbGwiLGlkOmMsbmFtZTp0LGFyZ3M6ZX0pfSk7dmFyIHA9bmV3IE1hcDtzZWxmLnJlcXVpcmU9dD0+e2xldCBlPXAuZ2V0KHQpO2lmKCFlKXRocm93IG5ldyBFcnJvcihgRHluYW1pY2FsbHkgaW1wb3J0aW5nIG5vbi1wcmVsb2FkZWQgbGlicmFyeSAke3R9YCk7cmV0dXJuIGV9O3NlbGYuY29uc29sZT1uZXcgYSgodCxlKT0+e28oe3R5cGU6ImxvZyIsbGV2ZWw6dCxtZXNzYWdlOmV9KX0sITEpO2Z1bmN0aW9uIGgodCl7cmV0dXJuYHJldHVybiAoJHt0fSlbImRlZmF1bHQiXWB9c2VsZi5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIix0PT57bChhc3luYygpPT57bGV0IGU9dC5kYXRhO3N3aXRjaChlLnR5cGUpe2Nhc2UibG9hZCI6e2xldCBuPW5ldyBGdW5jdGlvbihoKGUuY29kZSkpO2cuc2V0KGUubmFtZSxuKCkpLG8oe3R5cGU6ImluaXRlZCIsbmFtZTplLm5hbWV9KX1icmVhaztjYXNlImxvYWQtZGVwZW5kZW5jeSI6e2xldCByPW5ldyBGdW5jdGlvbihgcmV0dXJuICR7ZS5jb2RlfWApKCk7cC5zZXQoZS5uYW1lLHIpLG8oe3R5cGU6ImRlcGVuZGVuY3ktaW5pdGVkIixuYW1lOmUubmFtZX0pfWJyZWFrO2Nhc2UiaW52b2tlIjp7bGV0IG49Zy5nZXQoZS5uYW1lKTtpZighbil0aHJvdyBuZXcgRXJyb3IoYEZ1bmN0aW9uIG5vdCBsb2FkZWQ6ICR7ZS5uYW1lfWApO3RyeXtsZXQgcj1hd2FpdCBQcm9taXNlLnJlc29sdmUobiguLi5lLmFyZ3N8fFtdKSk7byh7dHlwZToicmVzdWx0IixpZDplLmlkLHJlc3VsdDpyfSl9Y2F0Y2gocil7byh7dHlwZToicmVzdWx0IixpZDplLmlkLGVycm9yOnIubWVzc2FnZSxzdGFjazpyLnN0YWNrfSl9fWJyZWFrO2Nhc2Uic3lzY2FsbC1yZXNwb25zZSI6e2xldCBuPWUuaWQscj1pLmdldChuKTtpZighcil0aHJvdyBjb25zb2xlLmxvZygiQ3VycmVudCBvdXRzdGFuZGluZyByZXF1ZXN0cyIsaSwibG9va2luZyB1cCIsbiksRXJyb3IoIkludmFsaWQgcmVxdWVzdCBpZCIpO2kuZGVsZXRlKG4pLGUuZXJyb3I/ci5yZWplY3QobmV3IEVycm9yKGUuZXJyb3IpKTpyLnJlc29sdmUoZS5yZXN1bHQpfWJyZWFrfX0pfSk7dSgpO30pKCk7CiByZXR1cm4gbW9kO30pKCk="
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
import { AssetBundle } from "./asset_bundle/bundle.ts";
|
|
||||||
import { compile } from "./compile.ts";
|
|
||||||
|
|
||||||
console.log("Generating sandbox worker...");
|
|
||||||
const bundlePath =
|
|
||||||
new URL("./environments/worker_bundle.json", import.meta.url).pathname;
|
|
||||||
const workerPath =
|
|
||||||
new URL("./environments/sandbox_worker.ts", import.meta.url).pathname;
|
|
||||||
|
|
||||||
const workerCode = await compile(workerPath);
|
|
||||||
|
|
||||||
const assetBundle = new AssetBundle();
|
|
||||||
assetBundle.writeTextFileSync("worker.js", workerCode);
|
|
||||||
Deno.writeTextFile(
|
|
||||||
bundlePath,
|
|
||||||
JSON.stringify(assetBundle.toJSON(), null, 2),
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log(`Wrote updated bundle to ${bundlePath}`);
|
|
||||||
|
|
||||||
console.log("Now generating SQLite worker...");
|
|
||||||
const sqliteBundlePath =
|
|
||||||
new URL("./sqlite/worker_bundle.json", import.meta.url).pathname;
|
|
||||||
const sqliteWorkerPath =
|
|
||||||
new URL("./sqlite/worker.ts", import.meta.url).pathname;
|
|
||||||
|
|
||||||
const sqliteWorkerCode = await compile(sqliteWorkerPath);
|
|
||||||
|
|
||||||
const sqliteAssetBundle = new AssetBundle();
|
|
||||||
sqliteAssetBundle.writeTextFileSync("worker.js", sqliteWorkerCode);
|
|
||||||
Deno.writeTextFile(
|
|
||||||
sqliteBundlePath,
|
|
||||||
JSON.stringify(sqliteAssetBundle.toJSON(), null, 2),
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log(`Wrote updated bundle to ${sqliteBundlePath}`);
|
|
||||||
Deno.exit(0);
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { AssetBundle } from "../asset_bundle/bundle.ts";
|
// import { AssetBundle } from "../asset_bundle/bundle.ts";
|
||||||
import { ISQLite } from "./sqlite_interface.ts";
|
import { ISQLite } from "./sqlite_interface.ts";
|
||||||
import workerBundleJson from "./worker_bundle.json" assert { type: "json" };
|
// import workerBundleJson from "./worker_bundle.json" assert { type: "json" };
|
||||||
|
|
||||||
const workerBundle = new AssetBundle(workerBundleJson);
|
// const workerBundle = new AssetBundle(workerBundleJson);
|
||||||
|
|
||||||
export class AsyncSQLite implements ISQLite {
|
export class AsyncSQLite implements ISQLite {
|
||||||
worker: Worker;
|
worker: Worker;
|
||||||
|
@ -13,15 +13,17 @@ export class AsyncSQLite implements ISQLite {
|
||||||
>();
|
>();
|
||||||
|
|
||||||
constructor(readonly dbPath: string) {
|
constructor(readonly dbPath: string) {
|
||||||
const workerHref = URL.createObjectURL(
|
// const workerHref = URL.createObjectURL(
|
||||||
new Blob([
|
// new Blob([
|
||||||
workerBundle.readFileSync("worker.js"),
|
// workerBundle.readFileSync("worker.js"),
|
||||||
], {
|
// ], {
|
||||||
type: "application/javascript",
|
// type: "application/javascript",
|
||||||
}),
|
// }),
|
||||||
);
|
// );
|
||||||
this.worker = new Worker(
|
this.worker = new Worker(
|
||||||
workerHref,
|
new URL("./worker.ts", import.meta.url),
|
||||||
|
// import.meta.resolve("./worker.ts"),
|
||||||
|
// workerHref,
|
||||||
{
|
{
|
||||||
type: "module",
|
type: "module",
|
||||||
},
|
},
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
deno task bundle
|
deno task compile
|
||||||
docker build -t zefhemel/silverbullet .
|
docker build -t zefhemel/silverbullet .
|
|
@ -42,6 +42,8 @@ echo > website_build/empty.md
|
||||||
|
|
||||||
echo "Bundling..."
|
echo "Bundling..."
|
||||||
deno task bundle
|
deno task bundle
|
||||||
cp dist/silverbullet.js website_build/
|
# Replace old bundled build with upgrade instruction script
|
||||||
|
cp scripts/silverbullet-needs-upgrade.js website_build/silverbullet.js
|
||||||
cp dist_bundle/web/global.plug.json website_build/
|
cp dist_bundle/web/global.plug.json website_build/
|
||||||
cp web/images/logo.ico website_build/
|
cp web/images/logo.ico website_build/
|
||||||
|
cp install.sh website_build/
|
|
@ -9,7 +9,6 @@ echo "Generating version number..."
|
||||||
echo "export const version = '$(git rev-parse HEAD)';" > version.ts
|
echo "export const version = '$(git rev-parse HEAD)';" > version.ts
|
||||||
echo "Building..."
|
echo "Building..."
|
||||||
deno task build
|
deno task build
|
||||||
deno task install
|
|
||||||
|
|
||||||
rm -rf website_build
|
rm -rf website_build
|
||||||
silverbullet publish --index -o website_build website
|
silverbullet publish --index -o website_build website
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
VERSION=$1
|
VERSION=$1
|
||||||
|
echo "export const version = '$VERSION';" > version.ts
|
||||||
cd desktop; npm version $VERSION; cd ..
|
cd desktop; npm version $VERSION; cd ..
|
||||||
git commit -am $VERSION
|
git commit -am $VERSION
|
||||||
git tag $VERSION
|
git tag $VERSION
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
An attempt at documenting the changes/new features introduced in each
|
An attempt at documenting the changes/new features introduced in each
|
||||||
release.
|
release.
|
||||||
|
|
||||||
|
---
|
||||||
|
## 0.3.0
|
||||||
|
* Big (somewhat breaking) distribution change: SilverBullet [[Server]] is [now distributed as a single binary](https://github.com/silverbulletmd/silverbullet/issues/397) (with Deno baked in, so no need to install/maintain Deno separately). This has the following implication for existing [[Server]] users that took the deno installation path before: you to **reinstall SilverBullet** via the [[Server|new instructions]] described (don’t worry, this is a single `curl | sh` command). If you run `silverbullet upgrade` you should get an upgrade notice the next time you run.
|
||||||
|
* Technically, this also changed how [[Desktop]] build work under the hood, but this should be transparent. You shouldn’t have to worry about it.
|
||||||
|
* Improvements to dark mode by [Max Richter](https://github.com/silverbulletmd/silverbullet/pull/396)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 0.2.13
|
## 0.2.13
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
UPDATE: These instrucitons are out of date and need to be updated
|
||||||
|
|
||||||
There are currently no official 64-bit ARM Linux builds available of [Deno](https://deno.land/). However, there are [unofficial ones](https://github.com/LukeChannings/deno-arm64). Here’s how to set that up.
|
There are currently no official 64-bit ARM Linux builds available of [Deno](https://deno.land/). However, there are [unofficial ones](https://github.com/LukeChannings/deno-arm64). Here’s how to set that up.
|
||||||
|
|
||||||
> **Note** Compatibility note
|
> **Note** Compatibility note
|
||||||
|
|
|
@ -2,30 +2,29 @@ Installing SilverBullet as a (local) web server is the most mature, and most fle
|
||||||
|
|
||||||
The idea is simple: you run the web server (instructions below), point your browser at it and _go, go, go_! You can access the URL via your desktop browser, but also a mobile one. This makes it a great option to access your space from various devices without requiring any type of sync. You could even go _full-on YOLO_ (that’s a technical term), and install it on a public cloud server somewhere and access it that way (be sure to at least enable authentication and put SSL on top of it, though).
|
The idea is simple: you run the web server (instructions below), point your browser at it and _go, go, go_! You can access the URL via your desktop browser, but also a mobile one. This makes it a great option to access your space from various devices without requiring any type of sync. You could even go _full-on YOLO_ (that’s a technical term), and install it on a public cloud server somewhere and access it that way (be sure to at least enable authentication and put SSL on top of it, though).
|
||||||
|
|
||||||
|
## Supported operating systems
|
||||||
|
* 64-bit Linux
|
||||||
|
* Intel or Apple Silicon macOS
|
||||||
|
* **Windows is currently not supported**, if there’s demand for it let us know. We recommend using [[Desktop]] on Windows instead.
|
||||||
|
|
||||||
You have two options to install and run SilverBullet as a server:
|
You have two options to install and run SilverBullet as a server:
|
||||||
|
|
||||||
1. Installation via Deno on your host system
|
1. Installation right on your host system
|
||||||
2. Running it with Docker
|
2. Running it with Docker
|
||||||
|
|
||||||
## Installation via Deno
|
## Regular installation
|
||||||
This consists of two steps (unless Deno is already installed — in which case we’re down to one):
|
Run the following in your terminal:
|
||||||
|
|
||||||
1. [Install Deno](https://deno.land/manual/getting_started/installation) (if you’re using a Raspberry Pi, follow [[Raspberry Pi Installation]]-specific instructions)
|
|
||||||
2. Installing SilverBullet itself
|
|
||||||
|
|
||||||
### Install SilverBullet
|
|
||||||
With Deno installed, run:
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
deno install -f --name silverbullet -A --unstable https://get.silverbullet.md
|
curl https://silverbullet.md/install.sh | sh
|
||||||
```
|
```
|
||||||
|
|
||||||
This will install `silverbullet` into your `~/.deno/bin` folder (which should already be in your `$PATH` if you followed the Deno install instructions).
|
This will determine your operating system and download the appropriate `silverbullet` into your current folder. You will likely want to move it to a more convenient location in your PATH (made sure this is a place where it's writable for future upgrades.)
|
||||||
|
|
||||||
To run SilverBullet, create a folder for your pages (it can be empty, or be an existing folder with `.md` files) and run the following command in your terminal:
|
To run SilverBullet, create a folder for your pages (it can be empty, or be an existing folder with `.md` files) and run the following command in your terminal:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
silverbullet <pages-path>
|
./silverbullet <pages-path>
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, SilverBullet will bind to port `3000`, to use a different port use the `--port` flag.
|
By default, SilverBullet will bind to port `3000`, to use a different port use the `--port` flag.
|
||||||
|
@ -38,10 +37,10 @@ Once downloaded and booted, SilverBullet will print out a URL to open SB in your
|
||||||
SilverBullet is regularly updated. To get the latest and greatest, simply run:
|
SilverBullet is regularly updated. To get the latest and greatest, simply run:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
silverbullet upgrade
|
./silverbullet upgrade
|
||||||
```
|
```
|
||||||
|
|
||||||
And restart SilverBullet. You should be good to go.
|
If all goes well, this will upgrade silverbullet in-place. After the upgrade, restart SilverBullet. You should be good to go.
|
||||||
|
|
||||||
## Installing SilverBullet with Docker
|
## Installing SilverBullet with Docker
|
||||||
|
|
||||||
|
@ -78,3 +77,5 @@ To upgrade, simply pull the latest docker image (rebuilt and pushed after every
|
||||||
```shell
|
```shell
|
||||||
docker pull zefhemel/silverbullet
|
docker pull zefhemel/silverbullet
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Docker images are also available based on version, have a look at the [docker hub page](https://hub.docker.com/r/zefhemel/silverbullet).
|
|
@ -17,12 +17,6 @@ And build it:
|
||||||
deno task build
|
deno task build
|
||||||
```
|
```
|
||||||
|
|
||||||
For convenience, replace your `silverbullet` install with the one from this repo via:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
deno task install
|
|
||||||
```
|
|
||||||
|
|
||||||
You can now run the server in “watch mode” (automatically restarting when you change source files) with:
|
You can now run the server in “watch mode” (automatically restarting when you change source files) with:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|
Loading…
Reference in New Issue