Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 82 additions & 15 deletions charts/octopus-deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ If you are creating a long-lived, production Octopus instance we recommend you r

Once you have your [license key](#license-key), you can run the command below to install Octopus Deploy:

```
```bash
helm upgrade octopus-deploy \
--install \
--namespace octopus-deploy \
Expand Down Expand Up @@ -43,7 +43,7 @@ The Quick Start installs SQL Server as a sub-chart.

If you want to host SQL Server independently, you must supply the connection string:

```
```yaml
octopus:
databaseConnectionString: <Your connection string>
```
Expand All @@ -66,7 +66,7 @@ If you ever need to create a new Octopus instance and wish to use keep all your

By default, the master key is generated, stored in Kubernetes secret, and output when the Helm chart is installed. If you need to supply an existing master key this can be done as follows

```
```yaml
octopus:
masterKey: <Your master key>
```
Expand All @@ -87,7 +87,7 @@ This default can be overridden in two ways.

You can configure the storage class to be used for all three of the persistent volumes above (and for the SQL Server sub-chart if enabled) via:

```
```yaml
global:
storageClass: "<your storage class name>"
```
Expand All @@ -97,7 +97,7 @@ ReadWriteOnce or ReadWriteMany can be used for single node clusters.

Alternatively, each volume may be configured individually. An example is shown below.

```
```yaml
octopus:
packageRepositoryVolume:
size: 20Gi
Expand Down Expand Up @@ -131,8 +131,46 @@ octopus:
sizeLimit: 10Gi # Set to some upper bound limit to protect from unbound usage
```

### <a name="strict-security-context"></a>Strict Security Context / Non-root setup

#### Octopus Deploy Server
To run Server in non-root mode you need to use values:
```yaml
octopus:
enableDockerInDocker: false # required - otherwise Server will be running in privileged mode
podSecurityContext:
fsGroup: 999
fsGroupChangePolicy: OnRootMismatch
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
runAsUser: 999
runAsGroup: 999
```

### Read-Only Root Filesystem
#### Built-in mssql
The built-in mssql chart ships with default security context values:
```yaml
podSecurityContext:
fsGroup: 10001
seccompProfile:
type: RuntimeDefault
containerSecurityContext:
runAsUser: 10001
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
```

#### Read-Only Root Filesystem

If your security policy requires a read-only root filesystem (`readOnlyRootFilesystem: true`), you must provide writable `emptyDir` mounts for the directories Octopus writes to at runtime.

Expand Down Expand Up @@ -187,6 +225,35 @@ A complete working example including environment variable overrides for .NET too

Note: `enableDockerInDocker` must be set to `false` when using a read-only root filesystem, as Docker-in-Docker requires a privileged, writable container.

### Openshift

[Hardcoded UID and fsGroup](#strict-security-context) in our `securityContext` requires assigning `nonroot-v2` SCC to service accounts.

Installation steps are following:

1. create dedicated project (namespace)
```bash
NS_NAME="octopus-deploy"
oc new-project $NS_NAME --description="Octopus Deploy resources" --display-name="Octopus Deploy"
```
2. Assign `nonroot-v2` SCC to SAs
- Server
```bash
NS_NAME="octopus-deploy"
SERVER_SERVICE_ACCOUNT="default"
oc adm policy add-scc-to-user nonroot-v2 -z $SERVER_SERVICE_ACCOUNT -n $NS_NAME
```
- Built-in mssql (if applicable)
```bash
NS_NAME="octopus-deploy"
MSSQL_SERVICE_ACCOUNT="octopus-deploy-mssql"
oc adm policy add-scc-to-user nonroot-v2 -z $MSSQL_SERVICE_ACCOUNT -n $NS_NAME
```
3. run `helm install` command with extra values from [Strict Security Context](#strict-security-context) section.




### Ingress
Comment thread
oleksandr-codefresh marked this conversation as resolved.
You'll likely want to allow external traffic to your Octopus instance, and this generally means configuring [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/).

Expand All @@ -199,7 +266,7 @@ There are three types of traffic which you will typically want to configure ingr

An example of a values file which configures ingress for HTTP traffic to the web portal and HTTP API using [NGINX](https://kubernetes.github.io/ingress-nginx/) is shown below:

```
```yaml
octopus:
ingress:
enabled: true
Expand All @@ -212,7 +279,7 @@ octopus:
To enable TLS in the ingress, you can create a certificate using cert-manager, and then reference it in the ingress configuration. An example is shown below:

Certificate:
```
```yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
Expand All @@ -228,7 +295,7 @@ spec:
```

Values file:
```
```yaml
octopus:
ingress:
enabled: true
Expand All @@ -250,7 +317,7 @@ If the chart is configured to create a single Octopus node (`replicaCount: 1`) t
The following configuration will create an ingress endpoint for each Octopus node (replica).


```
```yaml
octopus:
ingress:
enabled: true
Expand Down Expand Up @@ -279,7 +346,7 @@ Octopus Server uses gRPC communication for the Kubernetes monitor. By default, O
The Octopus Deploy service exposes this port for you by default. To allow external consumers of this service, you can either set this service to be a LoadBalancer, or use an ingress (or the Gateway API).

Setting the service to be a Load Balancer can be done by setting the following in the values:
```
```yaml
octopus:
service:
type: LoadBalancer
Expand All @@ -291,7 +358,7 @@ To pass through the default SSL certificate, you can use the `nginx.ingress.kube
Note that to do this, you must [enable SSL passthrough in your nginx ingress controller](https://kubernetes.github.io/ingress-nginx/user-guide/tls/#ssl-passthrough).

To enable passthrough, you can set the following in your values file:
```
```yaml
octopus:
ingress:
enabled: true
Expand All @@ -310,7 +377,7 @@ octopus:
```

If you wish to terminate SSL rather than use passthrough, you must ensure that your certificate is issued by a CA that is generally trusted. Using a certificate from LetsEncrypt is the recommended way to do this. An example certificate would be:
```
```yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
Expand All @@ -326,7 +393,7 @@ spec:
```

You can then set your ingress up as follows to enable the ingress:
```
```yaml
octopus:
ingress:
enabled: true
Expand All @@ -347,7 +414,7 @@ octopus:
```

The resulting ingress will be as follows:
```
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
Expand Down
145 changes: 145 additions & 0 deletions charts/octopus-deploy/applied-statefulset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: octopus-deploy
labels:
app.kubernetes.io/name: octopus-deploy
helm.sh/chart: octopusdeploy-helm-1.11.1
app.kubernetes.io/instance: octopus-deploy
app.kubernetes.io/managed-by: Helm
spec:
selector:
matchLabels:
app.kubernetes.io/name: octopus-deploy
helm.sh/chart: octopusdeploy-helm-1.11.1
app.kubernetes.io/instance: octopus-deploy
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: octopus-server
serviceName: octopus-deploy
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/name: octopus-deploy
helm.sh/chart: octopusdeploy-helm-1.11.1
app.kubernetes.io/instance: octopus-deploy
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: octopus-server
spec:
serviceAccountName: default
containers:
- name: octopus
image: "docker.packages.octopushq.com/octopusdeploy/octopusdeploy:2026.2.4992-noamgal-yos-32-investigate-octopus-deploy-helm-chart-compatibility-with-linux"
securityContext:
env:

- name: ACCEPT_EULA
value: "Y"
- name: OCTOPUS_SERVER_NODE_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: DB_CONNECTION_STRING
valueFrom:
secretKeyRef:
name: octopus-deploy-connectionstring
key: secret
- name: ADMIN_USERNAME
valueFrom:
secretKeyRef:
name: octopus-deploy-adminusername
key: secret
- name: ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: octopus-deploy-adminpassword
key: secret
- name: ADMIN_EMAIL
value:
- name: TASK_CAP
value: !!str
- name: OCTOPUS_SERVER_BASE64_LICENSE
# Your license key goes here. When using more than one node, a HA license is required.
# Without a HA license, the stateful set can have a replica count of 1.
valueFrom:
secretKeyRef:
name: octopus-deploy-licensekey
key: secret
- name: MASTER_KEY
valueFrom:
secretKeyRef:
name: octopus-deploy-masterkey
key: secret
- name: DISABLE_DIND
value: !!str "Y"
- name: OCTOPUS_INSTALLED_VIA_HELM
value: "true"
- name: OCTOPUS_GRPC_SERVICES_PORT
value: "8443"
ports:
- containerPort: 8080
name: web
- containerPort: 10943
name: tentacle
- containerPort: 8443
name: grpcs
volumeMounts:
- name: package-repository-volume
mountPath: /repository
- name: artifacts-volume
mountPath: /artifacts
- name: task-log-volume
mountPath: /taskLogs
- name: server-log-volume
mountPath: /home/octopus/.octopus/OctopusServer/Server/Logs
- name: audit-log-volume
mountPath: /eventExports
readinessProbe:
exec:
command:
- /bin/bash
- -c
- URL=http://localhost:8080; response=$(/usr/bin/curl -k $URL/api/serverstatus/hosted/internal --write-out %{http_code} --silent --output /dev/null); /usr/bin/test "$response" -ge 200 && /usr/bin/test "$response" -le 299 || /usr/bin/test
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 60
livenessProbe:
exec:
command:
- /bin/bash
- -c
- URL=http://localhost:8080; response=$(/usr/bin/curl -k $URL/api/octopusservernodes/ping --write-out %{http_code} --silent --output /dev/null); /usr/bin/test "$response" -ge 200 && /usr/bin/test "$response" -le 299 || /usr/bin/test "$response" -eq 418
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 10
startupProbe:
exec:
command:
- /bin/bash
- -c
- URL=http://localhost:8080; response=$(/usr/bin/curl -k $URL/api/octopusservernodes/ping --write-out %{http_code} --silent --output /dev/null); /usr/bin/test "$response" -ge 200 && /usr/bin/test "$response" -le 299 || /usr/bin/test "$response" -eq 418
failureThreshold: 30
periodSeconds: 60
terminationGracePeriodSeconds: 10
volumes:
- name: package-repository-volume
persistentVolumeClaim:
claimName: package-repository-claim
- name: artifacts-volume
persistentVolumeClaim:
claimName: artifacts-claim
- name: task-log-volume
persistentVolumeClaim:
claimName: task-log-claim
- name: audit-log-volume
persistentVolumeClaim:
claimName: audit-log-claim
volumeClaimTemplates:
- metadata:
name: server-log-volume
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 200Mi
Loading
Loading