Skip to content
This repository was archived by the owner on Sep 16, 2025. It is now read-only.
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
57 changes: 57 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Kubernetes Deployment Workflow

This workflow automates the process of building a Docker image for the public-wiki application, pushing it to the GitHub Container Registry (ghcr.io), and deploying it to a Kubernetes cluster.

## How it Works

The workflow is defined in `deploy.yml` and consists of two main jobs:

1. **`build-and-push`**: This job is responsible for:
* Checking out the repository's code.
* Logging into the GitHub Container Registry.
* Building the Docker image using the `Dockerfile` in the root of the project.
* Pushing the built image to the GitHub Container Registry, tagged with the Git SHA of the commit.

2. **`deploy`**: This job depends on the successful completion of `build-and-push` and is responsible for:
* Checking out the repository's code.
* Setting up `kubectl` with the credentials to access your Kubernetes cluster.
* Updating the `k8s/deployment.yml` to use the newly built Docker image.
* Applying the Kubernetes manifests (`deployment.yml`, `service.yml`, and `ingress.yml`) located in the `k8s/` directory to the cluster.

## Triggers

The workflow is automatically triggered on any `push` event to the following branches:

* `main`
* `dev`

## Prerequisites

Before this workflow can run successfully, you must configure a secret in your GitHub repository.

### `KUBE_CONFIG_DATA`

This secret is required for the `deploy` job to authenticate with your Kubernetes cluster. It should contain the base64-encoded content of your `kubeconfig` file.

To create this secret:

1. Go to your GitHub repository's **Settings**.
2. Navigate to **Secrets and variables** > **Actions**.
3. Click on **New repository secret**.
4. Name the secret `KUBE_CONFIG_DATA`.
5. For the value, you need to provide the base64-encoded version of your `kubeconfig` file. You can get this by running the following command in your terminal:

```bash
cat ~/.kube/config | base64
```

If you are on Windows using PowerShell, you can use:

```powershell
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes("$env:USERPROFILE\.kube\config"))
```

6. Copy the output of the command and paste it into the "Value" field of the secret.
7. Click **Add secret**.

Once the secret is configured, the workflow will be able to deploy your application to your Kubernetes cluster whenever you push changes to the `main` or `dev` branches.
95 changes: 95 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Deploy to Kubernetes

on:
push:
branches:
- main
- dev

env:
IMAGE_NAME: ghcr.io/${{ github.repository }}:${{ github.sha }}

jobs:
build-and-push:
runs-on: self-hosted
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up Docker tags
id: docker_tags
run: |
BRANCH="${GITHUB_REF_NAME}"
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
IMAGE_BASE="ghcr.io/${{ github.repository }}"
TAGS=""
if [ "$BRANCH" = "main" ]; then
TAGS+="${IMAGE_BASE}:main,${IMAGE_BASE}:latest,${IMAGE_BASE}:main-${SHORT_SHA}"
elif [ "$BRANCH" = "dev" ]; then
TAGS+="${IMAGE_BASE}:dev,${IMAGE_BASE}:dev-${SHORT_SHA}"
else
TAGS+="${IMAGE_BASE}:${BRANCH},${IMAGE_BASE}:${BRANCH}-${SHORT_SHA}"
fi
echo "tags=$TAGS" >> $GITHUB_OUTPUT

- name: Log in to the Container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ steps.docker_tags.outputs.tags }}

deploy:
runs-on: ubuntu-latest
needs: build-and-push

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up Kubeconfig
env:
KUBECONFIG_DATA: ${{ secrets.KUBE_CONFIG_DATA }}
run: |
mkdir -p ~/.kube

# Decode and write kubeconfig
echo "${KUBECONFIG_DATA}" | base64 -d > ~/.kube/config

# Verify kubeconfig was decoded properly
if [ ! -s ~/.kube/config ]; then
echo "❌ ERROR: Kubeconfig file is empty after decoding!"
echo "Please verify that KUBECONFIG_DATA secret contains valid base64 encoded kubeconfig"
exit 1
fi

# Set proper permissions
chmod 600 ~/.kube/config

# Verify connection
echo "Testing connection to Kubernetes cluster..."
kubectl cluster-info

