9 Commits

Author SHA1 Message Date
1eb8c99d2c Upgrade to wiki 0.20.0 2020-01-09 22:41:29 -07:00
5c326ed1ae Add help to remember how to start all the things 2019-12-25 13:08:08 -07:00
fb2aa0f67c Add example kubernetes deployment
This configuration partially works with kubernetes 1.15 running
locally using Docker Desktop for Mac and kind (k8s in docker).

For completeness, we installed kind & created a cluster like this:

    cd /tmp/ && GO111MODULE="on" go get sigs.k8s.io/kind
    kind create cluster --name workshop
    export KUBECONFIG="$(kind get kubeconfig-path --name="workshop")"

We describe finicky details discovered while creating wiki.yaml.

The persistent volume when mounted in wiki-config begins its life with
all files owned by root. This prevented our node user inside the
container from creating the config files inside .wiki. It took a while
to discover the correct securityContext for the wiki-config container.

We tested this configuration as follows:

    alias k=kubectl
    k apply -f wiki.yaml
    export POD=$(k get pod -lapp=wiki -o jsonpath='{.items[*].metadata.name}')
    export PASSWORD=$(k exec svc/wiki-service -- jq -r .admin .wiki/config.json)
    k port-forward svc/wiki-service 3000:80 > /dev/null &
    pbcopy <<<"$PASSWORD"
    open http://localhost:3000
    # click lock icon in the browser to login to wiki page
    # paste the password from the clipboard
    # click wiki to toggle editing on
    # make a few edits to the wiki page

Something about authentication is NOT working for anything except
localhost. When we try the same tests using http://localtest.me or
configuring foo.local in the MacOS /etc/hosts file, for some reason
the cookies don't seem to be passed through to the server. All edits
on other pages end up in browser localStorage.

Nevertheless, I'll commit what I have for now.
2019-11-22 12:24:34 -07:00
fb81d51e29 Use default node user & dumb-init & remove config assumptions
By default the wiki will run in farm mode with friends security
2019-11-16 16:49:43 -07:00
5e6f732fed Bump wiki to version 0.19.0 2019-08-14 12:07:10 -04:00
f85afce8c8 Change base image to node:10-alpine & wiki to 0.17.0 2019-03-27 22:26:09 -06:00
76280f3e7b Update wiki to 0.16.2 2019-03-11 08:00:53 -06:00
356afda8a7 Update wiki version for security fix 2018-11-27 21:10:15 -08:00
e9bd94e860 remind myself how to publish plugin experiments 2018-02-28 08:23:21 -07:00
6 changed files with 206 additions and 154 deletions

View File

@ -1,20 +1,16 @@
FROM node:8-slim
FROM node:lts-alpine
RUN useradd --create-home app \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
jq \
git
WORKDIR /home/app
ARG WIKI_PACKAGE=wiki@0.14.0
RUN su app -c "npm install -g --prefix . $WIKI_PACKAGE"
RUN su app -c "mkdir .wiki"
COPY configure-wiki set-owner-name ./
RUN chown app configure-wiki set-owner-name
VOLUME "/home/app/.wiki"
ENV DOMAIN=localhost
ENV OWNER_NAME="The Owner"
ENV COOKIE=insecure
RUN apk add --update --no-cache \
dumb-init \
git \
jq
WORKDIR "/home/node"
ARG WIKI_PACKAGE=wiki@0.20.0
RUN su node -c "npm install -g --prefix . $WIKI_PACKAGE"
RUN su node -c "mkdir -p .wiki"
VOLUME "/home/node/.wiki"
EXPOSE 3000
USER app
CMD ["/home/app/bin/wiki"]
USER node
ENV PATH="${PATH}:/home/node/bin"
ENTRYPOINT ["dumb-init"]
CMD ["wiki", "--farm", "--security_type=friends"]

View File

