Skip to content

Commit b19cf70

Browse files
authored
feat: change docker to use "coder" user and add basic Helm chart (coder#2746)
1 parent d2aa75d commit b19cf70

File tree

10 files changed

+343
-0
lines changed

10 files changed

+343
-0
lines changed

.github/workflows/release.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,12 +275,19 @@ jobs:
275275
- name: ls artifacts
276276
run: ls artifacts
277277

278+
- name: Publish Helm
279+
run: |
280+
set -euxo pipefail
281+
./scripts/helm.sh --push
282+
mv ./dist/*.tgz ./artifacts/
283+
278284
- name: Publish Release
279285
run: |
280286
./scripts/publish_release.sh \
281287
${{ (github.event.inputs.dry_run || github.event.inputs.snapshot) && '--dry-run' }} \
282288
./artifacts/*.zip \
283289
./artifacts/*.tar.gz \
290+
./artifacts/*.tgz \
284291
./artifacts/*.apk \
285292
./artifacts/*.deb \
286293
./artifacts/*.rpm

Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,9 @@ LABEL \
1414
# The coder binary is injected by scripts/build_docker.sh.
1515
ADD coder /opt/coder
1616

17+
# Create coder group and user.
18+
RUN addgroup -g 1000 coder && \
19+
adduser -D -g "" -h /home/coder -G coder -u 1000 -S -s /bin/sh coder
20+
USER coder:coder
21+
1722
ENTRYPOINT [ "/opt/coder", "server" ]

helm/.helmignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/

helm/Chart.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
apiVersion: v2
2+
name: coder
3+
description: Remote development environments on your infrastructure
4+
home: https://github.com/coder/coder
5+
6+
# version and appVersion are injected at release and will always be shown as
7+
# 0.1.0 in the repository.
8+
type: application
9+
version: "0.1.0"
10+
appVersion: "0.1.0"
11+
12+
# Coder has a hard requirement on Kubernetes 1.19, as this version introduced
13+
# the networking.k8s.io/v1 API.
14+
kubeVersion: ">= 1.19.0-0"
15+
16+
keywords:
17+
- coder
18+
- terraform
19+
sources:
20+
- https://github.com/coder/coder/tree/main/helm
21+
icon: https://helm.coder.com/coder_logo_black.png
22+
maintainers:
23+
- name: Coder Technologies, Inc.
24+
email: support@coder.com
25+
url: https://coder.com/contact

helm/templates/_helpers.tpl

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "coder.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
8+
{{/*
9+
Create chart name and version as used by the chart label.
10+
*/}}
11+
{{- define "coder.chart" -}}
12+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
13+
{{- end }}
14+
15+
{{/*
16+
Selector labels
17+
*/}}
18+
{{- define "coder.selectorLabels" -}}
19+
app.kubernetes.io/name: {{ include "coder.name" . }}
20+
app.kubernetes.io/instance: {{ .Release.Name }}
21+
{{- end }}
22+
23+
{{/*
24+
Common labels
25+
*/}}
26+
{{- define "coder.labels" -}}
27+
helm.sh/chart: {{ include "coder.chart" . }}
28+
{{ include "coder.selectorLabels" . }}
29+
{{- if .Chart.AppVersion }}
30+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
31+
{{- end }}
32+
app.kubernetes.io/managed-by: {{ .Release.Service }}
33+
{{- end }}

