Published: Jan 23, 2024 by Isaac Johnson
Cinny is “Yet another Matrix client” as their site puts it. They focus on elegance and simplicity. FluffyChat is a Matrix client with mobile and web versions.
I’ve wanted to circle back on them ever since using Element. They are the other two listed on the “Featured Clients” page of matrix.org
Cinny
The first try will be to just use docker to pull and launch it
We’ll start by pulling the Docker image locally
builder@builder-T100:~$ docker pull ghcr.io/cinnyapp/cinny:latest
latest: Pulling from cinnyapp/cinny
9398808236ff: Already exists
7b8bdebbb770: Pull complete
a2a4fe64baa0: Pull complete
0777b518fc6e: Pull complete
63f4060a8ef3: Pull complete
9cbe387ec693: Pull complete
48703ecfcf80: Pull complete
e6a5b5694466: Pull complete
bad39fabacf7: Pull complete
4c4ed36622de: Pull complete
Digest: sha256:419e4a03cb9e3b1547eeb0e7e14bf6b9ebc42bd0b499bbebcc5b489f2942f489
Status: Downloaded newer image for ghcr.io/cinnyapp/cinny:latest
ghcr.io/cinnyapp/cinny:latest
Now I can launch it
$ docker run -d -p 8088:80 --name cinny --restart always ghcr.io/cinnyapp/cinny:latest
9fe031d651422ed2985eacdf703a23dea559329211bfff0c871cccf63451986a
builder@builder-T100:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fe031d65142 ghcr.io/cinnyapp/cinny:latest "/docker-entrypoint.…" 9 minutes ago Up 8 minutes 0.0.0.0:8088->80/tcp, :::8088->80/tcp cinny
Let’s expose it externally
$ cat r53-cinny.json
{
"Comment": "CREATE cinny fb.s A record ",
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "cinny.freshbrewed.science",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "75.73.224.240"
}
]
}
}
]
}
$ aws route53 change-resource-record-sets --hosted-zone-id Z39E8QFU0F9PZP --change-batch file://r53-cinny.json
{
"ChangeInfo": {
"Id": "/change/C0864129N62OKYFJ8LDK",
"Status": "PENDING",
"SubmittedAt": "2024-01-02T01:33:38.091Z",
"Comment": "CREATE cinny fb.s A record "
}
}
I’ll use Kubernetes to forward out to Docker using the exposed port 8088.
$ cat ingresscinny.yaml
---
apiVersion: v1
kind: Endpoints
metadata:
name: cinny-external-ip
subsets:
- addresses:
- ip: 192.168.1.100
ports:
- name: cinny
port: 8088
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: cinny-external-ip
spec:
clusterIP: None
clusterIPs:
- None
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
- IPv6
ipFamilyPolicy: RequireDualStack
ports:
- name: cinny
port: 80
protocol: TCP
targetPort: 8088
sessionAffinity: None
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.org/websocket-services: cinny-external-ip
generation: 1
labels:
app.kubernetes.io/instance: cinnyingress
name: cinnyingress
spec:
rules:
- host: cinny.freshbrewed.science
http:
paths:
- backend:
service:
name: cinny-external-ip
port:
number: 80
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- cinny.freshbrewed.science
secretName: cinny-tls
$ kubectl apply -f ingresscinny.yaml
endpoints/cinny-external-ip created
service/cinny-external-ip created
ingress.networking.k8s.io/cinnyingress created
Which now loads without issue using TLS
We can compare Element (left) with Cinny (right)
I think the UI on Cinny is quite nice, but I noted it didn’t include the Jitsi video conferencing that Element has.
I tested private messaging which works fine
Fluffychat
FluffyChat is another nice client with an App for phones and web. You can find the code and steps in Github.
My first step was to try and build the Dockerfile in the repo
builder@DESKTOP-QADGF36:~/Workspaces/fluffychat$ docker build -t fluffychat:0.0.1 .
[+] Building 2.7s (5/5) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 38B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/nginx:alpine 0.8s
=> ERROR [internal] load metadata for ghcr.io/cirruslabs/flutter:latest 1.8s
=> [auth] cirruslabs/flutter:pull token for ghcr.io 0.0s
------
> [internal] load metadata for ghcr.io/cirruslabs/flutter:latest:
------
failed to solve with frontend dockerfile.v0: failed to create LLB definition: failed to authorize: rpc error: code = Unknown desc = failed to fetch oauth token: unexpected status: 403 Forbidden
I guess you need to periodically login to GHCR
builder@DESKTOP-QADGF36:~/Workspaces/fluffychat$ echo $CR_PAT | docker login ghcr.io -u idjohnson --password-stdin
Login Succeeded
Then I couldn’t find yq
builder@DESKTOP-QADGF36:~/Workspaces/fluffychat$ docker build -t fluffychat:0.0.1 .
[+] Building 50.5s (13/16)
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 38B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/nginx:alpine 2.1s
=> [internal] load metadata for ghcr.io/cirruslabs/flutter:latest 5.2s
=> [auth] cirruslabs/flutter:pull token for ghcr.io 0.0s
=> [internal] load build context 7.0s
=> => transferring context: 603.82MB 6.9s
=> [stage-1 1/3] FROM docker.io/library/nginx:alpine@sha256:a59278fd22a9d411121e190b8cec8aa57b306aa3332459197777583beb728f59 3.4s
=> => resolve docker.io/library/nginx:alpine@sha256:a59278fd22a9d411121e190b8cec8aa57b306aa3332459197777583beb728f59 0.0s
=> => sha256:a59278fd22a9d411121e190b8cec8aa57b306aa3332459197777583beb728f59 6.70kB / 6.70kB 0.0s
=> => sha256:529b5644c430c06553d2e8082c6713fe19a4169c9dc2369cbb960081f52924ff 11.72kB / 11.72kB 0.0s
=> => sha256:c926b61bad3b94ae7351bafd0c184c159ebf0643b085f7ef1d47ecdc7316833c 3.40MB / 3.40MB 0.3s
=> => sha256:2d2a2257c6e9d2e5b50d4fbeb436d8d2b55631c2a89935a425b417eb95212686 2.19kB / 2.19kB 0.0s
=> => sha256:fed54a1dc458a7f591fa1c986669998655ad54d260d53691c8ef4841185883d4 1.90MB / 1.90MB 0.3s
=> => sha256:d4735778d47c0be8db66c446904aa2ba47f3e7509c0c9c3985ecb3b96bb7179f 629B / 629B 0.3s
=> => extracting sha256:c926b61bad3b94ae7351bafd0c184c159ebf0643b085f7ef1d47ecdc7316833c 0.2s
=> => sha256:8695c106552e600555fefc1bc2b299b420c52583bbf537e6c0468bc7821a3f7b 955B / 955B 0.4s
=> => sha256:9e50a0e580b1e5240c8bf21f791b11fb7a8f3c04249f5db56f1bc72f2fa73929 1.21kB / 1.21kB 0.4s
=> => sha256:dffa16519b51a7abc6df8837b2ceffb699eedd09394ecfeff363ae5321cb7ad2 366B / 366B 0.6s
=> => sha256:5ddd532e9cec09472cd07e594cb6dce78c43ba5248310263f8f766c74b9fb6ae 1.40kB / 1.40kB 0.5s
=> => sha256:fe117667dcd024947ead1f25ad99a5e522efcf3b7dbd0752b6fb5e73feffb407 12.65MB / 12.65MB 0.8s
=> => extracting sha256:fed54a1dc458a7f591fa1c986669998655ad54d260d53691c8ef4841185883d4 0.4s
=> => extracting sha256:d4735778d47c0be8db66c446904aa2ba47f3e7509c0c9c3985ecb3b96bb7179f 0.1s
=> => extracting sha256:8695c106552e600555fefc1bc2b299b420c52583bbf537e6c0468bc7821a3f7b 0.1s
=> => extracting sha256:dffa16519b51a7abc6df8837b2ceffb699eedd09394ecfeff363ae5321cb7ad2 0.1s
=> => extracting sha256:9e50a0e580b1e5240c8bf21f791b11fb7a8f3c04249f5db56f1bc72f2fa73929 0.1s
=> => extracting sha256:5ddd532e9cec09472cd07e594cb6dce78c43ba5248310263f8f766c74b9fb6ae 0.1s
=> => extracting sha256:fe117667dcd024947ead1f25ad99a5e522efcf3b7dbd0752b6fb5e73feffb407 0.5s
=> [builder 1/7] FROM ghcr.io/cirruslabs/flutter@sha256:d37cffe5cabbe96f1c59ba5f0d5166f3d7043324279858ba2982e36d1d7361dc 24.6s
=> => resolve ghcr.io/cirruslabs/flutter@sha256:d37cffe5cabbe96f1c59ba5f0d5166f3d7043324279858ba2982e36d1d7361dc 0.0s
=> => sha256:d37cffe5cabbe96f1c59ba5f0d5166f3d7043324279858ba2982e36d1d7361dc 856B / 856B 0.0s
=> => sha256:461a1551032ea5375bfd2b7aa19b74b4c21e375361e96eafa22d80723fa652a2 1.44kB / 1.44kB 0.0s
=> => sha256:6664e9fe749c93a3cc112f0f82a35a8d108d3602adadf8bed6482165ba2a2582 7.61kB / 7.61kB 0.0s
=> => sha256:c5e70d3948ed7b8958a65e1f9b663debedbc130485f07741250ec265bbd06a4c 25.58MB / 25.58MB 4.5s
=> => sha256:486c3f4ba609c5cd84ac96c65edf7931aba0a8aea0a7661d2747c60bf5c7c4ee 309.34MB / 309.34MB 15.6s
=> => extracting sha256:c5e70d3948ed7b8958a65e1f9b663debedbc130485f07741250ec265bbd06a4c 1.9s
=> => extracting sha256:486c3f4ba609c5cd84ac96c65edf7931aba0a8aea0a7661d2747c60bf5c7c4ee 8.5s
=> [stage-1 2/3] RUN rm -rf /usr/share/nginx/html 2.8s
=> [builder 2/7] RUN sudo apt update && sudo apt install curl jq -y 15.1s
=> [builder 3/7] COPY . /app 4.0s
=> [builder 4/7] WORKDIR /app 0.0s
=> ERROR [builder 5/7] RUN ./scripts/prepare-web.sh 0.4s
------
> [builder 5/7] RUN ./scripts/prepare-web.sh:
#13 0.402 #!/bin/sh -ve
#13 0.402 rm -r assets/js/package
#13 0.403
#13 0.403 OLM_VERSION=$(cat pubspec.yaml | yq .dependencies.flutter_olm)
#13 0.403 ./scripts/prepare-web.sh: 4: yq: not found
------
executor failed running [/bin/sh -c ./scripts/prepare-web.sh]: exit code: 127
I tried a few ways to install yq including adding homebrew and snap and apt… in the end, just downloaded and extracted a linux x64 tgz from https://github.com/mikefarah/yq/releases and put it next to the Dockerfile. I then added a copy step to put it in /usr/bin
FROM ghcr.io/cirruslabs/flutter as builder
RUN sudo apt update && sudo apt install curl jq -y
COPY ./yq_linux_amd64 /usr/bin/yq
COPY . /app
WORKDIR /app
RUN ./scripts/prepare-web.sh
RUN flutter pub get
RUN flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --release --source-maps
FROM docker.io/nginx:alpine
RUN rm -rf /usr/share/nginx/html
COPY --from=builder /app/build/web /usr/share/nginx/html
This worked, but did take a long time to build
$ docker build -t fluffychat:0.0.1 .
[+] Building 108.3s (14/16)
[+] Building 164.9s (14/16)
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 463B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/nginx:alpine 2.5s
=> [internal] load metadata for ghcr.io/cirruslabs/flutter:latest 2.9s
=> [builder 1/8] FROM ghcr.io/cirruslabs/flutter@sha256:d37cffe5cabbe96f1c59ba5f0d5166f3d7043324279858ba2982e36d1d7361dc 0.0s
=> [internal] load build context 0.2s
=> => transferring context: 14.01MB 0.1s[+] Building 165.0s (14/16)
[+] Building 167.3s (17/17) FINISHED
=> [internal] load build definition from Dockerfile 0.0s.
=> => transferring dockerfile: 463B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/nginx:alpine 2.5s
=> [internal] load metadata for ghcr.io/cirruslabs/flutter:latest 2.9s
=> [builder 1/8] FROM ghcr.io/cirruslabs/flutter@sha256:d37cffe5cabbe96f1c59ba5f0d5166f3d7043324279858ba2982e36d1d7361dc 0.0s
=> [internal] load build context 0.2s
=> => transferring context: 14.01MB 0.1s
=> [stage-1 1/3] FROM docker.io/library/nginx:alpine@sha256:a59278fd22a9d411121e190b8cec8aa57b306aa3332459197777583beb728f59 0.0s
=> CACHED [stage-1 2/3] RUN rm -rf /usr/share/nginx/html 0.0s
=> CACHED [builder 2/8] RUN sudo apt update && sudo apt install curl jq -y 0.0s
=> [builder 3/8] COPY ./yq_linux_amd64 /usr/bin/yq 0.2s
=> [builder 4/8] COPY . /app 3.2s
=> [builder 5/8] WORKDIR /app 0.0s
=> [builder 6/8] RUN ./scripts/prepare-web.sh 1.3s
=> [builder 7/8] RUN flutter pub get 40.7s
=> [builder 8/8] RUN flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --release --source-maps 117.4s
=> [stage-1 3/3] COPY --from=builder /app/build/web /usr/share/nginx/html 0.2s
=> exporting to image 0.3s
=> => exporting layers 0.2s
=> => writing image sha256:ba0af52ba2e086499120d09d5dc2368ee65c1ce05b1128f2f9977169c2b7c3cf 0.0s
=> => naming to docker.io/library/fluffychat:0.0.1
I could now fire up a test
builder@DESKTOP-QADGF36:~/Workspaces/fluffychat$ docker run -p 9090:80 fluffychat:0.0.1
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/01/03 12:37:59 [notice] 1#1: using the "epoll" event method
2024/01/03 12:37:59 [notice] 1#1: nginx/1.25.3
2024/01/03 12:37:59 [notice] 1#1: built by gcc 12.2.1 20220924 (Alpine 12.2.1_git20220924-r10)
2024/01/03 12:37:59 [notice] 1#1: OS: Linux 5.15.133.1-microsoft-standard-WSL2
2024/01/03 12:37:59 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/01/03 12:37:59 [notice] 1#1: start worker processes
2024/01/03 12:37:59 [notice] 1#1: start worker process 30
2024/01/03 12:37:59 [notice] 1#1: start worker process 31
2024/01/03 12:37:59 [notice] 1#1: start worker process 32
2024/01/03 12:37:59 [notice] 1#1: start worker process 33
2024/01/03 12:37:59 [notice] 1#1: start worker process 34
2024/01/03 12:37:59 [notice] 1#1: start worker process 35
2024/01/03 12:37:59 [notice] 1#1: start worker process 36
2024/01/03 12:37:59 [notice] 1#1: start worker process 37
2024/01/03 12:37:59 [notice] 1#1: start worker process 38
2024/01/03 12:37:59 [notice] 1#1: start worker process 39
2024/01/03 12:37:59 [notice] 1#1: start worker process 40
2024/01/03 12:37:59 [notice] 1#1: start worker process 41
2024/01/03 12:37:59 [notice] 1#1: start worker process 42
2024/01/03 12:37:59 [notice] 1#1: start worker process 43
2024/01/03 12:37:59 [notice] 1#1: start worker process 44
2024/01/03 12:37:59 [notice] 1#1: start worker process 45
172.17.0.1 - - [03/Jan/2024:12:38:13 +0000] "GET / HTTP/1.1" 200 2485 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "-"
172.17.0.1 - - [03/Jan/2024:12:38:13 +0000] "GET /splash/style.css HTTP/1.1" 200 674 "http://localhost:9090/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "-"
172.17.0.1 - - [03/Jan/2024:12:38:13 +0000] "GET /flutter.js HTTP/1.1" 200 14326 "http://localhost:9090/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "-"
It seemed rather stuck on the server picklist
I think I need to create a config.json
and build again
builder@DESKTOP-QADGF36:~/Workspaces/fluffychat$ vi config.sample.json
builder@DESKTOP-QADGF36:~/Workspaces/fluffychat$ cp config.sample.json config.json
builder@DESKTOP-QADGF36:~/Workspaces/fluffychat$ vi config.json
builder@DESKTOP-QADGF36:~/Workspaces/fluffychat$ cat config.json
{
"application_name": "FluffyChat for FB",
"application_welcome_message": "Welcome to Fresh/Brewed",
"default_homeserver": "matrix.freshbrewed.science",
"web_base_url": "https://freshbrewed.science/",
"privacy_url": "https://fluffychat.im/en/privacy.html",
"render_html": true,
"hide_redacted_events": false,
"hide_unknown_events": false
}
builder@DESKTOP-QADGF36:~/Workspaces/fluffychat$ docker build -t fluffychat:0.0.2 .
[+] Building 30.0s (12/16)
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 38B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/nginx:alpine 2.0s
=> [internal] load metadata for ghcr.io/cirruslabs/flutter:latest 1.4s
=> [internal] load build context
...snip...
I also took a moment to fix the Dockerfile in a more re-usable way - that is, pull down yq
during the build as opposed to needing to get a tgz download handy.
FROM ghcr.io/cirruslabs/flutter as builder
RUN sudo apt update && sudo apt install curl wget jq -y
WORKDIR /tmp
RUN wget https://github.com/mikefarah/yq/releases/download/v4.40.5/yq_linux_amd64.tar.gz
RUN tar -xzvf ./yq_linux_amd64.tar.gz
RUN mv yq_linux_amd64 /usr/bin/yq
COPY . /app
WORKDIR /app
RUN ./scripts/prepare-web.sh
RUN flutter pub get
RUN flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --release --source-maps
FROM docker.io/nginx:alpine
RUN rm -rf /usr/share/nginx/html
COPY --from=builder /app/build/web /usr/share/nginx/html
It did not set a default and still shows an error, but I did manage to just type in the homeserver and hit enter and it worked to login
builder@DESKTOP-QADGF36:~/Workspaces/fluffychat$ docker run -p 9090:80 fluffychat:0.0.3
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/01/03 12:54:35 [notice] 1#1: using the "epoll" event method
2024/01/03 12:54:35 [notice] 1#1: nginx/1.25.3
2024/01/03 12:54:35 [notice] 1#1: built by gcc 12.2.1 20220924 (Alpine 12.2.1_git20220924-r10)
2024/01/03 12:54:35 [notice] 1#1: OS: Linux 5.15.133.1-microsoft-standard-WSL2
2024/01/03 12:54:35 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/01/03 12:54:35 [notice] 1#1: start worker processes
2024/01/03 12:54:35 [notice] 1#1: start worker process 30
...
I tried updating the web/manifest.json
{
"name": "FluffyChat",
"short_name": "FluffyChat",
"start_url": "matrix.freshbrewed.science",
"default_homeserver": "matrix.freshbrewed.science",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "The cutest messenger in the Matrix network",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
I tried forcing the config copy in the Dockerfile
FROM ghcr.io/cirruslabs/flutter as builder
RUN sudo apt update && sudo apt install curl wget jq -y
WORKDIR /tmp
RUN wget https://github.com/mikefarah/yq/releases/download/v4.40.5/yq_linux_amd64.tar.gz
RUN tar -xzvf ./yq_linux_amd64.tar.gz
RUN mv yq_linux_amd64 /usr/bin/yq
COPY . /app
WORKDIR /app
RUN ./scripts/prepare-web.sh
COPY config.json /app/config.json
RUN flutter pub get
RUN flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --release --source-maps
FROM docker.io/nginx:alpine
RUN rm -rf /usr/share/nginx/html
COPY --from=builder /app/build/web /usr/share/nginx/html
But I just could not get it to take the changes. I ultimately forced it by updating the .dart
file which seems a bit extreme
which we can see
I was about to blame Fluffychat for not decrypting prior messages, but then I realized this is a ?feature? of the end-to-end built-in encryption.
The conversation I started yesterday from Cinny Web as my GMail identity on matrix.org just couldn’t decrypt outside of that session
Note: if you do want to backup messages, you can set aside the key under settings
Clearly nothing (by default) is stored on the server, so logging back into Cinny web as my GMail identity didn’t help. I would need to power up the laptop used yesterday to decrypt those messages
For the security minded, that is handy. But if you use chat for history, one can suggest busting into a new room if discussing something you want history on or transferring between clients.
I can see calls work just fine between Element and Fluffychat (but not Cinny)
Cinny shows the calls as “Unsupported message”
Lastly, in the themes area, we can tweak light and dark mode as well as font size. Here I switched to light mode with smaller fonts
Hosting
Let me push the local build to my CR
builder@DESKTOP-QADGF36:~$ docker tag fluffychat:0.0.6 harbor.freshbrewed.science/freshbrewedprivate/fluffychat:0.0.6
builder@DESKTOP-QADGF36:~$ docker push harbor.freshbrewed.science/freshbrewedprivate/fluffychat:0.0.6
The push refers to repository [harbor.freshbrewed.science/freshbrewedprivate/fluffychat]
8a4818a2a13a: Pushed
4fc9dfc985df: Pushed
2d33248ce9da: Pushed
9770295d804c: Pushed
62e59aa00d24: Pushed
769b844042ad: Pushed
4c6b2fc6378f: Pushed
c612d245f985: Pushed
3d49ee199a5c: Pushed
9fe9a137fd00: Pushed
0.0.6: digest: sha256:686cf5ec4c595080e7ce76171c881c4d209cbc8a0033c99b630555d964d6670d size: 2408
Now on the Dockerhost I’ll pull down that image
builder@builder-T100:~$ docker pull harbor.freshbrewed.science/freshbrewedprivate/fluffychat:0.0.6
0.0.6: Pulling from freshbrewedprivate/fluffychat
c926b61bad3b: Already exists
fed54a1dc458: Pull complete
d4735778d47c: Pull complete
8695c106552e: Pull complete
dffa16519b51: Pull complete
9e50a0e580b1: Pull complete
5ddd532e9cec: Pull complete
fe117667dcd0: Pull complete
89e33d70780f: Pull complete
438b8669ac0d: Pull complete
Digest: sha256:686cf5ec4c595080e7ce76171c881c4d209cbc8a0033c99b630555d964d6670d
Status: Downloaded newer image for harbor.freshbrewed.science/freshbrewedprivate/fluffychat:0.0.6
harbor.freshbrewed.science/freshbrewedprivate/fluffychat:0.0.6
I’ll pick a port and start it
builder@builder-T100:~$ sudo docker run -p 9095:80 --restart unless-stopped --name fluffychat -d harbor.freshbrewed.science/freshbrewedprivate/fluffychat:0.0.6
15c7521468041cb9c5ce26928ab44ddb324c1af353ce2eadd9330f1bf2329591
Just like Cinny, let’s create an A Record
$ cat r53-fluffychat.json
{
"Comment": "CREATE fluffychat fb.s A record ",
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "fluffychat.freshbrewed.science",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "75.73.224.240"
}
]
}
}
]
}
$ aws route53 change-resource-record-sets --hosted-zone-id Z39E8QFU0F9PZP --change-batch file://r53-fluffychat.json
{
"ChangeInfo": {
"Id": "/change/C0880875M09JKJ8EH63E",
"Status": "PENDING",
"SubmittedAt": "2024-01-03T14:25:32.490Z",
"Comment": "CREATE fluffychat fb.s A record "
}
}
Let’s then create the Kubernetes passthrough that will sort out Certs
$ cat ingressfluffy.yaml
---
apiVersion: v1
kind: Endpoints
metadata:
name: fluffychat-external-ip
subsets:
- addresses:
- ip: 192.168.1.100
ports:
- name: fluffychat
port: 9095
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: fluffychat-external-ip
spec:
clusterIP: None
clusterIPs:
- None
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
- IPv6
ipFamilyPolicy: RequireDualStack
ports:
- name: fluffychat
port: 80
protocol: TCP
targetPort: 9095
sessionAffinity: None
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.org/websocket-services: fluffychat-external-ip
generation: 1
labels:
app.kubernetes.io/instance: fluffychatingress
name: fluffychatingress
spec:
rules:
- host: fluffychat.freshbrewed.science
http:
paths:
- backend:
service:
name: fluffychat-external-ip
port:
number: 80
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- fluffychat.freshbrewed.science
secretName: fluffychat-tls
$ kubectl apply -f ingressfluffy.yaml
endpoints/fluffychat-external-ip created
service/fluffychat-external-ip created
ingress.networking.k8s.io/fluffychatingress created
And we can see it live now at https://fluffychat.freshbrewed.science/#/home
Mobile app
The mobile app is free on the Play store.
We can see won’t show prior encrypted messages
It doesn’t have the same navigation. Just the chats you have been in lately. This is a deal breaker for me.
It has the idea of “Stories”, whatever those are and can show you “Public Rooms” which seemed a bit shady to me.
Summary
Both Cinny and Fluffychat are compelling options. I likely wouldn’t stick with Cinny just because it lacks calling. For me, that’s a requirement.
I didn’t cover the mobile app in detail as it’s pretty basic. The element app on Android is definitely superior.