Sign inSign up

cerebralvoyage/ungit-docker

By cerebralvoyage

•Updated 8 days ago

Ungit, containerized. https://gitlab.com/cerebral.voyage/ungit-docker

Image
Developer tools
0

7.0K

cerebralvoyage/ungit-docker repository overview

⁠ungit-docker

This is a simple image for deploying Ungit⁠ as a self-hosted web app.

⁠Approach

Since Ungit is a Node application, which also runs Git commands in the backend, the following approach has been used:

  1. Start with an Alpine-based Node.js image
  2. Install Git, GPG, GPG-Agent & OpenSSH client by using Alpine's built-in package manager (apk)
  3. Install Ungit using NPM
  4. Copy the custom entrypoint.sh file which optinally creates the runtime user from the supplied environment variables & launches the app.
  5. Expose Ungit's operating port (8448)
  6. Switch to the working directory - assumed to be /var/local/ungit/

You can build it yourself if you wish. Here's the Dockerfile

  FROM docker.io/library/node:24.21.0-alpine3.24
  RUN apk add --no-cache git gpg gpg-agent openssh-client && rm -vrf /var/cache/apk/*
  RUN npm install [email protected] -g && npm cache clean --force
  COPY entrypoint.sh /usr/local/bin/
  EXPOSE 8448/tcp
  WORKDIR /var/local/ungit
  ENTRYPOINT ["entrypoint.sh"]

The entrypoint.sh file checks if the environment variables for a custom user have been provided. If so, it creates the user/group and then launches Ungit as that new user. If not, it runs Ungit as the default node user, which comes in the reference node OCI image.

Ungit's launch command has been baked into the image. However there is scope for command line arguments through Docker's command functionality, to allow tweaking Ungit's behaviour at the container level/stage.

Ideally, the user can launch a VS Code Server image, running as the same user, and use the same directory where the code rests to have an IDE with a Git client. The development environment can be further extended by having instances of PHP & Caddy using the code repo as the HTML directory, also running as the same user.

⁠Deployment

To deploy the container as a stack, the following requirements must be met:

  1. The user who owns the code repositories must be running the container.
  2. The uid & user name of the user who owns the code repositories must be provided as environment variables
    • PUID=localuserid
    • PGID=localgroupid
    • PUNAME=localusername
    • PGNAME=localgroupname
  3. The home directory of the user must be mapped to /home/localusername/ (or /home/node/, if username is not provided) in the container. The environment variable HOME must be overriden with this path, since the running user may not exist inside the container.
  4. Ungit's bind IP must be set to 0.0.0.0 as part of the launch command to ensure that it can be accessed from outside the container.

Here's a sample Docker Compose file


name: "ungit"


services:

  main:

    container_name: "Ungit"
    restart: "unless-stopped"

    deploy:
      resources:
        limits:
          cpus: "0.25"
          memory: "512m"

    healthcheck:
      test: "/usr/bin/wget --no-verbose --quiet --tries=1 --spider http://127.0.0.1:8448 || exit 1"
      interval: "60s"
      timeout: "10s"
      start_period: "20s"
      retries: 3

    networks:
      net_app:
        ipv4_address: "172.20.170.2"
    hostname: "ungit"
    extra_hosts:
      - "dockerhost:172.20.170.1"
    # ports:
    #   - target: 8448
    #     host_ip: "0.0.0.0"
    #     published: 8448
    #     protocol: "tcp"
    #     mode: "host"

    volumes:
      - type: "bind"
        source: "/etc/localtime"
        target: "/etc/localtime"
        read_only: true
      - type: "bind"
        source: "/etc/timezone"
        target: "/etc/timezone"
        read_only: true
      - type: "bind"
        source: "/home/username"
        target: "/home/localusername"
        read_only: false
      - type: "bind"
        source: "/var/local/CodeRepo/Data"
        target: "/var/local/ungit" # This should match the value of 'forcedLaunchPath' argument passed to Ungit.
        read_only: false

    environment:
      TZ: "Europe/London"
      HOME: "/home/node"
      PGID: 16000
      PUID: 16000
      PUNAME: "localusername"
      PGNAME: "localgroupname"

    labels:
      wud.tag.include: '^v\d+\.\d+\.\d+-\d+$$' # Label for What's Up Docker to flag updates for only images tagged with semver.
      wud.tag.transform: '^v(\d+\.\d+\.\d+-\d+)$$ => $$1' # Label for What's Up Docker to exclude the 'v' prefix for version comparison.

    image: "cerebralvoyage/ungit-docker:1.5.30-29"

    command:
      - "--logLevel=warn" # "none" < "error" < "warn" < "info" < "verbose" < "debug" < "silly"
      - "--ungitBindIp=0.0.0.0"
      - "--forcedLaunchPath=\"/var/local/ungit\"" # This should match the mounted volume target.
      - "--no-launchBrowser"
      - "--no-bugTracking" # Adjust as needed.
      - "--no-autoFetch"
      - "--tabSize=2" # Adjust as needed.


networks:
  net_app:
    name: "Ungit_net"
    driver: "bridge"
    ipam:
      driver: "default"
      config:
        - subnet: "172.20.170.0/24"

Then serve this via a reverse proxy or expose the ports (uncomment above) for direct use. Remember to apply the appropriate authentication. Authelia is recommended, but any basic authenticating reverse proxy would work.

⁠Known Limitations

Since password protected SSH keys are an inherent limitations of the underlying systems, only passwordless SSH keys are known to work with this setup.

These can simply be configured in the home directory of the localuser on the Docker host, so they will be available to the container once the home directory is bind-mounted as per the example in Deployment⁠.

Currently there is no elegant way to map the Docker host's keyring to access OpenPGP keys. Hence SSH commit signing and SSH authentication are the only recommended key-based mechanisms available.

Standard username/password prompts for https-based remote repositories works as per Ungit's normal behaviours.

⁠References

  1. https://nodejs.org/en/docs/guides/nodejs-docker-webapp⁠
  2. https://dockerlabs.collabnix.com/beginners/dockerfile/lab1_dockerfile_git.html⁠
  3. https://stackoverflow.com/a/49119046⁠
  4. https://coder-coder.com/npm-clear-cache/⁠
  5. https://github.com/FredrikNoren/ungit/blob/master/source/config.js⁠
  6. https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#non-root-user⁠

Tag summary

Content type

Image

Digest

sha256:aef20582c…

Size

95.6 MB

Last updated

8 days ago

docker pull cerebralvoyage/ungit-docker