helm/templates/deployment.yaml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: coder
5+
labels:
6+
{{- include "coder.labels" . | nindent 4 }}
7+
spec:
8+
# NOTE: this is currently not used as coder v2 does not support high
9+
# availability yet.
10+
# replicas: {{ .Values.coder.replicaCount }}
11+
replicas: 1
12+
selector:
13+
matchLabels:
14+
{{- include "coder.selectorLabels" . | nindent 6 }}
15+
template:
16+
metadata:
17+
labels:
18+
{{- include "coder.selectorLabels" . | nindent 8 }}
19+
spec:
20+
restartPolicy: Always
21+
terminationGracePeriodSeconds: 60
22+
containers:
23+
- name: coder
24+
image: "{{ .Values.coder.image.repo }}:{{ .Values.coder.image.tag | default (printf "v%v" .Chart.AppVersion) }}"
25+
imagePullPolicy: {{ .Values.coder.image.pullPolicy }}
26+
resources:
27+
{{- toYaml .Values.resources | nindent 12 }}
28+
env:
29+
{{- if .Values.coder.tls.secretName }}
30+
- name: CODER_ADDRESS
31+
value: "0.0.0.0:8443"
32+
- name: CODER_TLS_ENABLE
33+
value: "true"
34+
- name: CODER_TLS_CERT_FILE
35+
value: /etc/ssl/certs/coder/tls.crt
36+
- name: CODER_TLS_KEY_FILE
37+
value: /etc/ssl/certs/coder/tls.key
38+
{{- else }}
39+
- name: CODER_ADDRESS
40+
value: "0.0.0.0:8080"
41+
{{- end }}
42+
{{- with .Values.coder.env -}}
43+
{{ toYaml . | nindent 12 }}
44+
{{- end }}
45+
ports:
46+
{{- if .Values.coder.tls.secretName }}
47+
- name: https
48+
containerPort: 8443
49+
protocol: TCP
50+
{{- else }}
51+
- name: http
52+
containerPort: 8080
53+
protocol: TCP
54+
{{- end }}
55+
readinessProbe:
56+
httpGet:
57+
path: /api/v2/buildinfo
58+
port: http
59+
livenessProbe:
60+
httpGet:
61+
path: /api/v2/buildinfo
62+
port: http

helm/templates/service.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{{- if .Values.coder.service.enable }}
2+
---
3+
apiVersion: v1
4+
kind: Service
5+
metadata:
6+
name: coder
7+
labels:
8+
{{- include "coder.labels" . | nindent 4 }}
9+
spec:
10+
type: {{ .Values.coder.service.type }}
11+
ports:
12+
{{- if .Values.coder.tls.secretName }}
13+
- name: https
14+
port: 443
15+
targetPort: https
16+
protocol: TCP
17+
{{- else }}
18+
- name: http
19+
port: 80
20+
targetPort: http
21+
protocol: TCP
22+
{{- end }}
23+
selector:
24+
{{- include "coder.selectorLabels" . | nindent 4 }}
25+
{{- end }}

helm/values.yaml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# coder -- Primary configuration for `coder server`.
2+
coder:
3+
# NOTE: this is currently not used as coder v2 does not support high
4+
# availability yet.
5+
# # coder.replicaCount -- The number of Kubernetes deployment replicas.
6+
# replicaCount: 1
7+
8+
# coder.image -- The image to use for Coder.
9+
image:
10+
# coder.image.repo -- The repository of the image.
11+
repo: "ghcr.io/coder/coder"
12+
# coder.image.tag -- The tag of the image, defaults to {{.Chart.AppVersion}}
13+
# if not set.
14+
tag: ""
15+
# coder.image.pullPolicy -- The pull policy to use for the image. See:
16+
# https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy
17+
pullPolicy: IfNotPresent
18+
19+
# coder.env -- The environment variables to set for Coder. These can be used
20+
# to configure all aspects of `coder server`. Please see `coder server --help`
21+
# for information about what environment variables can be set.
22+
#
23+
# Note: The following environment variables are set by default and cannot be
24+
# overridden:
25+
# - CODER_ADDRESS: set to 0.0.0.0:80 and cannot be changed.
26+
# - CODER_TLS_ENABLE: set if tls.secretName is not empty.
27+
# - CODER_TLS_CERT_FILE: set if tls.secretName is not empty.
28+
# - CODER_TLS_KEY_FILE: set if tls.secretName is not empty.
29+
env:
30+
- name: CODER_ACCESS_URL
31+
value: "https://coder.example.com"
32+
#- name: CODER_PG_CONNECTION_URL
33+
# value: "postgres://coder:password@postgres:5432/coder?sslmode=disable"
34+
35+
# coder.tls -- The TLS configuration for Coder.
36+
tls:
37+
# coder.tls.secretName -- The name of the secret containing the TLS
38+
# certificate. The secret should exist in the same namespace as the Helm
39+
# deployment and should be of type "kubernetes.io/tls". The secret will be
40+
# automatically mounted into the pod if specified, and the correct
41+
# "CODER_TLS_*" environment variables will be set for you.
42+
secretName: ""
43+
44+
# coder.resources -- The resources to request for Coder. These are optional
45+
# and are not set by default.
46+
resources: {}
47+
# limits:
48+
# cpu: 100m
49+
# memory: 128Mi
50+
# requests:
51+
# cpu: 100m
52+
# memory: 128Mi
53+
54+
# coder.service -- The Service object to expose for Coder.
55+
service:
56+
# coder.service.enable -- Whether to create the Service object.
57+
enable: true
58+
# coder.service.type -- The type of service to expose. See:
59+
# https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
60+
type: LoadBalancer
61+
# coder.service.externalTrafficPolicy -- The external traffic policy to use.
62+
# You may need to change this to "Local" to preserve the source IP address
63+
# in some situations.
64+
# https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip
65+
externalTrafficPolicy: Cluster
66+
# coder.service.loadBalancerIP -- The IP address of the LoadBalancer. If not
67+
# specified, a new IP will be generated each time the load balancer is
68+
# recreated. It is recommended to manually create a static IP address in
69+
# your cloud and specify it here in production to avoid accidental IP
70+
# address changes.
71+
loadBalancerIP: ""

