Skip to content

Commit

Permalink
Cosign tests and readme links (#283)
Browse files Browse the repository at this point in the history
  • Loading branch information
ngeorger authored Sep 11, 2024
1 parent 776b81b commit 31bd864
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
25 changes: 23 additions & 2 deletions .github/workflows/multi-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
paths:
- Dockerfile
- entrypoint.js
- .github/workflows/multi-build.yaml
tags:
- v*

Expand Down Expand Up @@ -196,6 +197,11 @@ jobs:
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1
with:
egress-policy: audit

- name: Install Cosign
uses: sigstore/cosign-installer@v3
continue-on-error: true

-
name: Download digests
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
Expand Down Expand Up @@ -271,7 +277,7 @@ jobs:
--annotation='index:io.artifacthub.package.maintainers=[{"name":"Nicolas Georger","email":"info@sredevops.org"}]' \
--annotation='index:io.artifacthub.package.alternative-locations=oci://index.docker.io/ngeorger/ghost-on-kubernetes' \
--annotation='index:io.artifacthub.package.logo-url=https://raw.githubusercontent.com/sredevopsorg/.github/main/SREDevOpsOrg-Logo.png' \
--annotation='index:io.artifacthub.package.keywords=kubernetes, cms, deploy, ghost, self-hosted, k8s, ghost blog, ghost cms, kubernetes-deployment, container-image, distroless, k3s, hardened-images' \
--annotation='index:io.artifacthub.package.keywords=ghost, blog, cms' \
$(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *)
-
Expand All @@ -287,8 +293,23 @@ jobs:
id: inspect
continue-on-error: true
run: |
docker buildx imagetools inspect ${{ env.GHCR_IMAGE }}:${{ steps.meta.outputs.version }}
docker buildx imagetools inspect ${{ env.GHCR_IMAGE }}:${{ steps.meta.outputs.version }} &&
echo "DIGEST=$(docker buildx imagetools inspect ${{ env.GHCR_IMAGE }}:${{ steps.meta.outputs.version }} | jq -r '.[0].digest')" >> $GITHUB_OUTPUT &&
echo "TAGS=$(docker buildx imagetools inspect ${{ env.GHCR_IMAGE }}:${{ steps.meta.outputs.version }} | jq -r '.[0].tags')" >> $GITHUB_OUTPUT
- name: Sign the images with GitHub OIDC Token
id: sign
continue-on-error: true
env:
DIGEST: ${{ steps.inspect.outputs.DIGEST }}
TAGS: ${{ steps.inspect.outputs.TAGS }}
run: |
images=""
for tag in ${TAGS}; do
images+="${tag}@${DIGEST} "
done
cosign sign --yes ${images}
-
name: Login to Docker Hub
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
Expand Down
35 changes: 25 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Ghost on Kubernetes by SREDevOps.Org

<center><a href="https://sredevops.org" target="_blank" rel="noopener"><img src="https://github.com/sredevopsorg/.github/assets/34670018/6878e00f-635c-4553-8df7-3b20406fdb4f" alt="SREDevOps.org" width="60%" align="center" /></a></center>
[![SREDevOps.org](https://github.com/sredevopsorg/.github/assets/34670018/6878e00f-635c-4553-8df7-3b20406fdb4f)](https://sredevops.org)

**Community for SRE, DevOps, Cloud Native, GNU/Linux, and more. 🌎**

Expand All @@ -20,10 +20,12 @@ This repository implements Ghost CMS v5.xx.x from [@TryGhost (upstream)](https:/
- Removed gosu, now everything runs as non-root (UID/GID 65532) inside the Distroless container. This change alone reduces 6 critical vulnerabilities and 34 high vulnerabilities reported by Docker Scout in the original Ghost image. References:

- [Ghost Official Image](https://hub.docker.com/_/ghost/tags)
![Docker Scout Report - Ghost Official Image](docs/images/dockerhub-ghost.png)

![Docker Scout Report - Ghost Official Image](https://raw.githubusercontent.com/sredevopsorg/ghost-on-kubernetes/main/docs/images/dockerhub-ghost.png)

- [Ghost on Kubernetes Image on Docker Hub](https://hub.docker.com/r/ngeorger/ghost-on-kubernetes/tags)
![Docker Scout Report - Ghost on Kubernetes Image](docs/images/dockerhub-ngeorger.png)

![Docker Scout Report - Ghost on Kubernetes Image](https://raw.githubusercontent.com/sredevopsorg/ghost-on-kubernetes/main/docs/images/dockerhub-ngeorger.png)

- New Entrypoint flow, using a Node.js script executed by the unprivileged Node user inside the Distroless container, which updates the default themes and starts the Ghost application, an operation that is performed inside the Distroless container itself.
- We use the latest version of Ghost 5 (when the image is built).
Expand All @@ -40,12 +42,7 @@ We've made some significant updates to improve the security and efficiency of ou

## Star History

<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=sredevopsorg/ghost-on-kubernetes&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=sredevopsorg/ghost-on-kubernetes&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=sredevopsorg/ghost-on-kubernetes&type=Date" height="300px" />
</picture>

![Star History Chart](https://api.star-history.com/svg?repos=sredevopsorg/ghost-on-kubernetes&type=Date&theme=dark)

## Installation

Expand All @@ -59,7 +56,6 @@ cd ghost-on-kubernetes
# Create a new branch for your changes (optional but recommended).
git checkout -b my-branch --no-track --detach


```

### 1. Check the example configurations
Expand All @@ -79,6 +75,8 @@ Deploying a sophisticated application like Ghost on Kubernetes involves orchestr

Namespaces in Kubernetes provide a logical separation of resources. We'll use the `ghost-on-kubernetes` namespace to contain all resources related to our Ghost deployment. This approach enhances organization and prevents resource conflicts with other applications running on the same cluster.

File: [deploy/00-namespace.yaml](https://github.com/sredevopsorg/ghost-on-kubernetes/blob/main/deploy/00-namespace.yaml)

```yaml
apiVersion: v1
kind: Namespace
Expand All @@ -97,6 +95,12 @@ Secrets in Kubernetes allow us to store and manage sensitive data, such as datab
- `ghost-on-kubernetes-mysql-env`: Contains environment variables for the MySQL database, including the database name, username, and password.
- `tls-secret`: Holds the TLS certificate and key for enabling HTTPS on our Ghost blog.

File: [deploy/01-mysql-config.yaml](https://github.com/sredevopsorg/ghost-on-kubernetes/blob/main/deploy/01-mysql-config.yaml)

File: [deploy/04-ghost-config.yaml](https://github.com/sredevopsorg/ghost-on-kubernetes/blob/main/deploy/04-ghost-config.yaml)

File: [deploy/01-tls.yaml](https://github.com/sredevopsorg/ghost-on-kubernetes/blob/main/deploy/01-tls.yaml)

```yaml
apiVersion: v1
kind: Secret
Expand All @@ -119,6 +123,8 @@ PersistentVolumeClaims (PVCs) in Kubernetes enable us to request persistent stor
- `k8s-ghost-content`: Provides persistent storage for Ghost's content, including images, themes, and uploaded files.
- `ghost-on-kubernetes-mysql-pvc`: Offers persistent storage for the MySQL database, ensuring data persistence across pod restarts and reschedulings.

File: [deploy/02-pvc.yaml](https://github.com/sredevopsorg/ghost-on-kubernetes/blob/main/deploy/02-pvc.yaml)

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
Expand All @@ -137,6 +143,8 @@ Services in Kubernetes provide a way to expose our applications running on a set
- `ghost-on-kubernetes-service`: Exposes the Ghost application internally within the cluster on port 2368.
- `ghost-on-kubernetes-mysql-service`: Exposes the MySQL database internally on port 3306, allowing the Ghost application to connect to the database.

File: [deploy/03-service.yaml](https://github.com/sredevopsorg/ghost-on-kubernetes/blob/main/deploy/03-service.yaml)

```yaml
apiVersion: v1
kind: Service
Expand All @@ -148,10 +156,13 @@ spec:
# ... Service specification
```


### StatefulSet: Managing the MySQL Database

A StatefulSet in Kubernetes is designed to manage stateful applications, such as databases, that require persistent storage and stable network identities. We'll use a StatefulSet to deploy a single replica of the MySQL database.

File: [deploy/05-mysql.yaml](https://github.com/sredevopsorg/ghost-on-kubernetes/blob/main/deploy/05-mysql.yaml)

```yaml
apiVersion: apps/v1
kind: StatefulSet
Expand All @@ -167,6 +178,8 @@ spec:

Deployments in Kubernetes manage the deployment and scaling of stateless applications. We'll use a Deployment to deploy a single replica of the Ghost application.

File: [deploy/06-ghost-deployment.yaml](https://github.com/sredevopsorg/ghost-on-kubernetes/blob/main/deploy/06-ghost-deployment.yaml)

```yaml
apiVersion: apps/v1
kind: Deployment
Expand All @@ -182,6 +195,8 @@ spec:

An Ingress resource in Kubernetes acts as a reverse proxy, routing external traffic to services within the cluster. We'll use an Ingress to expose our Ghost blog to the internet using a domain name.

File: [deploy/07-ingress.yaml](https://github.com/sredevopsorg/ghost-on-kubernetes/blob/main/deploy/07-ingress.yaml)

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
Expand Down

0 comments on commit 31bd864

Please sign in to comment.