Allow configuration via environment variables #132

Open
opened 2023-12-14 08:05:06 +00:00 by viceice · 2 comments
Member

It's sometimes easier (eg Kubernetes) to configure the runner via environment variables instead of a config file.

I would suggest a syntax like the docker registry uses.

So an variable like RUNNER__FETCH_INTERVAL=5s and RUNNER__LABELS__0=some would become this config:

runner:
  fetch_interval: 5s
  labels:
    - some
It's sometimes easier (eg Kubernetes) to configure the runner via environment variables instead of a config file. I would suggest a syntax like the docker registry uses. So an variable like `RUNNER__FETCH_INTERVAL=5s` and `RUNNER__LABELS__0=some` would become this config: ```yml runner: fetch_interval: 5s labels: - some ```
viceice added the
Kind/Feature
Priority
Medium
labels 2023-12-14 08:05:06 +00:00
Member

I think this is a great addition. The example provided for a k8s deployment can also be further improved by mounting a ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: forgejo-runner-config
  labels:
    app: forgejo-runner
data:
  config.yaml: |-
    runner:
      fetch_timeout: 60s
      fetch_interval: 5s
    container:
      valid_volumes: 
        - '**'    

and on the deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: forgejo-runner
  name: forgejo-runner
spec:
  # Two replicas means that if one is busy, the other can pick up jobs.
  replicas: 1
  selector:
    matchLabels:
      app: forgejo-runner
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: forgejo-runner
    spec:
      restartPolicy: Always
      volumes:
      - name: docker-certs
        emptyDir: {}
      - name: runner-data
        emptyDir: {}
      - name: config
        configMap:
          name: forgejo-runner-config
      initContainers:
      - name: runner-config-generation
        image: code.forgejo.org/forgejo/runner:3.2.0
        #command: [ "forgejo-runner", "create-runner-file", "--instance", "$(FORGEJO_INSTANCE_URL)", "--secret", "$(RUNNER_SECRET)", "--connect" ]
        command: [ "forgejo-runner", "register", "--no-interactive", "--token", "$(RUNNER_SECRET)", "--name", "vinland", "--instance", "$(FORGEJO_INSTANCE_URL)", "--labels", "self-hosted,docker"]
        env:
        - name: RUNNER_SECRET
          valueFrom:
            secretKeyRef:
              name: runner-secret
              key: token
        - name: FORGEJO_INSTANCE_URL
          value: https://codeberg.org
        volumeMounts:
        - name: runner-data
          mountPath: /data
      containers:
      - name: runner
        image: code.forgejo.org/forgejo/runner:3.2.0
        command: ["sh", "-c", "while ! nc -z localhost 2376 </dev/null; do echo 'waiting for docker daemon...'; sleep 5; done; forgejo-runner daemon --config config.yaml"]
        env:
        - name: DOCKER_HOST
          value: tcp://localhost:2376
        - name: DOCKER_CERT_PATH
          value: /certs/client
        - name: DOCKER_TLS_VERIFY
          value: "1"
        volumeMounts:
        - name: docker-certs
          mountPath: /certs
        - name: runner-data
          mountPath: /data
        - name: config
          mountPath: /data/config.yaml
          subPath: "config.yaml"
      - name: daemon
        image: docker:23.0.6-dind
        env:
        - name: DOCKER_TLS_CERTDIR
          value: /certs
        securityContext:
          privileged: true
        volumeMounts:
        - name: docker-certs
          mountPath: /certs

The important parts are the volumeMount to mount the ConfigMap to /data/config.yaml on the runner pod and the volume definition.

I think this is a great addition. The example provided for a k8s deployment can also be further improved by mounting a ConfigMap: ```yaml apiVersion: v1 kind: ConfigMap metadata: name: forgejo-runner-config labels: app: forgejo-runner data: config.yaml: |- runner: fetch_timeout: 60s fetch_interval: 5s container: valid_volumes: - '**' ``` and on the deployment: ```yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: forgejo-runner name: forgejo-runner spec: # Two replicas means that if one is busy, the other can pick up jobs. replicas: 1 selector: matchLabels: app: forgejo-runner strategy: {} template: metadata: creationTimestamp: null labels: app: forgejo-runner spec: restartPolicy: Always volumes: - name: docker-certs emptyDir: {} - name: runner-data emptyDir: {} - name: config configMap: name: forgejo-runner-config initContainers: - name: runner-config-generation image: code.forgejo.org/forgejo/runner:3.2.0 #command: [ "forgejo-runner", "create-runner-file", "--instance", "$(FORGEJO_INSTANCE_URL)", "--secret", "$(RUNNER_SECRET)", "--connect" ] command: [ "forgejo-runner", "register", "--no-interactive", "--token", "$(RUNNER_SECRET)", "--name", "vinland", "--instance", "$(FORGEJO_INSTANCE_URL)", "--labels", "self-hosted,docker"] env: - name: RUNNER_SECRET valueFrom: secretKeyRef: name: runner-secret key: token - name: FORGEJO_INSTANCE_URL value: https://codeberg.org volumeMounts: - name: runner-data mountPath: /data containers: - name: runner image: code.forgejo.org/forgejo/runner:3.2.0 command: ["sh", "-c", "while ! nc -z localhost 2376 </dev/null; do echo 'waiting for docker daemon...'; sleep 5; done; forgejo-runner daemon --config config.yaml"] env: - name: DOCKER_HOST value: tcp://localhost:2376 - name: DOCKER_CERT_PATH value: /certs/client - name: DOCKER_TLS_VERIFY value: "1" volumeMounts: - name: docker-certs mountPath: /certs - name: runner-data mountPath: /data - name: config mountPath: /data/config.yaml subPath: "config.yaml" - name: daemon image: docker:23.0.6-dind env: - name: DOCKER_TLS_CERTDIR value: /certs securityContext: privileged: true volumeMounts: - name: docker-certs mountPath: /certs ``` The important parts are the `volumeMount` to mount the ConfigMap to `/data/config.yaml` on the runner pod and the `volume` definition.
Author
Member

I'm doing something like that now 😉

I'm doing something like that now 😉
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: forgejo/runner#132
No description provided.