diff options
author | polwex <polwex@sortug.com> | 2025-10-05 21:56:51 +0700 |
---|---|---|
committer | polwex <polwex@sortug.com> | 2025-10-05 21:56:51 +0700 |
commit | fcedfddf00b3f994e4f4e40332ac7fc192c63244 (patch) | |
tree | 51d38e62c7bdfcc5f9a5e9435fe820c93cfc9a3d /vere/docker |
claude is gud
Diffstat (limited to 'vere/docker')
-rw-r--r-- | vere/docker/Dockerfile | 12 | ||||
-rw-r--r-- | vere/docker/README.md | 135 | ||||
-rwxr-xr-x | vere/docker/get_urbit_code.sh | 8 | ||||
-rwxr-xr-x | vere/docker/reset_urbit_code.sh | 16 | ||||
-rwxr-xr-x | vere/docker/start_urbit.sh | 71 |
5 files changed, 242 insertions, 0 deletions
diff --git a/vere/docker/Dockerfile b/vere/docker/Dockerfile new file mode 100644 index 0000000..7151534 --- /dev/null +++ b/vere/docker/Dockerfile @@ -0,0 +1,12 @@ +FROM alpine:3.17.1 +RUN apk update && apk add bash curl +ENV PATH="$PATH:/bin" +COPY get_urbit_code.sh /bin/get_urbit_code +COPY reset_urbit_code.sh /bin/reset_urbit_code +COPY start_urbit.sh /bin/start_urbit +COPY urbit /bin/ +EXPOSE 80/tcp +EXPOSE 34343/udp +VOLUME /urbit +WORKDIR /urbit +ENTRYPOINT ["/bin/start_urbit"] diff --git a/vere/docker/README.md b/vere/docker/README.md new file mode 100644 index 0000000..1cae449 --- /dev/null +++ b/vere/docker/README.md @@ -0,0 +1,135 @@ +# Official Urbit Docker Image + +This is the official Docker image for [Urbit](https://urbit.org). + +Urbit is a clean-slate OS and network for the 21st century. + +## Using + +To use this image, you should mount a volume with a keyfile, comet file, or +existing pier at `/urbit`, and map ports as described below. + +### Volume Mount + +This image expects a volume mounted at `/urbit`. This volume should initially +contain one of: +- A keyfile `<shipname>.key` for a galaxy, star, planet, or moon. See the + setup instructions for information on + [obtaining a keyfile](https://urbit.org/getting-started/get-id). + - e.g. `sampel-palnet.key` for the planet `~sampel-palnet`. +- An empty file with the extension `.comet`. This will cause Urbit to boot a + comet in a pier named for the `.comet` file (less the extension). + - e.g. starting with an empty file `my-urbit-bot.comet` will result in Urbit + booting a comet into the pier `my-urbit-bot` under your volume. +- An existing pier as a directory `<shipname>`. You can migrate an existing ship + to a new docker container in this way by placing its pier under the volume. + - e.g. if your ship is `sampel-palnet` then you likely have a directory + `sampel-palnet` whose path you pass to `./urbit` when starting. + [Move your pier](https://docs.urbit.org/user-manual/os/basics#moving-your-pier) + directory to the volume and then start the container. + +The first two options result in Urbit attempting to boot either the ship named +by the keyfile, or a comet. In both cases, after that boot is successful, the +`.key` or `.comet` file will be removed from the volume and the pier will take +its place. + +Therefore, it is safe to remove the Docker container and start a new container +which mounts the same volume (e.g. to upgrade the version of the Urbit binary +by running a newer image). It is also possible to stop the container and then +move the pier out of the Docker volume (e.g. to run it using an Urbit binary +directly). If you do this, make sure to delete the Docker volume after you move +your pier; if you launch a container using this same pier after moving it and +launching it elsewhere, you will likely need to perform a +[breach](https://docs.urbit.org/user-manual/id/guide-to-resets). + +### Ports + +The image includes `EXPOSE` directives for TCP port `80` and UDP port `34343`. +Port `80` is used for Urbit's HTTP interface for both Landscape and for +[API calls](https://docs.urbit.org/build-on-urbit/tools/js-libs/http-api-guide) +to the ship. Port `34343` is set by default to be used by +[Ames](https://docs.urbit.org/urbit-os/kernel/ames) for ship-to-ship communication. + +You can either pass the `-P` flag to docker to map ports directly to the +corresponding ports on the host, or map them individually with `-p` flags. For +local testing the latter is often convenient, for instance to remap port `80` to +an unprivileged port. + +For best performance, you must map the Ames UDP port to the *same* port on the +host. If you map to a different port Ames will not be able to make direct +connections and your network performance may suffer somewhat. Note that using +the same port is required for direct connections but is not by itself sufficient +for them. If you are behind a NAT router or the host is not on a public IP +address (or you are firewalled), you may not achieve direct connections +regardless. + +For this reason, you can force Ames to use a custom port. +`/bin/start-urbit --port=$AMES_PORT` can be passed as an argument to the +`docker start` command. Passing `/bin/start-urbit --port=13436` for example, +would use port `13436`. Note that you must pass the full script command +`/bin/start-urbit` in order to also pass arguments. If the script is omitted, +your container will not start. + +You can also set the http port using `--http-port=$HTTP_PORT`. Passing +`/bin/start-urbit --http-port=8085` for example, would use port `8085`. The +default http port is `8080`. + +### Variable Loom Size + +You can also set a variable loom size (Urbit memory size) using +`--loom=$LOOM_SIZE`. Passing `/bin/start-urbit --loom=32` for example, would set +up a 4GiB loom (`2^32 bytes = 4GiB`). The default loom size is `31` (2GiB). + +### Examples + +Creating a volume for `~sampel-palnet`: +``` +docker volume create sampel-palnet +``` + +Copying key to `~sampel-palnet`'s volume (assumes default Docker location): +``` +sudo cp ~/sampel-palnet.key /var/lib/docker/volumes/sampel-palnet/_data/sampel-palnet.key +``` + +Using that volume and launching `~sampel-palnet` on host port `8080` with Ames +talking on the default host port `34343`: +``` +docker run -d -p 8080:80 -p 34343:34343/udp --name sampel-palnet \ + --mount type=volume,source=sampel-palnet,destination=/urbit \ + tloncorp/vere +``` + +Using host port `8088` with Ames talking on host port `23232`: +``` +docker run -d -p 8088:80 -p 23232:23232/udp --name sampel-palnet \ + --mount type=volume,source=sampel-palnet,destination=/urbit \ + tloncorp/vere /bin/start-urbit --port=23232 +``` + +### Getting and resetting the Landscape `+code` + +This docker image includes tools for retrieving and resetting the Landscape +login code belonging to a ship, for programmatic use so the container does not +need a tty. These scripts can be called using `docker container exec`. + +Getting the code: +``` +$ docker container exec sampel-palnet /bin/get-urbit-code +sampel-sampel-sampel-sampel +``` + +Resetting the code: +``` +$ docker container exec sampel-palnet /bin/reset-urbit-code +OK +``` + +## Extending + +You likely do not want to extend this image. External applications which +interact with Urbit do so primarily via an HTTP API, which should be exposed as +described above. For containerized applications using Urbit, it is more +appropriate to use a container orchestration service such as Docker Compose or +Kubernetes to run Urbit alongside other containers which will interface with its +API. diff --git a/vere/docker/get_urbit_code.sh b/vere/docker/get_urbit_code.sh new file mode 100755 index 0000000..4873a04 --- /dev/null +++ b/vere/docker/get_urbit_code.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +code=$(curl -s -X POST -H "Content-Type: application/json" \ + -d '{ "source": { "dojo": "+code" }, "sink": { "stdout": null } }' \ + http://127.0.0.1:12321) + +# Trim newlines and double quotes. +echo "$code" | sed 's/\\n//' | tr -d '"' diff --git a/vere/docker/reset_urbit_code.sh b/vere/docker/reset_urbit_code.sh new file mode 100755 index 0000000..20af60d --- /dev/null +++ b/vere/docker/reset_urbit_code.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Sending `+hood/code %reset` to `dojo` resets the `+code`, but it requires +# interactive confirmation to do so. Obviously, we don't want to have to provide +# that confirmation, so we force reset the `+code` using +# `+hood/pass [%j %step ~]`, credit for which goes to ~wicdev-wisryt. +resp=$(curl -s -X POST -H "Content-Type: application/json" \ + -d '{ "source": { "dojo": "+hood/pass [%j %step ~]" }, "sink": { "app": "hood" } }' \ + http://127.0.0.1:12321) + +if [[ $? -eq 0 ]] +then + echo "OK" +else + echo "Curl error: $?" +fi diff --git a/vere/docker/start_urbit.sh b/vere/docker/start_urbit.sh new file mode 100755 index 0000000..809f2f1 --- /dev/null +++ b/vere/docker/start_urbit.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +set -eu + +# set defaults +amesPort="34343" +httpPort="80" +loom="31" +snap="2" + +# check args +for i in "$@" +do +case $i in + -p=*|--port=*) + amesPort="${i#*=}" + shift + ;; + --http-port=*) + httpPort="${i#*=}" + shift + ;; + --loom=*) + loom="${i#*=}" + shift + ;; + --snap-time=*) + snap="${i#*=}" + shift + ;; +esac +done + +# If the container is not started with the `-i` flag +# then STDIN will be closed and we need to start +# Urbit/vere with the `-t` flag. +ttyflag="" +if [ ! -t 0 ]; then + echo "Running with no STDIN" + ttyflag="-t" +fi + +# Check if there is a keyfile, if so boot a ship with its name, and then remove the key +if [ -e *.key ]; then + # Get the name of the key + keynames="*.key" + keys=( $keynames ) + keyname=''${keys[0]} + mv $keyname /tmp + + # Boot urbit with the key, exit when done booting + urbit $ttyflag -w $(basename $keyname .key) -k /tmp/$keyname -c $(basename $keyname .key) -p $amesPort -x --http-port $httpPort --loom $loom --snap-time $snap + + # Remove the keyfile for security + rm /tmp/$keyname + rm *.key || true +elif [ -e *.comet ]; then + cometnames="*.comet" + comets=( $cometnames ) + cometname=''${comets[0]} + rm *.comet + + urbit $ttyflag -c $(basename $cometname .comet) -p $amesPort -x --http-port $httpPort --loom $loom --snap-time $snap +fi + +# Find the first directory and start urbit with the ship therein +dirnames="*/" +dirs=( $dirnames ) +dirname=''${dirnames[0]} + +exec urbit $ttyflag -p $amesPort --http-port $httpPort --loom $loom $dirname --snap-time $snap |