golink fork w controlURL hardcoded to lz
Go to file
j3s 8d5cc9f254 blah 2022-12-14 15:23:09 -06:00
.github/workflows .github: cross-compile docker images 2022-12-06 20:33:21 -08:00
cmd/golink all: add flag for specifying snapshot file 2022-11-08 12:32:58 -08:00
static add basic favicon 2022-12-05 20:03:25 -08:00
tmpl add basic favicon 2022-12-05 20:03:25 -08:00
.gitignore all: librarify golink and make importable 2022-08-20 07:25:26 -07:00
Dockerfile Use a directory writable by nonroot. 2022-12-05 12:34:19 -08:00
LICENSE add: add license and headers 2022-11-08 12:53:39 -08:00
README.md readme: add disambiguation links for other go link services 2022-12-14 12:12:31 -08:00
db.go all: remove some dead code 2022-11-09 16:53:17 -08:00
db_test.go add: add license and headers 2022-11-08 12:53:39 -08:00
go.mod blah 2022-12-14 15:23:09 -06:00
go.sum blah 2022-12-14 15:23:09 -06:00
golink.go blah 2022-12-14 15:23:09 -06:00
golink_test.go add support for resolving links locally 2022-12-06 14:19:31 -08:00
package.json bump tailwind and dependencies 2022-11-08 15:04:21 -08:00
schema.sql cmd/golink: add SQLiteDB implementation 2022-06-14 13:00:04 -07:00
screenshot.png readme: add simple description and screenshot 2022-11-09 08:50:32 -08:00
tailwind.config.js cmd/golink: provide user documentation 2022-06-21 09:25:14 -07:00
yarn.lock bump tailwind and dependencies 2022-11-08 15:04:21 -08:00



status: experimental

golink is a private shortlink service for your tailnet. It lets you create short, memorable links for the websites you and your team use most. If you're new to golink, learn more in our announcement blog post. If you were looking for a SaaS go link service that doesn't use Tailscale, you might be thinking of golinks.io or trot.to

Screenshot of golink home screen

Building and running

To build from source and run in dev mode:

go run ./cmd/golink -dev-listen :8080

golink will be available at http://localhost:8080/, storing links in a temporary database, and will not attempt to join a tailnet.

The equivalent using the pre-built docker image:

docker run -it --rm -p 8080:8080 ghcr.io/tailscale/golink:main -dev-listen :8080

If you receive the docker error unable to open database file: out of memory (14), use a persistent volume as documented in Running in production.

Joining a tailnet

Create an [auth key] for your tailnet at https://login.tailscale.com/admin/settings/keys. Configure the auth key to your preferences, but at a minimum we generally recommend:

  • add a tag (maybe something like tag:golink) to make it easier to set ACLs for controlling access and to ensure the node doesn't expires.
  • don't set "ephemeral" so the node isn't removed if it goes offline

Once you have a key, set it as the TS_AUTHKEY environment variable when starting golink. You will also need to specify your sqlite database file:

TS_AUTHKEY="tskey-auth-<key>" go run ./cmd/golink -sqlitedb golink.db

golink stores its tailscale data files in a tsnet-golink directory inside os.UserConfigDir. As long as this is on a persistent volume, the auth key only needs to be provided on first run.


When golink joins your tailnet, it will attempt to use "go" as its node name, and will be available at http://go.tailnet0000.ts.net/ (or whatever your tailnet name is). To make it accessible simply as http://go/, enable MagicDNS for your tailnet. With MagicDNS enabled, no special configuration or browser extensions are needed on client devices. Users just need to have Tailscale installed and connected to the tailnet.

Running in production

golink compiles as a single static binary (including the frontend) and can be deployed and run like any other binary. Two pieces of data should be on persistent volumes:

  • tailscale data files in the tsnet-golink directory inside os.UserConfigDir
  • the sqlite database file where links are stored

In the docker image, both are stored in /home/nonroot, so you can mount a persistent volume:

docker run -v /persistant/data:/home/nonroot ghcr.io/tailscale/golink:main

The mounted directory will need to be writable by the nonroot user (uid: 65532, gid: 65532), for example by calling sudo chown 65532 /persistent/data. Alternatively, you can run golink as root using docker run -u root.

No ports need to be exposed, whether running as a binary or in docker. golink will listen on port 80 on the tailscale interface, so can be accessed at http://go/.

Deploy on Fly

See https://fly.io/docs/ for full instructions for deploying apps on Fly, but this should give you a good start. Replace FLY_APP_NAME and FLY_VOLUME_NAME with your app and volume names.

Create a fly.toml file:

app = "FLY_APP_NAME"

image = "ghcr.io/tailscale/golink:main"

strategy = "immediate"


Then run the commands with the flyctl CLI.

$ flyctl apps create FLY_APP_NAME
$ flyctl volumes create FLY_VOLUME_NAME
$ flyctl secrets set TS_AUTHKEY=tskey-auth-<key>
$ flyctl deploy


Once you have golink running, you can backup all of your links in JSON lines format from http://go/.export. At Tailscale, we snapshot our links weekly and store them in git.

To restore links, specify the snapshot file on startup. Only links that don't already exist in the database will be added.

golink -snapshot links.json

You can also resolve links locally using a snapshot file:

golink -resolve-from-backup links.json go/link