- name: Deploy to Kubernetes
run: |
if [ "${{ github.ref_name }}" = "main" ]; then
OVERLAY=main
elif [ "${{ github.ref_name }}" = "dev" ]; then
OVERLAY=dev
else
echo "Branch is not main or dev, skipping deployment."
exit 1
fi
cd k8s/overlays/$OVERLAY
kustomize build . | kubectl apply --prune -l app=public-wiki --prune-allowlist=core/v1/Namespace --prune-allowlist=apps/v1/Deployment --prune-allowlist=core/v1/Service --prune-allowlist=networking.k8s.io/v1/Ingress -f -
22 changes: 22 additions & 0 deletions k8s/base/deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: public-wiki
namespace: wiki
labels:
app: public-wiki
spec:
replicas: 3 # default, will be overridden by overlays
selector:
matchLabels:
app: public-wiki
template:
metadata:
labels:
app: public-wiki
spec:
containers:
- name: public-wiki
image: IMAGE_TAG # will be replaced by kustomize
ports:
- containerPort: 3000
21 changes: 21 additions & 0 deletions k8s/base/ingress.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: public-wiki-ingress
namespace: wiki
labels:
app: public-wiki
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: PLACEHOLDER_HOST
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: public-wiki
port:
number: 80
11 changes: 11 additions & 0 deletions k8s/base/kustomization.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resources:
- namespace.yml
- deployment.yml
- service.yml
- ingress.yml

images:
- name: public-wiki
newName: IMAGE_TAG

namespace: wiki
6 changes: 6 additions & 0 deletions k8s/base/namespace.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: wiki
labels:
app: public-wiki
14 changes: 14 additions & 0 deletions k8s/base/service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: public-wiki
namespace: wiki
labels:
app: public-wiki
spec:
selector:
app: public-wiki
ports:
- protocol: TCP
port: 80
targetPort: 3000
22 changes: 22 additions & 0 deletions k8s/deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: public-wiki
namespace: wiki
labels:
app: public-wiki
spec:
replicas: 3 # default, will be overridden by overlays
selector:
matchLabels:
app: public-wiki
template:
metadata:
labels:
app: public-wiki
spec:
containers:
- name: public-wiki
image: IMAGE_TAG # will be replaced by kustomize
ports:
- containerPort: 3000
21 changes: 21 additions & 0 deletions k8s/ingress.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: public-wiki-ingress
namespace: wiki
labels:
app: public-wiki
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: PLACEHOLDER_HOST
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: public-wiki
port:
number: 80
10 changes: 10 additions & 0 deletions k8s/kustomization.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resources:
- namespace.yml
- deployment.yml
- service.yml
- ingress.yml
images:
- name: public-wiki
newName: IMAGE_TAG

namespace: wiki
6 changes: 6 additions & 0 deletions k8s/namespace.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: wiki
labels:
app: public-wiki
25 changes: 25 additions & 0 deletions k8s/overlays/dev/kustomization.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
resources:
- ../../base

namespace: wiki

patches:
- target:
kind: Deployment
name: public-wiki
patch: |-
- op: replace
path: /spec/replicas
value: 1
- target:
kind: Ingress
name: public-wiki-ingress
patch: |-
- op: replace
path: /spec/rules/0/host
value: dev.wiki.coregame.de

images:
- name: IMAGE_TAG
newName: ghcr.io/42core-team/wiki
newTag: dev
25 changes: 25 additions & 0 deletions k8s/overlays/main/kustomization.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
resources:
- ../../base

namespace: wiki

patches:
- target:
kind: Deployment
name: public-wiki
patch: |-
- op: replace
path: /spec/replicas
value: 3
- target:
kind: Ingress
name: public-wiki-ingress
patch: |-
- op: replace
path: /spec/rules/0/host
value: wiki.coregame.de

images:
- name: IMAGE_TAG
newName: ghcr.io/42core-team/wiki
newTag: main
14 changes: 14 additions & 0 deletions k8s/service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: public-wiki
namespace: wiki
labels:
app: public-wiki
spec:
selector:
app: public-wiki
ports:
- protocol: TCP
port: 80
targetPort: 3000