Memos, a self-hosted, simple stream of your notes
03-28-2023 • Memos, Kubernetes, Note-taking
Memos is a self-hosted application that simplifies note-taking by allowing users to save notes in a simple, unordered stream. Whether it's text, links, images, or PDF files, Memos can help you to keep track of your notes.
Prerequisite
Before getting started, it's important to note that you'll need a running Kubernetes cluster to follow this post. If you don't already have one available, consider using kind for now.
Memos
Structured note-taking can be a challenge, and there are many open-source projects available that attempt to solve this problem in different ways. To see what's available, check out the up-to-date list on GitHub.
Structured note-taking is a pretty tough task on its own, there are a lot of open-source projects, that try to solve this in different ways. You can find an up-to-date list of available projects on GitHub.
Memos itself is only a server and a web app, that will store your notes, that are based on Markdown, within a SQLite database.
Despite providing a web application out of the box, there is also a project called Moe Memos, that provides clients for Android and iOS.
TIP
There is a memos demo available online!
Kubernetes
In order to deploy memos, we need several Kubernetes resources:
code/
├── deployment.yaml
├── kustomization.yaml
├── namespace.yaml
├── pvc-hostpath.yaml
├── pvc.yaml
└── service.yaml
kustomization.yaml
Let's start by creating a kustomization.yaml
, that will be used to bundle all other resources:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: memos
resources:
- namespace.yaml
- deployment.yaml
- service.yaml
- pvc.yaml
namespace.yaml
The most obvious resource is the namespace
, so let's create it:
kind: Namespace
apiVersion: v1
metadata:
name: memos
pvc.yaml
After creating the namespace, we will create a PersistentVolumeClaim
, that is used to persist our data:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: memos
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: ssd
TIP
If you don't have a custom storage class available within your cluster, you can also use a volume of type hostPath
.
apiVersion: v1
kind: PersistentVolume
metadata:
name: memos
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
deployment.yaml
As we have defined a persistent volume for our memos server, we can continue to deploy memos itself:
apiVersion: apps/v1
kind: Deployment
metadata:
name: memos
spec:
replicas: 1
selector:
matchLabels:
app: memos
template:
metadata:
labels:
app: memos
spec:
containers:
- name: memos
image: docker.io/neosmemo/memos:0.11.2
ports:
- containerPort: 5230
protocol: TCP
env:
- name: PUID
value: "1000"
- name: PGID
value: "1000"
volumeMounts:
- name: data
mountPath: /var/opt/memos
securityContext:
fsGroup: 1000
volumes:
- name: data
persistentVolumeClaim:
claimName: memos
readOnly: false
TIP
This post might be outdated pretty soon, you might want to check the official Docker repository of memos to see if there is a new version available.
service.yaml
As you might want to expose the deployment by using a custom ingress controller, we also create a service
.
apiVersion: v1
kind: Service
metadata:
name: memos
spec:
ports:
- name: memos
port: 80
protocol: TCP
targetPort: 5230
selector:
app: memos
Access
After exposing the service to your local network, you can connect to memos by using the browser or the available clients mentioned previously.
TIP
A restart/redeployment of the server will cause all clients to lose their connection. This is a known issue and can be solved, by using the OpenAPI login within the mobile applications.
Verdict
Memos is a very simple note-taking application, that is pretty simple, but also powerful and can be easily deployed within a homelab.