@ -1,48 +1,58 @@
# Federated Wiki Farm
http://fed.wiki.org
Start Playing Federated Wiki: http://start.fed.wiki
Although this container can run alone, I use and develop it with
a reverse proxy. See: https://github.com/dobbs/wiki-tls
### Run a local wiki farm
See also http://local-farm.wiki.dbbs.co for many more details.
docker run -p 3000:3000 -it --rm \
dobbs/farm
### Get acquainted with wiki.
Visit http://localhost:3000 and http://anything.localtest.me:3000
Launch the container:
``` bash
docker run -p 3000:3000 -it --rm \
dobbs/farm
```
### Run a local wiki that will survive a reboot
Visit http://localhost:3000
docker run -p 3000:3000 -it --rm \
-v ~/.wiki:/home/node/.wiki \
dobbs/farm
### Make your wiki survive a reboot
Your wiki pages and configuration will be saved in the ~/.wiki folder.
Create a volume:
# Release Notes for 1.0.0
``` bash
docker volume create dot-wiki
```
This is a significant **breaking** change from pre-1.0 releases. Especially:
Launch the container:
``` bash
docker run -p 3000:3000 -it --rm \
-v dot-wiki:/home/app/.wiki \
dobbs/farm
```
* changed the user from `app` (`uid=1001(app) gid=1001(app) groups=1001(app)`)
to `node` (`uid=1000(node) gid=1000(node) groups=1000(node),1000(node)`)
Visit http://localhost:3000
* no longer installing `bash`, `configure-wiki`, nor `set-owner-name`
* no longer creating `/home/app/.wiki/wiki.json`
Those changes in particular will impose some work on authors upgrading
from previous versions.
The last non-breaking revision is 0.52.0 https://github.com/dobbs/farm/tree/0.52.0#readme
# Development
This image's tag matches the version of the included wiki software.
This image's tag does not match the version of the included wiki software.
Notes to self:
``` bash
git tag -am "" '0.14.0'
docker build --tag dobbs/farm:0.51.0 .
git tag -am "" '0.51.0'
git push --tags
```
The repos in Dockerhub and GitHub are configured to automatically build new tags.
# Publish experimental plugins
``` bash
docker build \
--tag dobbs/farm:0.14.0-frame \
--build-arg WIKI_PACKAGE='dobbs/wiki#frame' \
.
docker push dobbs/farm:0.14.0-frame
```

View File

