Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
1eb8c99d2c | |||
5c326ed1ae | |||
fb2aa0f67c | |||
fb81d51e29 | |||
5e6f732fed | |||
f85afce8c8 | |||
76280f3e7b | |||
356afda8a7 | |||
e9bd94e860 | |||
b0be20f5f3 | |||
26329ee584 | |||
e37d746c69 | |||
86548c594a | |||
ef34fdc759 |
31
Dockerfile
31
Dockerfile
@ -1,19 +1,16 @@
|
|||||||
FROM node:4-slim
|
FROM node:lts-alpine
|
||||||
|
|
||||||
RUN useradd --create-home app \
|
RUN apk add --update --no-cache \
|
||||||
&& apt-get update \
|
dumb-init \
|
||||||
&& apt-get install -y --no-install-recommends \
|
git \
|
||||||
jq
|
jq
|
||||||
WORKDIR /home/app
|
WORKDIR "/home/node"
|
||||||
ARG WIKI_PACKAGE=wiki@0.12.1
|
ARG WIKI_PACKAGE=wiki@0.20.0
|
||||||
RUN su app -c "npm install -g --prefix . $WIKI_PACKAGE"
|
RUN su node -c "npm install -g --prefix . $WIKI_PACKAGE"
|
||||||
RUN su app -c "mkdir .wiki"
|
RUN su node -c "mkdir -p .wiki"
|
||||||
COPY configure-and-launch-wiki set-owner-name ./
|
VOLUME "/home/node/.wiki"
|
||||||
RUN chown app configure-and-launch-wiki set-owner-name
|
|
||||||
VOLUME "/home/app/.wiki"
|
|
||||||
ENV DOMAIN=localhost
|
|
||||||
ENV OWNER_NAME="The Owner"
|
|
||||||
ENV COOKIE=insecure
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
USER app
|
USER node
|
||||||
CMD ["./configure-and-launch-wiki"]
|
ENV PATH="${PATH}:/home/node/bin"
|
||||||
|
ENTRYPOINT ["dumb-init"]
|
||||||
|
CMD ["wiki", "--farm", "--security_type=friends"]
|
||||||
|
77
README.md
77
README.md
@ -1,59 +1,58 @@
|
|||||||
# Federated Wiki Farm
|
# Federated Wiki Farm
|
||||||
|
|
||||||
http://fed.wiki.org
|
Start Playing Federated Wiki: http://start.fed.wiki
|
||||||
|
|
||||||
### Get acquainted with wiki.
|
### Run a local wiki farm
|
||||||
|
|
||||||
Launch the container:
|
docker run -p 3000:3000 -it --rm \
|
||||||
``` bash
|
dobbs/farm
|
||||||
docker run -p 3000:3000 -it --rm \
|
|
||||||
dobbs/farm
|
|
||||||
```
|
|
||||||
|
|
||||||
Visit http://localhost:3000
|
Visit http://localhost:3000 and http://anything.localtest.me:3000
|
||||||
|
|
||||||
### Make your wiki survive a reboot
|
### Run a local wiki that will survive a reboot
|
||||||
|
|
||||||
Create a volume:
|
docker run -p 3000:3000 -it --rm \
|
||||||
|
-v ~/.wiki:/home/node/.wiki \
|
||||||
|
dobbs/farm
|
||||||
|
|
||||||
``` bash
|
Your wiki pages and configuration will be saved in the ~/.wiki folder.
|
||||||
docker volume create dot-wiki
|
|
||||||
```
|
|
||||||
|
|
||||||
Launch the container:
|
# Release Notes for 1.0.0
|
||||||
``` bash
|
|
||||||
docker run -p 3000:3000 -it --rm \
|
|
||||||
-v dot-wiki:/home/app/.wiki \
|
|
||||||
dobbs/farm
|
|
||||||
```
|
|
||||||
|
|
||||||
Visit http://localhost:3000
|
This is a significant **breaking** change from pre-1.0 releases. Especially:
|
||||||
|
|
||||||
### Make your wiki a local 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)`)
|
||||||
|
|
||||||
We're going to use http://localtest.me instead of localhost for our
|
* no longer installing `bash`, `configure-wiki`, nor `set-owner-name`
|
||||||
domain name. See http://readme.localtest.me for more info.
|
|
||||||
|
|
||||||
Let's also use a different volume for this one:
|
* no longer creating `/home/app/.wiki/wiki.json`
|
||||||
``` bash
|
|
||||||
docker volume create localtest.me
|
|
||||||
```
|
|
||||||
|
|
||||||
Specify the domain name when you launch your wiki
|
Those changes in particular will impose some work on authors upgrading
|
||||||
``` bash
|
from previous versions.
|
||||||
docker run -p 3000:3000 -it --rm \
|
|
||||||
-v localtest.me:/home/app/.wiki \
|
|
||||||
-e DOMAIN=localtest.me \
|
|
||||||
dobbs/farm
|
|
||||||
```
|
|
||||||
|
|
||||||
Open http://this.localtest.me:3000 in one tab.
|
The last non-breaking revision is 0.52.0 https://github.com/dobbs/farm/tree/0.52.0#readme
|
||||||
Open http://that.localtest.me:3000 in another.
|
|
||||||
|
|
||||||
# Development
|
# Development
|
||||||
|
|
||||||
|
This image's tag does not match the version of the included wiki software.
|
||||||
|
|
||||||
|
Notes to self:
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
VERSION=0.12.0
|
docker build --tag dobbs/farm:0.51.0 .
|
||||||
docker build --build-arg VERSION=$VERSION -t dobbs/farm:$VERSION .
|
git tag -am "" '0.51.0'
|
||||||
git tag -am "" $VERSION
|
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
|
||||||
```
|
```
|
||||||
|
@ -1,77 +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
|
|
||||||
exec-wiki
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
exec-wiki() {
|
|
||||||
exec /home/app/bin/wiki
|
|
||||||
}
|
|
||||||
|
|
||||||
main
|
|
27
examples/k8s/README.md
Normal file
27
examples/k8s/README.md
Normal 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
130
examples/k8s/wiki.yaml
Normal 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
|
@ -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 "$@"
|
|
Reference in New Issue
Block a user