mirror of
https://github.com/jbowdre/runtimeterror.git
synced 2024-11-21 22:42:19 +00:00
update draft
This commit is contained in:
parent
5e428b41fa
commit
fb20c34ebe
1 changed files with 135 additions and 7 deletions
|
@ -16,7 +16,7 @@ tags:
|
||||||
- linux
|
- linux
|
||||||
- selfhosting
|
- selfhosting
|
||||||
- tailscale
|
- tailscale
|
||||||
---
|
---
|
||||||
|
|
||||||
A few days ago I [posted on my other blog](https://srsbsns.lol/is-silverbullet-the-note-keeping-silver-bullet/) about trying out [SilverBullet](https://silverbullet.md), an open-source self-hosted web-based note-keeping app. SilverBullet has continued to impress me as I use it and learn more about its [features](https://silverbullet.md/SilverBullet@1992). It really fits my multi-device use case much better than Obsidian ever did (even with its paid sync plugin).
|
A few days ago I [posted on my other blog](https://srsbsns.lol/is-silverbullet-the-note-keeping-silver-bullet/) about trying out [SilverBullet](https://silverbullet.md), an open-source self-hosted web-based note-keeping app. SilverBullet has continued to impress me as I use it and learn more about its [features](https://silverbullet.md/SilverBullet@1992). It really fits my multi-device use case much better than Obsidian ever did (even with its paid sync plugin).
|
||||||
|
|
||||||
|
@ -24,25 +24,128 @@ In that post, I shared a brief overview of how I set up SilverBullet:
|
||||||
|
|
||||||
> I deployed my instance in Docker alongside both a [Tailscale sidecar](/tailscale-serve-docker-compose-sidecar/) and [Cloudflare Tunnel sidecar](/publish-services-cloudflare-tunnel/). This setup lets me easily access/edit/manage my notes from any device I own by just pointing a browser at `https://silverbullet.tailnet-name.ts.net/`. And I can also hit it from any *other* device by using the public Cloudflare endpoint which is further protected by an email-based TOTP challenge. Either way, I don't have to worry about installing a bloated app or managing a complicated sync setup. Just log in and write.
|
> I deployed my instance in Docker alongside both a [Tailscale sidecar](/tailscale-serve-docker-compose-sidecar/) and [Cloudflare Tunnel sidecar](/publish-services-cloudflare-tunnel/). This setup lets me easily access/edit/manage my notes from any device I own by just pointing a browser at `https://silverbullet.tailnet-name.ts.net/`. And I can also hit it from any *other* device by using the public Cloudflare endpoint which is further protected by an email-based TOTP challenge. Either way, I don't have to worry about installing a bloated app or managing a complicated sync setup. Just log in and write.
|
||||||
|
|
||||||
This post will go into a bit more detail about the configuration.
|
This post will go into a bit more detail about that configuration.
|
||||||
|
|
||||||
### Docker Prep
|
### Setup
|
||||||
I chose to deploy SilverBullet on an Ubuntu 22.04 VM in my [homelab](/homelab/) which was already set up for serving Docker workloads so I'm not going to cover the Docker [installation process](https://docs.docker.com/engine/install/ubuntu/) here. I tend to run my Docker workloads out of `/opt/` so I started this journey by creating a place to hold the SilverBullet setup:
|
I chose to deploy SilverBullet on an Ubuntu 22.04 VM in my [homelab](/homelab/) which was already set up for serving Docker workloads so I'm not going to cover the Docker [installation process](https://docs.docker.com/engine/install/ubuntu/) here. I tend to run my Docker workloads out of `/opt/` so I start this journey by creating a place to hold the SilverBullet setup:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
sudo mkdir -p /opt/silverbullet # [tl! .cmd]
|
sudo mkdir -p /opt/silverbullet # [tl! .cmd]
|
||||||
```
|
```
|
||||||
|
|
||||||
I set up appropriate ownership of the folder and then entered it:
|
I set appropriate ownership of the folder and then move into it:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
sudo chown john:docker /opt/silverbullet # [tl! .cmd:1]
|
sudo chown john:docker /opt/silverbullet # [tl! .cmd:1]
|
||||||
cd /opt/silverbullet
|
cd /opt/silverbullet
|
||||||
```
|
```
|
||||||
|
|
||||||
### Docker Compose
|
The documentation offers easy-to-follow guidance on [installing SilverBullet with Docker Compose](https://silverbullet.md/Install/Docker), and that makes for a pretty good starting point. The only change I make here is setting the `SB_USER` variable from an environment variable instead of directly in the YAML:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
# torchlight! {"lineNumbers":true}
|
||||||
|
services:
|
||||||
|
silverbullet:
|
||||||
|
image: zefhemel/silverbullet
|
||||||
|
container_name: silverbullet
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
SB_USER: "${SB_CREDS}"
|
||||||
|
volumes:
|
||||||
|
- ./space:/space
|
||||||
|
ports:
|
||||||
|
- 3000:3000
|
||||||
|
|
||||||
|
watchtower:
|
||||||
|
image: containrrr/watchtower
|
||||||
|
container_name: silverbullet-watchtower
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
```
|
||||||
|
|
||||||
|
I used a password manager to generate a random password *and username*, and I store those in a `.env` file alongside the Docker Compose configuration. For example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SB_CREDS='alldiaryriver:XCTpmddGc3Ga4DkUr7DnPBYzt1b'
|
||||||
|
```
|
||||||
|
|
||||||
|
That's all that's really needed for running SilverBullet locally, but I also want to be able to access the application from any device connected to my Tailscale tailnet. So I add in a [Tailscale sidecar](/tailscale-serve-docker-compose-sidecar/#compose-configuration), and update the `silverbullet` service to share Tailscale's network:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# torchlight! {"lineNumbers":true}
|
||||||
|
services:
|
||||||
|
tailscale: # [tl! ++:12 **:12]
|
||||||
|
image: tailscale/tailscale:latest
|
||||||
|
container_name: silverbullet-tailscale
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
TS_AUTHKEY: ${TS_AUTHKEY:?err}
|
||||||
|
TS_HOSTNAME: ${TS_HOSTNAME:-ts-docker}
|
||||||
|
TS_EXTRA_ARGS: ${TS_EXTRA_ARGS:-}
|
||||||
|
TS_STATE_DIR: /var/lib/tailscale/
|
||||||
|
TS_SERVE_CONFIG: /config/serve-config.json
|
||||||
|
volumes:
|
||||||
|
- ./ts_data:/var/lib/tailscale/
|
||||||
|
- ./serve-config.json:/config/serve-config.json
|
||||||
|
|
||||||
|
silverbullet:
|
||||||
|
image: zefhemel/silverbullet
|
||||||
|
container_name: silverbullet
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
SB_USER: "${SB_CREDS}"
|
||||||
|
volumes:
|
||||||
|
- ./space:/space
|
||||||
|
ports: # [tl! --:1 **:1]
|
||||||
|
- 3000:3000
|
||||||
|
network_mode: service:tailscale # [tl! ++ **]
|
||||||
|
|
||||||
|
watchtower:
|
||||||
|
image: containrrr/watchtower
|
||||||
|
container_name: silverbullet-watchtower
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
```
|
||||||
|
|
||||||
|
That of course means adding a few more items to the `.env` file: a [pre-authentication key](https://tailscale.com/kb/1085/auth-keys), the hostname to use for the application's presence on my tailnet, and the `--ssh` extra argument to enable SSH access to the container (not strictly necessary, but can be handy for troubleshooting):
|
||||||
|
|
||||||
|
```text
|
||||||
|
SB_CREDS='alldiaryriver:XCTpmddGc3Ga4DkUr7DnPBYzt1b'
|
||||||
|
TS_AUTHKEY=tskey-auth-[...] [tl! ++:2 **:2]
|
||||||
|
TS_HOSTNAME=silverbullet
|
||||||
|
TS_EXTRA_ARGS=--ssh
|
||||||
|
```
|
||||||
|
|
||||||
|
And I need to create a `serve-config.json` file to configure [Tailscale Serve](/tailscale-ssh-serve-funnel/#tailscale-serve) to proxy port `443` on the tailnet to port `3000` on the container:
|
||||||
|
|
||||||
|
```json
|
||||||
|
// torchlight! {"lineNumbers":true}
|
||||||
|
{
|
||||||
|
"TCP": {
|
||||||
|
"443": {
|
||||||
|
"HTTPS": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Web": {
|
||||||
|
"silverbullet.tailnet-name.ts.net:443": {
|
||||||
|
"Handlers": {
|
||||||
|
"/": {
|
||||||
|
"Proxy": "http://127.0.0.1:3000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
But what if I want to consult my notes from outside of my tailnet? Sure, I *could* use [Tailscale Funnel](/tailscale-ssh-serve-funnel/#tailscale-funnel) to publish the SilverBullet service on the internet, but (1) funnel would require me to use a URL like `https://silverbullet.tailnet-name.ts.net` instead of simply `https://silverbullet.example.com` and (2) I'm still a little wary of putting a login page on the public web.
|
||||||
|
|
||||||
|
[Cloudflare Tunnel](/publish-services-cloudflare-tunnel/) is able to address those concerns without a lot of extra work. I can set up a tunnel at `silverbullet.example.com` and use [Cloudflare Access](https://developers.cloudflare.com/cloudflare-one/applications/configure-apps/) to put an additional challenge in front of the login page.
|
||||||
|
|
||||||
|
I just need to add a `cloudflared` container to my stack:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# torchlight! {"lineNumbers":true}
|
||||||
services:
|
services:
|
||||||
tailscale:
|
tailscale:
|
||||||
image: tailscale/tailscale:latest
|
image: tailscale/tailscale:latest
|
||||||
|
@ -58,7 +161,7 @@ services:
|
||||||
- ./ts_data:/var/lib/tailscale/
|
- ./ts_data:/var/lib/tailscale/
|
||||||
- ./serve-config.json:/config/serve-config.json
|
- ./serve-config.json:/config/serve-config.json
|
||||||
|
|
||||||
cloudflared:
|
cloudflared: # [tl! ++:9 **:9]
|
||||||
image: cloudflare/cloudflared
|
image: cloudflare/cloudflared
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
container_name: silverbullet-cloudflared
|
container_name: silverbullet-cloudflared
|
||||||
|
@ -85,3 +188,28 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To get the required `$CLOUDFLARED_TOKEN`, I have to [create a new `cloudflared` tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel/) in the Cloudflare dashboard, and then I just add the generated value to my `.env` file:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SB_CREDS='alldiaryriver:XCTpmddGc3Ga4DkUr7DnPBYzt1b'
|
||||||
|
TS_AUTHKEY=tskey-auth-[...]
|
||||||
|
TS_HOSTNAME=silverbullet
|
||||||
|
TS_EXTRA_ARGS=--ssh
|
||||||
|
CLOUDFLARED_TOKEN=eyJhIjo[...]BNSJ9 [tl! ++ **]
|
||||||
|
```
|
||||||
|
|
||||||
|
Back in the Cloudflare Tunnel setup flow, I select my desired public hostname (`silverbullet.example.com`) and then specify that the backend service is `http://localhost:3000`.
|
||||||
|
|
||||||
|
Now I'm ready to start up my containers:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker compose up -d # [tl! .cmd .nocopy:1,5]
|
||||||
|
[+] Running 5/5
|
||||||
|
✔ Network silverbullet_default Created
|
||||||
|
✔ Container silverbullet-watchtower Started
|
||||||
|
✔ Container silverbullet-tailscale Started
|
||||||
|
✔ Container silverbullet Started
|
||||||
|
✔ Container silverbullet-cloudflared Started
|
||||||
|
```
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue