git@cosmocr.at/gitweb.git @ HEAD · summary refs log
HEAD / DEPLOY.md /
DEPLOY.md · 10.9 KiB · raw
view: SourceMarkdown ☑ force

Deploying the gitweb browser

How to build and deploy the gitweb service to the upspin VM (instance-2). It is a single Go binary (page templates + static assets embedded via go:embed) that runs as a docker-compose service alongside the existing upspin stack, exactly like vault and markdown.

Architecture at a glance

Prerequisites

Routine redeploy (code change)

This is the common case. Because the templates + assets are embedded, any change needs a rebuilt image.

  1. Build + push the image from the gitweb repo:

    make push
    

    (= CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build, docker build --platform linux/amd64, tag, docker push.)

  2. Pull + recreate the container on the VM:

    # authenticate the Docker daemon to gcr.io
    sudo env HOME=/var/upspin /bin/sh /var/upspin/auth.sh
    
    # pull the new image
    sudo docker run --rm \
      -v /var/run/docker.sock:/var/run/docker.sock \
      -v /var/upspin/.docker:/root/.docker \
      -v /var/upspin:/var/upspin -w /var/upspin \
      docker/compose:1.29.2 -p patrick pull gitweb
    
    # recreate just the gitweb container (rm + create; see "compose recreate" note)
    sudo docker rm -f patrick_gitweb_1
    sudo docker run --rm \
      -v /var/run/docker.sock:/var/run/docker.sock \
      -v /var/upspin/.docker:/root/.docker \
      -v /var/upspin:/var/upspin -w /var/upspin \
      docker/compose:1.29.2 -p patrick up -d --no-recreate gitweb
    

    (Re-running deploy-git.sh also works and is idempotent; the cert step is a no-op once the cert exists — but see the certbot gotcha below.)

  3. Verify:

    sudo docker logs --tail 5 patrick_gitweb_1        # "gitweb: serving on :8446"
    curl -sI https://git.cosmocr.at/git@cosmocr.at/demo.git/   # 200
    

If you changed config, the compose service, or nginx

This covers any change to the compose services (incl. restart: policies), the nginx routing/SNI map, or the upspin config — i.e. anything that lives in cloud-init-cos121.yaml.

⚠️ The instance metadata is the source of truth, not the files on the VM. On every boot, cloud-init re-applies the VM's user-data metadata and overwrites /var/upspin/docker-compose.yml and /var/upspin/nginx/nginx.conf. A change you only sudo cp onto the VM (or nginx -s reload) works until the next reboot, then silently reverts. This is exactly how the vault service once vanished on its first reboot: it was added to the running VM and to the repo, but never pushed to the metadata. Always push the metadata.

1. Edit + push the metadata (authoritative — survives reboots):

# edit upspin/vm/cloud-init-cos121.yaml in the control repo, then from that repo:
gcloud compute instances add-metadata instance-2 --zone us-central1-a \
  --metadata-from-file user-data=upspin/vm/cloud-init-cos121.yaml

Mirror the same edit into upspin/vm/docker-compose.vault.yml and upspin/nginx/nginx.conf so the local reference copies stay identical. The push takes effect on the next reboot; verify it landed (run on the VM):

curl -s -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/attributes/user-data \
  | grep -c 'gitweb:'      # expect a non-zero count

2. Apply now without waiting for a reboot (optional, for a live change): copy the rendered files up and reload/recreate only the affected pieces:

# control/upspin/vm/docker-compose.vault.yml -> /var/upspin/docker-compose.yml
# control/upspin/nginx/nginx.conf            -> /var/upspin/nginx/nginx.conf
sudo docker exec patrick_nginx_1 nginx -t && sudo docker exec patrick_nginx_1 nginx -s reload
# recreate any container whose service/config changed (rm + up; see note below)

These hot-apply the change immediately; step 1 is what makes it durable. Do both — they are not alternatives.

First-time setup (new VM / from scratch)

Use control/upspin/vm/deploy-git.sh, which does it all idempotently: stages the config + keys onto the data disk, issues the TLS cert (certbot webroot via the running nginx), updates nginx + compose, pulls the image, recreates nginx (for the SNI route) and starts gitweb, then verifies. Manual outline:

  1. DNS: covered by the *.cosmocr.at wildcard → 34.28.234.94 (no per-host record needed).
  2. Config + keys onto the data disk: /mnt/disks/data/gitweb/config + /mnt/disks/data/gitweb/secrets/*.upspinkey (keys 0600, root-owned).
  3. TLS cert (nginx must be serving :80 for the ACME challenge):
    sudo docker run --rm \
      -v /mnt/disks/data/certbot-www:/var/www/certbot:rw \
      -v /mnt/disks/data/letsencrypt:/etc/letsencrypt:rw \
      certbot/certbot certonly --webroot --webroot-path=/var/www/certbot \
        --register-unsafely-without-email --agree-tos --no-eff-email \
        -d git.cosmocr.at
    
  4. nginx route and the gitweb compose service (already in cloud-init-cos121.yaml): SNI route git.cosmocr.at gitweb:8446;.
  5. Recreate nginx, then start gitweb (commands as in "Routine redeploy").

Before the first run, make sure the infra edits are in cloud-init-cos121.yaml and pushed to the metadata (see "If you changed config"): the gitweb: compose service and the git.cosmocr.at gitweb:8446; line in the nginx map.

Gotchas / troubleshooting