scripts/helm.sh

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env bash
2+
3+
# This script creates a Helm package for the given version. It will output a
4+
# .tgz file at the specified path, and may optionally push it to the Coder OSS
5+
# repo.
6+
#
7+
# ./helm.sh [--version 1.2.3] [--output path/to/coder.tgz] [--push]
8+
#
9+
# If no version is specified, defaults to the version from ./version.sh.
10+
#
11+
# If no output path is specified, defaults to
12+
# "$repo_root/dist/coder_helm_$version.tgz".
13+
#
14+
# If the --push parameter is specified, the resulting artifact will be published
15+
# to the Coder OSS repo. This requires `gsutil` to be installed and configured.
16+
17+
set -euo pipefail
18+
# shellcheck source=scripts/lib.sh
19+
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
20+
21+
version=""
22+
output_path=""
23+
push=0
24+
25+
args="$(getopt -o "" -l version:,output:,push -- "$@")"
26+
eval set -- "$args"
27+
while true; do
28+
case "$1" in
29+
--version)
30+
version="$2"
31+
shift 2
32+
;;
33+
--output)
34+
output_path="$(realpath "$2")"
35+
shift 2
36+
;;
37+
--push)
38+
push="1"
39+
shift
40+
;;
41+
--)
42+
shift
43+
break
44+
;;
45+
*)
46+
error "Unrecognized option: $1"
47+
;;
48+
esac
49+
done
50+
51+
# Remove the "v" prefix.
52+
version="${version#v}"
53+
if [[ "$version" == "" ]]; then
54+
version="$(execrelative ./version.sh)"
55+
fi
56+
57+
if [[ "$output_path" == "" ]]; then
58+
cdroot
59+
mkdir -p dist
60+
output_path="$(realpath "dist/coder_helm_$version.tgz")"
61+
fi
62+
63+
# Check dependencies
64+
dependencies helm
65+
66+
# Make a destination temporary directory, as you cannot fully control the output
67+
# path of `helm package` except for the directory name :/
68+
cdroot
69+
temp_dir="$(mktemp -d)"
70+
71+
cdroot
72+
cd ./helm
73+
log "--- Packaging helm chart for version $version ($output_path)"
74+
helm package \
75+
--version "$version" \
76+
--app-version "$version" \
77+
--destination "$temp_dir" \
78+
. 1>&2
79+
80+
log "Moving helm chart to $output_path"
81+
cp "$temp_dir"/*.tgz "$output_path"
82+
rm -rf "$temp_dir"
83+
84+
if [[ "$push" == 1 ]]; then
85+
log "--- Publishing helm chart..."
86+
# TODO: figure out how/where we want to publish the helm chart
87+
fi

scripts/version.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ set -euo pipefail
1515
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
1616
cdroot
1717

18+
if [[ "${CODER_FORCE_VERSION:-}" != "" ]]; then
19+
echo "$CODER_FORCE_VERSION"
20+
exit 0
21+
fi
22+
1823
last_tag="$(git describe --tags --abbrev=0)"
1924
version="$last_tag"
2025

0 commit comments

Comments
 (0)