Skip to content
Draft
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
51 changes: 51 additions & 0 deletions .github/workflows/publish-helmchart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: release

on:
push:
tags:
- '*'
branches:
- add-helmchart


permissions:
contents: read

jobs:
release:
runs-on: ubuntu-latest
permissions:
#contents: write # needed to write releases
#id-token: write # needed for keyless signing
packages: write # needed for ghcr access
steps:
- uses: actions/checkout@v4
- name: Setup Helm
uses: azure/setup-helm@v4.2.0

- name: Prepare
id: prep
run: |
VERSION=sha-${GITHUB_SHA::8}
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF/refs\/tags\//}
fi
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
echo "REVISION=${GITHUB_SHA}" >> $GITHUB_OUTPUT
echo "CHART_VERSION=$(yq eval '.version' charts/factorio/Chart.yaml)" >> $GITHUB_OUTPUT

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

#Docker hub login - https://github.com/docker/login-action?tab=readme-ov-file#docker-hub

- name: Publish Helm chart to GHCR
run: |
helm package charts/factorio
helm push factorio-${{ steps.prep.outputs.CHART_VERSION }}.tgz oci://ghcr.io/fredx30/factorio-docker
rm factorio-${{ steps.prep.outputs.CHART_VERSION }}.tgz
23 changes: 23 additions & 0 deletions charts/factorio/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
24 changes: 24 additions & 0 deletions charts/factorio/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: factorio
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.1

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "2.0.15" # Match factorio client version.
16 changes: 16 additions & 0 deletions charts/factorio/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "factorio.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "factorio.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "factorio.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "factorio.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Connect to ip 127.0.0.1:34197 in your factorio client."
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 34197:$CONTAINER_PORT
{{- end }}
62 changes: 62 additions & 0 deletions charts/factorio/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "factorio.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "factorio.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "factorio.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "factorio.labels" -}}
helm.sh/chart: {{ include "factorio.chart" . }}
{{ include "factorio.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "factorio.selectorLabels" -}}
app.kubernetes.io/name: {{ include "factorio.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "factorio.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "factorio.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
82 changes: 82 additions & 0 deletions charts/factorio/templates/cm-server-settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: server-settings
data:
server-settings: |
{
"name": "Name of the game as it will appear in the game listing",
"description": "Description of the game that will appear in the listing",
"tags": [ "game", "tags" ],

"_comment_max_players": "Maximum number of players allowed, admins can join even a full server. 0 means unlimited.",
"max_players": 0,

"_comment_visibility": [
"public: Game will be published on the official Factorio matching server",
"lan: Game will be broadcast on LAN"
],
"visibility": {
"public": false,
"lan": true
},

"_comment_credentials": "Your factorio.com login credentials. Required for games with visibility public",
"username": "",
"password": "",

"_comment_token": "Authentication token. May be used instead of 'password' above.",
"token": "",

"game_password": "",

"_comment_require_user_verification": "When set to true, the server will only allow clients that have a valid Factorio.com account",
"require_user_verification": true,

"_comment_max_upload_in_kilobytes_per_second": "optional, default value is 0. 0 means unlimited.",
"max_upload_in_kilobytes_per_second": 0,

"_comment_max_upload_slots": "optional, default value is 5. 0 means unlimited.",
"max_upload_slots": 5,

"_comment_minimum_latency_in_ticks": "optional one tick is 16ms in default speed, default value is 0. 0 means no minimum.",
"minimum_latency_in_ticks": 0,

"_comment_max_heartbeats_per_second": "Network tick rate. Maximum rate game updates packets are sent at before bundling them together. Minimum value is 6, maximum value is 240.",
"max_heartbeats_per_second": 60,

"_comment_ignore_player_limit_for_returning_players": "Players that played on this map already can join even when the max player limit was reached.",
"ignore_player_limit_for_returning_players": false,

"_comment_allow_commands": "possible values are, true, false and admins-only",
"allow_commands": "admins-only",

"_comment_autosave_interval": "Autosave interval in minutes",
"autosave_interval": 10,

"_comment_autosave_slots": "server autosave slots, it is cycled through when the server autosaves.",
"autosave_slots": 5,

"_comment_afk_autokick_interval": "How many minutes until someone is kicked when doing nothing, 0 for never.",
"afk_autokick_interval": 15,

"_comment_auto_pause": "Whether should the server be paused when no players are present.",
"auto_pause": true,

"_comment_auto_pause_when_players_connect": "Whether should the server be paused when someone is connecting to the server.",
"auto_pause_when_players_connect": false,

"only_admins_can_pause_the_game": true,

"_comment_autosave_only_on_server": "Whether autosaves should be saved only on server or also on all connected clients. Default is true.",
"autosave_only_on_server": true,

"_comment_non_blocking_saving": "Highly experimental feature, enable only at your own risk of losing your saves. On UNIX systems, server will fork itself to create an autosave. Autosaving on connected Windows clients will be disabled regardless of autosave_only_on_server option.",
"non_blocking_saving": false,

"_comment_segment_sizes": "Long network messages are split into segments that are sent over multiple ticks. Their size depends on the number of peers currently connected. Increasing the segment size will increase upload bandwidth requirement for the server and download bandwidth requirement for clients. This setting only affects server outbound messages. Changing these settings can have a negative impact on connection stability for some clients.",
"minimum_segment_size": 25,
"minimum_segment_size_peer_count": 20,
"maximum_segment_size": 100,
"maximum_segment_size_peer_count": 10
}
67 changes: 67 additions & 0 deletions charts/factorio/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "factorio.fullname" . }}
labels:
{{- include "factorio.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
{{- include "factorio.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "factorio.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
hostNetwork: {{ .Values.hostNetwork }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
env:
{{- toYaml .Values.envVars | nindent 12 }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: rcon
containerPort: {{ .Values.service.portTcp }}
protocol: TCP
- name: game
containerPort: {{ .Values.service.portUdp }}
protocol: UDP
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.volumeMounts }}
volumeMounts:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.volumes }}
volumes:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
19 changes: 19 additions & 0 deletions charts/factorio/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "factorio.fullname" . }}
labels:
{{- include "factorio.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.portTcp }}
targetPort: rcon
protocol: TCP
name: rcon
- port: {{ .Values.service.portUdp }}
targetPort: game
protocol: UDP
name: game
selector:
{{- include "factorio.selectorLabels" . | nindent 4 }}
15 changes: 15 additions & 0 deletions charts/factorio/templates/tests/test-connection.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "factorio.fullname" . }}-test-connection"
labels:
{{- include "factorio.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "factorio.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never
Loading