I had been thinking about adding a commenting system to this blog for a while, but I didn’t want to use a external provider like Disqus or Commento. Those are totally valid options, but I just wanted to self-host my stuff all the way.
The task of setting up a commenting system seemed pretty complicated at first. I had to take care of HTTPS, user authentication, persistent storage, and blog integration. Recently, though, I realized that I had already set up most of the stuff needed, and there was a project that could help me with the rest: Remark42.
This self-hosted solution can handle user registration/authentication through OAuth providers, and stores blog comments in a file-based data store.
In my case, the prerequisites are satisfied as such:
Blog integration: The theme I’m using supports Remark42 integration. Hugo Theme Stack
Deploy Remark42
Remark42 can be deployed either with a helm chart or with some manifests. I chose the latter to better integrate with Kustomize.
The manifest available here pretty much worked out of the box. I just extracted the secrets to the kustomization file and defined a traefik ingress. The process is pretty similar to this post: Define application manifest using Kustomize.
I used Kustomize since I wanted a staging and a production environment, but feel free to just use the manifests.
# base/comment.yml# use the default storage classapiVersion:v1kind:PersistentVolumeClaimmetadata:name:remark42spec:accessModes:- ReadWriteOnceresources:requests:storage:10Gi---apiVersion:apps/v1kind:Deploymentmetadata:name:remark42labels:app:remark42spec:replicas:1selector:matchLabels:app:remark42strategy:type:Recreatetemplate:metadata:labels:app:remark42spec:containers:- name:remark42image:ghcr.io/umputun/remark42:v1.14.0ports:- containerPort:8080env:- name:REMARK_URLvalueFrom:configMapKeyRef:name:blog-cmkey:COMMENT_URL- name:SITEvalueFrom:configMapKeyRef:name:blog-cmkey:BLOG_NAME- name:SECRETvalueFrom:secretKeyRef:name:remark42key:SECRET- name:AUTH_GOOGLE_CIDvalueFrom:secretKeyRef:name:remark42key:AUTH_GOOGLE_CID- name:AUTH_GOOGLE_CSECvalueFrom:secretKeyRef:name:remark42key:AUTH_GOOGLE_CSEC- name:AUTH_GITHUB_CIDvalueFrom:secretKeyRef:name:remark42key:AUTH_GITHUB_CID- name:AUTH_GITHUB_CSECvalueFrom:secretKeyRef:name:remark42key:AUTH_GITHUB_CSEC- name:ADMIN_SHARED_IDvalue:<admin-shared-id># this can be arbitrary- name:TIME_ZONEvalue:"America/Denver"volumeMounts:- name:srvvarmountPath:/srv/varsecurityContext:readOnlyRootFilesystem:falseresources:requests:cpu:"100m"memory:"25Mi"limits:cpu:"1"memory:"1Gi"securityContext:# Has its own root privilege drop. Can't do runAsUser / runAsGroup.volumes:- name:srvvarpersistentVolumeClaim:claimName:remark42---apiVersion:v1kind:Servicemetadata:name:remark42-webspec:selector:app:remark42ports:- name:httpprotocol:TCPport:8080targetPort:8080
# overlays/prd/kustomization.ymlapiVersion:kustomize.config.k8s.io/v1beta1kind:Kustomizationresources:- ../../base- ingress.yml- certificate.ymlnamespace:blogreplicas:- name:blogcount:2images:- name:jyking99/blog# image for the blog itselfdigest:<digest># updated by ArgoCD Image UpdaterconfigMapGenerator:- name:blog-cmliterals:- BLOG_NAME=jy-blog- COMMENT_URL=https://comment.blog.junyi.mesecretGenerator:- name:remark42literals:- SECRET=<secret># this can be arbitrary- AUTH_GOOGLE_CID=<google-client-id>- AUTH_GOOGLE_CSEC=<google-client-secret>- AUTH_GITHUB_CID=<github-client-id>- AUTH_GITHUB_CSEC=<github-client-secret>
Info
See below for how to obtain the client IDs and secrets.
In the provided manifest, we have to specify the Google and GitHub OAuth client IDs and secrets. Here is how to set up OAuth clients for each provider and get their IDs and secrets.
Clicking on “Create” will give you the client ID and secret.
GitHub OAuth
Go to settings / OAuth Apps in your GitHub account or organization.
Click on “New OAuth App”
Fill in the details like this:
Clicking on “Register application” will give you the client ID and secret.
Hugo Theme Stack integration
Confirm the above is working by running kubectl apply -k overlays/prd. If everything is set up correctly, A Remark42 instance should be running in your cluster.
Info
This part is specific to the theme Hugo Theme Stack. For other themes, consult the theme documentation.
The URL REMARK42_URL is just a placeholder here. In my case it will be updated by the GitHub Actions workflow. Feel free to hardcode it.
GitHub Actions workflow
Since I have an existing workflow that updates the blog image, I just added a step to update the Remark42 URL. Here is the relevant part:
1
2
3
4
5
6
7
8
- name:Set remark42 URLrun:| if [ $BRANCH_NAME == 'master' ]; then
REMARK42_URL=https://comment.blog.junyi.me
else
REMARK42_URL=https://comment.blog.i.junyi.me
fi
sed -i "s|REMARK42_URL|$REMARK42_URL|g" hugo.yml
This will separate the production and staging Remark42 instances.
Conclusion
This is all the steps I took to get a comments section as below working.