@ -1,72 +0,0 @@
#!/bin/bash -eu
set -o pipefail
main() {
initialize-environment-vars
assert-file-privileges || report-errors-and-exit
ensure-owner-file
ensure-config-file
show-configs
}
initialize-environment-vars() {
ERRORS=''
readonly OWNER_FILE=/home/app/.wiki/$DOMAIN.owner.json
readonly CONFIG_FILE=/home/app/.wiki/config.json
}
assert-file-privileges() {
[ -w /home/app/.wiki ] \
|| ERRORS="app cannot write to /home/app/.wiki\n${ERRORS}"
[ ${#ERRORS} == 0 ]
}
report-errors-and-exit() {
echo -e $ERRORS
echo "exiting."
exit 1
}
ensure-owner-file() {
if [ ! -r "$OWNER_FILE" ]; then
jq -n --arg name "$OWNER_NAME" --arg secret $(random-string) \
'.name = $name | .friend.secret = $secret' > $OWNER_FILE
fi
}
ensure-config-file() {
if [ ! -r "$CONFIG_FILE" ]; then
> $CONFIG_FILE \
jq -n -M \
--arg admin $(jq -r .friend.secret $OWNER_FILE) \
--arg random $(random-string) \
--arg cookie $COOKIE \
--arg domain $DOMAIN \
--arg owner $OWNER_FILE \
'
.admin = $admin
| .autoseed = true
| .farm = true
| .cookieSecret = $random
| .secure_cookie = ("secure" == $cookie)
| .security_type = "friends"
| .wikiDomains[$domain].id = "/home/app/.wiki/\($domain).owner.json"
'
fi
}
random-string() {
node -e 'console.log(require("crypto").randomBytes(64).toString("hex"))'
}
show-configs() {
set -x
ls -l $OWNER_FILE $CONFIG_FILE
cat $OWNER_FILE
cat $CONFIG_FILE
set +x
}
main

27
examples/k8s/README.md Normal file
View File

@ -0,0 +1,27 @@
# Wiki Farm in Kubernetes
There are easier ways to get started with federated wiki. Here we are
using wiki to drive some learning about kubernetes.
# We're using MacOS, Docker Desktop, and kind
brew cask install docker
brew install kind
kind create cluster --name wiki
# Deploy Wiki
kubectl apply -f wiki.yaml
# Play with the wiki
# pbcopy & open are MacOS commands
kubectl port-forward svc/wiki-service 3000:80 \
> port-forward.log \
2> port-forward.err &
# get admin password on the clipboard
kubectl exec svc/wiki-service -- \
jq -r .admin .wiki/config.json \
| pbcopy
open http://localhost:3000
# login with the password on the clipboard

130
examples/k8s/wiki.yaml Normal file
View File

@ -0,0 +1,130 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dot-wiki
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 4Gi
---
apiVersion: v1
kind: ConfigMap
metadata:
name: wiki-config
data:
config.json: |
{
"admin": "ADMIN",
"farm": true,
"cookieSecret": "RANDOM",
"security_type": "friends",
"secure_cookie": false,
"wikiDomains": {
"local": {
"id": "/home/node/.wiki/local.owner.json"
},
"localhost": {
"id": "/home/node/.wiki/local.owner.json"
},
"localtest.me": {
"id": "/home/node/.wiki/local.owner.json"
},
"local.dbbs.co": {
"id": "/home/node/.wiki/local.owner.json"
}
}
}
local.owner.json: |
{
"name": "The Owner",
"friend": {
"secret": "ADMIN"
}
}
install-config: |
#!/bin/sh
randomstring() {
node -e 'console.log(require("crypto").randomBytes(64).toString("hex"))'
}
readonly ADMIN=$(randomstring)
readonly COOKIE=$(randomstring)
readonly CONFIG=/home/node/.wiki/config.json
readonly OWNER=/home/node/.wiki/local.owner.json
[ -f $CONFIG ] || {
jq --arg admin $ADMIN \
--arg cookie $COOKIE \
'.admin = $admin | .cookieSecret = $cookie' \
/etc/config/config.json \
> $CONFIG
}
[ -f $OWNER ] || {
jq --arg admin $ADMIN \
'.friend.secret = $admin' \
/etc/config/local.owner.json \
> $OWNER
}
chown -R 1000:1000 /home/node/.wiki
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wiki-deployment
spec:
replicas: 1
selector:
matchLabels:
app: wiki
template:
metadata:
labels:
app: wiki
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
initContainers:
- name: wiki-config
image: dobbs/farm:1.0.0
securityContext:
runAsUser: 0
runAsGroup: 0
allowPrivilegeEscalation: false
volumeMounts:
- name: dot-wiki
mountPath: /home/node/.wiki
- name: config-templates
mountPath: /etc/config
command: ["sh", "/etc/config/install-config"]
containers:
- name: farm
image: dobbs/farm:1.0.0
command: ["wiki", "--config", "/home/node/.wiki/config.json"]
ports:
- containerPort: 3000
volumeMounts:
- name: dot-wiki
mountPath: /home/node/.wiki
volumes:
- name: dot-wiki
persistentVolumeClaim:
claimName: dot-wiki
- name: config-templates
configMap:
name: wiki-config
---
apiVersion: v1
kind: Service
metadata:
name: wiki-service
spec:
ports:
- name: http
targetPort: 3000
port: 80
selector:
app: wiki

View File

@ -1,39 +0,0 @@
#!/bin/bash -eu
set -o pipefail
usage() {
cat <<EOF
Usage: $(basename $0) NAME
replaces the owner's name in $OWNER_FILE
EOF
}
main() {
initialize-environment-vars $@ || { usage; exit 1; }
backup-and-save-name
report-success
}
initialize-environment-vars() {
readonly OWNER_FILE=/home/app/.wiki/$DOMAIN.owner.json
readonly OWNER_BACKUP_FILE=$OWNER_FILE-saved-$(date --iso-8601=minutes)
readonly NAME=${@:-missing}
[ ! "$NAME" == "missing" ]
}
backup-and-save-name() {
mv $OWNER_FILE $OWNER_BACKUP_FILE
jq ".name = \"$NAME\"" $OWNER_BACKUP_FILE > $OWNER_FILE
}
report-success() {
cat <<EOF
Owner's name changed to "$NAME"
Previous config is saved in ${OWNER_BACKUP_FILE##$PWD/}
EOF
}
main "$@"