├── cockpit
├── .gitignore
├── docker-compose.yml
└── Readme.md
├── daptin
├── .gitignore
├── Readme.md
└── docker-compose.yml
├── strapi
├── .gitignore
├── Readme.md
└── docker-compose.yml
├── strapi-hasura
├── .gitignore
├── Readme.md
├── Dockerfile
├── docker-compose.yml
└── wait-for.sh
├── directus-chameleon-hasura
├── .gitignore
├── chameleon
│ ├── Dockerfile
│ └── wait-for.sh
├── chameleon-conf
│ └── configuration
│ │ └── default.yml
├── Readme.md
└── docker-compose.yml
├── prime
├── .gitignore
├── prime-docker
│ ├── index.js
│ ├── Dockerfile
│ ├── package.json
│ └── newrelic.js
├── Readme.md
└── docker-compose.yml
├── canner
├── docker-compose.yml
├── generated
│ ├── .dockerignore
│ ├── .gitignore
│ ├── package.json
│ ├── components
│ │ └── layout
│ │ │ └── body.js
│ ├── Dockerfile
│ ├── canner.schema.js
│ ├── schema
│ │ ├── categories.schema.js
│ │ └── posts.schema.js
│ ├── canner.cloud.js
│ └── canner.server.js
└── Readme.md
├── quokka
├── docker-compose.yml
└── Readme.md
├── directus
├── README.md
└── docker-compose.yml
└── Readme.md
/cockpit/.gitignore:
--------------------------------------------------------------------------------
1 | db
--------------------------------------------------------------------------------
/daptin/.gitignore:
--------------------------------------------------------------------------------
1 | db
--------------------------------------------------------------------------------
/strapi/.gitignore:
--------------------------------------------------------------------------------
1 | db
--------------------------------------------------------------------------------
/strapi-hasura/.gitignore:
--------------------------------------------------------------------------------
1 | db
--------------------------------------------------------------------------------
/directus-chameleon-hasura/.gitignore:
--------------------------------------------------------------------------------
1 | db
--------------------------------------------------------------------------------
/prime/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .env
3 | *.log
4 | db
--------------------------------------------------------------------------------
/daptin/Readme.md:
--------------------------------------------------------------------------------
1 | # Daptin
2 |
3 | ```sh
4 | docker-compose up
5 | ```
6 |
7 | Open http://localhost:8080/
8 |
--------------------------------------------------------------------------------
/canner/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | web:
5 | build: ./generated
6 | ports:
7 | - "3000:3000"
8 |
--------------------------------------------------------------------------------
/quokka/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | app:
5 | image: quokka/quokka
6 | ports:
7 | - "5000:5000"
8 |
--------------------------------------------------------------------------------
/canner/generated/.dockerignore:
--------------------------------------------------------------------------------
1 | .cms
2 | node_modules
3 | canner.schema.json
4 | Dockerfile
5 | .dockerignore
6 | .DS_Store
7 | .git
8 | .gitignore
9 |
--------------------------------------------------------------------------------
/quokka/Readme.md:
--------------------------------------------------------------------------------
1 | # Quokka
2 |
3 | ```sh
4 | docker-compose up
5 | ```
6 |
7 | Open http://localhost:5000/admin/
8 |
9 | ```
10 | username: admin
11 | password: admin
12 | ```
--------------------------------------------------------------------------------
/strapi-hasura/Readme.md:
--------------------------------------------------------------------------------
1 | # Strapi
2 |
3 | ```
4 | docker-compose up
5 | ```
6 |
7 | Go to http://localhost:1337/admin/. Register.
8 |
9 | GraphQL http://localhost:8080/
10 |
--------------------------------------------------------------------------------
/canner/generated/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 |
4 | # Canner generated files
5 | .cms
6 | canner.schema.json
7 |
8 | # Error files
9 | npm-debug.log
10 | yarn-error.log
11 |
--------------------------------------------------------------------------------
/strapi-hasura/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM hasura/graphql-engine
2 |
3 | COPY wait-for.sh /bin
4 |
5 | ENV CONNECTION db:5432
6 |
7 | ENTRYPOINT sh -c '/bin/wait-for.sh $CONNECTION -- graphql-engine serve'
8 |
--------------------------------------------------------------------------------
/prime/prime-docker/index.js:
--------------------------------------------------------------------------------
1 | if (process.env.NEW_RELIC_LICENSE_KEY) {
2 | require('newrelic');
3 | }
4 |
5 | if (process.env.SENTRY_DSN) {
6 | require('@sentry/node').init({ dsn: process.env.SENTRY_DSN });
7 | }
8 |
9 | require('@primecms/core');
10 |
--------------------------------------------------------------------------------
/canner/generated/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "canner-project",
3 | "version": "1.0.0",
4 | "description": "canner project",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1"
7 | },
8 | "author": "",
9 | "license": "ISC"
10 | }
11 |
--------------------------------------------------------------------------------
/cockpit/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | web:
5 | image: agentejo/cockpit
6 | ports:
7 | - "8080:80"
8 | restart: always
9 | # volumes:
10 | # - ./db/storage/:/var/www/html/storage
11 | # - ./db/config/:/var/www/html/config
12 |
--------------------------------------------------------------------------------
/prime/Readme.md:
--------------------------------------------------------------------------------
1 | # Prime CMS
2 |
3 | Copied from https://github.com/primecms/heroku
4 |
5 | TODO: change to official Dockerfile as soon as it will be published.
6 |
7 | link: https://docs.primecms.app/#/
8 | version: 0.3.4-beta.0
9 |
10 | ```sh
11 | docker-compose up
12 | ```
13 |
14 | Open http://localhost:4000/
15 |
--------------------------------------------------------------------------------
/canner/Readme.md:
--------------------------------------------------------------------------------
1 | # Canner
2 |
3 | ```sh
4 | docker-compose up
5 | ```
6 |
7 | Open http://localhost:3000/
8 |
9 | ```
10 | username: canner
11 | password: canner
12 | ```
13 |
14 | ## Dockerfile
15 |
16 | Dockerfile and other files generated with
17 |
18 | ```sh
19 | npm i -g @canner/cli
20 | canner init
21 | ```
22 |
--------------------------------------------------------------------------------
/canner/generated/components/layout/body.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Item} from 'canner-helpers';
3 | import {Card} from 'antd';
4 |
5 | export default function Body() {
6 | return (
7 |
10 |
11 |
12 |
13 |
14 | )
15 | }
--------------------------------------------------------------------------------
/prime/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | db:
5 | image: postgres
6 | restart: always
7 | environment:
8 | POSTGRES_PASSWORD: password
9 | volumes:
10 | - ./db/data/:/var/lib/postgresql/data
11 | ports:
12 | - "5432:5432"
13 | app:
14 | build: ./prime-docker
15 | ports:
16 | - "4000:4000"
17 |
--------------------------------------------------------------------------------
/canner/generated/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM canner/builder:latest AS build
2 | WORKDIR /usr/src/app
3 | COPY . .
4 | RUN canner build -s canner.schema.js -c canner.server.js
5 |
6 | # Run
7 | FROM canner/server:latest
8 | WORKDIR /usr/src/app
9 | COPY --from=build /usr/src/app /usr/src/app
10 |
11 | EXPOSE 3000
12 | ENTRYPOINT ["canner-server"]
13 | CMD [ "-c", "canner.server.js" ]
14 |
--------------------------------------------------------------------------------
/strapi/Readme.md:
--------------------------------------------------------------------------------
1 | # Strapi
2 |
3 | ```
4 | docker-compose up
5 | ```
6 |
7 | Go to http://localhost:1337/admin/. Register.
8 |
9 | Go to http://localhost:1337/admin/marketplace. Install GraphQL plugin.
10 |
11 | Add content type.
12 |
13 | Edit permissions http://localhost:1337/admin/plugins/users-permissions/roles/edit/3
14 |
15 | Your API is ready http://localhost:1337/graphql
16 |
--------------------------------------------------------------------------------
/cockpit/Readme.md:
--------------------------------------------------------------------------------
1 | # Cockpit
2 |
3 | ```sh
4 | docker-compose up
5 | ```
6 |
7 | Open http://localhost:8080/install/
8 |
9 | With `volumes` config get following error
10 |
11 | ```
12 | Data folder is not writable: /storage/data
13 | Cache folder is not writable: /storage/cache
14 | Temp folder is not writable: /storage/tmp
15 | Uploads folder is not writable: /storage/uploads
16 | ```
17 |
--------------------------------------------------------------------------------
/directus/README.md:
--------------------------------------------------------------------------------
1 | # Directus
2 |
3 | Copied from https://github.com/directus/docker/tree/master/examples/single-api
4 |
5 | ```sh
6 | docker-compose up
7 | ```
8 |
9 | Open http://localhost:8000/
10 |
11 | ```
12 | login: admin@localhost.com
13 | password: directusrocks
14 | ```
15 |
16 | Myabe would be possible to use with Hasura/Postgraphile with the help of [mysql_fdw](https://github.com/EnterpriseDB/mysql_fdw).
17 |
--------------------------------------------------------------------------------
/prime/prime-docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:lts-alpine
2 |
3 | WORKDIR app
4 |
5 | COPY index.js newrelic.js package.json yarn.lock ./
6 |
7 | RUN yarn
8 |
9 | ENTRYPOINT yarn start
10 |
11 | EXPOSE 4000
12 |
13 | ENV PORT=4000
14 | ENV DATABASE_URL=postgresql://postgres:password@db:5432/postgres
15 | ENV SESSION_SECRET=keyboard-cat-dart
16 |
17 | LABEL version="0.3.4-beta.0"
18 | LABEL maintainer="Birkir Gudjonsson "
19 |
--------------------------------------------------------------------------------
/directus-chameleon-hasura/chameleon/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.7-alpine
2 |
3 | RUN \
4 | apk add --no-cache postgresql-libs && \
5 | apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev && \
6 | pip install pg_chameleon --no-cache-dir && \
7 | apk --purge del .build-deps && \
8 | chameleon set_configuration_files
9 |
10 | COPY wait-for.sh /bin
11 | VOLUME /root/.pg_chameleon
12 |
13 | ENTRYPOINT sh -c '/bin/wait-for.sh db:3306 -- /bin/wait-for.sh pg:5432 -- chameleon init_replica --config default --source mysql --debug'
--------------------------------------------------------------------------------
/daptin/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | db:
5 | image: postgres
6 | restart: always
7 | environment:
8 | POSTGRES_PASSWORD: password
9 | volumes:
10 | - ./db/data/:/var/lib/postgresql/data
11 | ports:
12 | - "5432:5432"
13 | web:
14 | image: daptin/daptin
15 | ports:
16 | - "8080:8080"
17 | restart: always
18 | environment:
19 | DAPTIN_PORT: "8080"
20 | DAPTIN_DB_TYPE: "postgres"
21 | DAPTIN_DB_CONNECTION_STRING: "host=db port=5432 user=postgres password=password dbname=postgres sslmode=disable"
22 | depends_on:
23 | - db
24 |
--------------------------------------------------------------------------------
/canner/generated/canner.schema.js:
--------------------------------------------------------------------------------
1 | import CannerScript, {Body} from 'canner-script';
2 | import Posts from './schema/posts.schema.js';
3 | import Categories from './schema/categories.schema';
4 | import BodyComponent from './components/layout/body';
5 | import {ImgurStorage} from '@canner/storage';
6 |
7 | export const imageStorage = new ImgurStorage({
8 | clientId: 'a214c4836559c77'
9 | });
10 |
11 | const schema = (
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 |
20 | export default schema;
--------------------------------------------------------------------------------
/strapi/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | db:
5 | image: postgres
6 | restart: always
7 | environment:
8 | POSTGRES_PASSWORD: password
9 | volumes:
10 | - ./db/data/:/var/lib/postgresql/data
11 | ports:
12 | - "5432:5432"
13 | strapi:
14 | image: strapi/strapi
15 | depends_on:
16 | - db
17 | ports:
18 | - 1337:1337
19 | environment:
20 | - APP_NAME=strapi-app
21 | - DATABASE_CLIENT=postgres
22 | - DATABASE_HOST=db
23 | - DATABASE_PORT=5432
24 | - DATABASE_USERNAME=postgres
25 | - DATABASE_PASSWORD=password
26 | - DATABASE_NAME=postgres
27 | volumes:
28 | - ./db/strapi-app/:/usr/src/api/strapi-app
--------------------------------------------------------------------------------
/canner/generated/schema/categories.schema.js:
--------------------------------------------------------------------------------
1 |
2 | import CannerScript from 'canner-script';
3 |
4 | export default ({attributes}) => (
5 |
15 |
16 |
27 |
28 | )
--------------------------------------------------------------------------------
/prime/prime-docker/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "primecms-heroku",
3 | "version": "0.3.4-beta.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/primecms/heroku.git"
13 | },
14 | "author": "Birkir Gudjonsson ",
15 | "license": "MIT",
16 | "bugs": {
17 | "url": "https://github.com/primecms/heroku/issues"
18 | },
19 | "homepage": "https://github.com/primecms/heroku",
20 | "dependencies": {
21 | "@primecms/core": "0.3.4-beta.0",
22 | "@primecms/ui": "0.3.4-beta.0",
23 | "@sentry/node": "5.0.7",
24 | "newrelic": "5.6.3"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/directus/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | db:
5 | image: mysql:5.7
6 | restart: always
7 | environment:
8 | MYSQL_DATABASE: "somedb"
9 | MYSQL_ROOT_PASSWORD: "rootpassword"
10 | MYSQL_USER: "someusername"
11 | MYSQL_PASSWORD: "somepassword"
12 | ports:
13 | - 3306:3306
14 | api:
15 | image: directus/api:latest
16 | environment:
17 | DATABASE_HOST: db
18 | DATABASE_NAME: "somedb"
19 | DATABASE_USERNAME: "someusername"
20 | DATABASE_PASSWORD: "somepassword"
21 | ADMIN_EMAIL: "admin@localhost.com"
22 | ADMIN_PASSWORD: "directusrocks"
23 | ports:
24 | - 7000:80
25 | web:
26 | image: directus/app:latest
27 | environment:
28 | API_ENDPOINT: "API; http://localhost:7000/_/"
29 | ports:
30 | - 8000:80
31 |
--------------------------------------------------------------------------------
/strapi-hasura/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | db:
5 | image: postgres
6 | restart: always
7 | environment:
8 | POSTGRES_PASSWORD: password
9 | volumes:
10 | - ./db/data/:/var/lib/postgresql/data
11 | ports:
12 | - "5432:5432"
13 | strapi:
14 | image: strapi/strapi
15 | depends_on:
16 | - db
17 | ports:
18 | - 1337:1337
19 | environment:
20 | - APP_NAME=strapi-app
21 | - DATABASE_CLIENT=postgres
22 | - DATABASE_HOST=db
23 | - DATABASE_PORT=5432
24 | - DATABASE_USERNAME=postgres
25 | - DATABASE_PASSWORD=password
26 | - DATABASE_NAME=postgres
27 | volumes:
28 | - ./db/strapi-app/:/usr/src/api/strapi-app
29 | hasura:
30 | build: ./
31 | ports:
32 | - "8080:8080"
33 | environment:
34 | - HASURA_GRAPHQL_DATABASE_URL=postgresql://postgres:password@db:5432/postgres
35 | - HASURA_GRAPHQL_ENABLE_CONSOLE=true
36 | depends_on:
37 | - db
38 |
--------------------------------------------------------------------------------
/directus-chameleon-hasura/chameleon-conf/configuration/default.yml:
--------------------------------------------------------------------------------
1 | ---
2 | #global settings
3 | pid_dir: "~/.pg_chameleon/pid/"
4 | log_dir: "~/.pg_chameleon/logs/"
5 | log_dest: file
6 | log_level: info
7 | log_days_keep: 10
8 | rollbar_key: ""
9 | rollbar_env: ""
10 |
11 | #postgres destination connection
12 | pg_conn:
13 | host: "pg"
14 | port: "5432"
15 | user: "postgres"
16 | password: "password"
17 | database: "postgres"
18 | charset: "utf8"
19 |
20 | sources:
21 | mysql:
22 | db_conn:
23 | host: "db"
24 | port: "3306"
25 | user: "someusername"
26 | password: "somepassword"
27 | charset: "utf8"
28 | connect_timeout: 10
29 | grant_select_to:
30 | - someusername
31 | lock_timeout: "120s"
32 | my_server_id: 100
33 | replica_batch_size: 10000
34 | replay_max_rows: 10000
35 | batch_retention: "1 day"
36 | copy_max_memory: "300M"
37 | copy_mode: "file"
38 | out_dir: /tmp
39 | sleep_loop: 1
40 | on_error_replay: continue
41 | on_error_read: continue
42 | auto_maintenance: "disabled"
43 | gtid_enable: No
44 | type: mysql
45 |
--------------------------------------------------------------------------------
/directus-chameleon-hasura/Readme.md:
--------------------------------------------------------------------------------
1 | # Directus + Chameleon + Hasura
2 |
3 | Doesn't work :/
4 |
5 | ```
6 | /usr/local/lib/python3.7/site-packages/pg_chameleon/lib/global_lib.py:214: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
7 | self.config = yaml.load(config_file.read())
8 | Traceback (most recent call last):
9 | File "/usr/local/bin/chameleon", line 5, in
10 | exec(compile(open(__file__).read(), __file__, 'exec'))
11 | File "/usr/local/bin/chameleon.py", line 56, in
12 | replica = replica_engine(args)
13 | File "/usr/local/lib/python3.7/site-packages/pg_chameleon/lib/global_lib.py", line 115, in __init__
14 | self.pg_engine.type_override = self.config["type_override"]
15 | KeyError: 'type_override'
16 | Exception ignored in:
17 | Traceback (most recent call last):
18 | File "/usr/local/lib/python3.7/site-packages/pg_chameleon/lib/pg_lib.py", line 609, in __del__
19 | self.disconnect_db()
20 | File "/usr/local/lib/python3.7/site-packages/pg_chameleon/lib/pg_lib.py", line 651, in disconnect_db
21 | if self.pgsql_cur:
22 | AttributeError: 'pg_engine' object has no attribute 'pgsql_cur'
23 | ```
--------------------------------------------------------------------------------
/directus-chameleon-hasura/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | db:
5 | image: mysql:5.7
6 | restart: always
7 | environment:
8 | MYSQL_DATABASE: "somedb"
9 | MYSQL_ROOT_PASSWORD: "rootpassword"
10 | MYSQL_USER: "someusername"
11 | MYSQL_PASSWORD: "somepassword"
12 | ports:
13 | - 3306:3306
14 | # api:
15 | # image: directus/api:latest
16 | # environment:
17 | # DATABASE_HOST: db
18 | # DATABASE_NAME: "somedb"
19 | # DATABASE_USERNAME: "someusername"
20 | # DATABASE_PASSWORD: "somepassword"
21 | # ADMIN_EMAIL: "admin@localhost.com"
22 | # ADMIN_PASSWORD: "directusrocks"
23 | # ports:
24 | # - 7000:80
25 | # web:
26 | # image: directus/app:latest
27 | # environment:
28 | # API_ENDPOINT: "API; http://localhost:7000/_/"
29 | # ports:
30 | # - 8000:80
31 | pg:
32 | image: postgres
33 | restart: always
34 | environment:
35 | POSTGRES_PASSWORD: password
36 | volumes:
37 | - ./db/data/:/var/lib/postgresql/data
38 | ports:
39 | - "5432:5432"
40 | chameleon:
41 | build: ./chameleon
42 | volumes:
43 | - ./chameleon-conf:/root/.pg_chameleon
44 | depends_on:
45 | - pg
46 | - db
47 | # hasura:
48 | # build: ./
49 | # ports:
50 | # - "8080:8080"
51 | # environment:
52 | # - HASURA_GRAPHQL_DATABASE_URL=postgresql://postgres:password@pg:5432/postgres
53 | # - HASURA_GRAPHQL_ENABLE_CONSOLE=true
54 | # depends_on:
55 | # - pg
--------------------------------------------------------------------------------
/strapi-hasura/wait-for.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | TIMEOUT=60
4 | QUIET=0
5 |
6 | echoerr() {
7 | if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
8 | }
9 |
10 | usage() {
11 | exitcode="$1"
12 | cat << USAGE >&2
13 | Usage:
14 | $cmdname host:port [-t timeout] [-- command args]
15 | -q | --quiet Do not output any status messages
16 | -t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout
17 | -- COMMAND ARGS Execute command with args after the test finishes
18 | USAGE
19 | exit "$exitcode"
20 | }
21 |
22 | wait_for() {
23 | for i in `seq $TIMEOUT` ; do
24 | nc -z "$HOST" "$PORT" > /dev/null 2>&1
25 |
26 | result=$?
27 | if [ $result -eq 0 ] ; then
28 | if [ $# -gt 0 ] ; then
29 | exec "$@"
30 | fi
31 | exit 0
32 | fi
33 | sleep 1
34 | done
35 | echo "Operation timed out" >&2
36 | exit 1
37 | }
38 |
39 | while [ $# -gt 0 ]
40 | do
41 | case "$1" in
42 | *:* )
43 | HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
44 | PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
45 | shift 1
46 | ;;
47 | -q | --quiet)
48 | QUIET=1
49 | shift 1
50 | ;;
51 | -t)
52 | TIMEOUT="$2"
53 | if [ "$TIMEOUT" = "" ]; then break; fi
54 | shift 2
55 | ;;
56 | --timeout=*)
57 | TIMEOUT="${1#*=}"
58 | shift 1
59 | ;;
60 | --)
61 | shift
62 | break
63 | ;;
64 | --help)
65 | usage 0
66 | ;;
67 | *)
68 | echoerr "Unknown argument: $1"
69 | usage 1
70 | ;;
71 | esac
72 | done
73 |
74 | if [ "$HOST" = "" -o "$PORT" = "" ]; then
75 | echoerr "Error: you need to provide a host and port to test."
76 | usage 2
77 | fi
78 |
79 | wait_for "$@"
80 |
--------------------------------------------------------------------------------
/directus-chameleon-hasura/chameleon/wait-for.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | TIMEOUT=60
4 | QUIET=0
5 |
6 | echoerr() {
7 | if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
8 | }
9 |
10 | usage() {
11 | exitcode="$1"
12 | cat << USAGE >&2
13 | Usage:
14 | $cmdname host:port [-t timeout] [-- command args]
15 | -q | --quiet Do not output any status messages
16 | -t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout
17 | -- COMMAND ARGS Execute command with args after the test finishes
18 | USAGE
19 | exit "$exitcode"
20 | }
21 |
22 | wait_for() {
23 | for i in `seq $TIMEOUT` ; do
24 | nc -z "$HOST" "$PORT" > /dev/null 2>&1
25 |
26 | result=$?
27 | if [ $result -eq 0 ] ; then
28 | if [ $# -gt 0 ] ; then
29 | exec "$@"
30 | fi
31 | exit 0
32 | fi
33 | sleep 1
34 | done
35 | echo "Operation timed out" >&2
36 | exit 1
37 | }
38 |
39 | while [ $# -gt 0 ]
40 | do
41 | case "$1" in
42 | *:* )
43 | HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
44 | PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
45 | shift 1
46 | ;;
47 | -q | --quiet)
48 | QUIET=1
49 | shift 1
50 | ;;
51 | -t)
52 | TIMEOUT="$2"
53 | if [ "$TIMEOUT" = "" ]; then break; fi
54 | shift 2
55 | ;;
56 | --timeout=*)
57 | TIMEOUT="${1#*=}"
58 | shift 1
59 | ;;
60 | --)
61 | shift
62 | break
63 | ;;
64 | --help)
65 | usage 0
66 | ;;
67 | *)
68 | echoerr "Unknown argument: $1"
69 | usage 1
70 | ;;
71 | esac
72 | done
73 |
74 | if [ "$HOST" = "" -o "$PORT" = "" ]; then
75 | echoerr "Error: you need to provide a host and port to test."
76 | usage 2
77 | fi
78 |
79 | wait_for "$@"
80 |
--------------------------------------------------------------------------------
/prime/prime-docker/newrelic.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /**
3 | * New Relic agent configuration.
4 | *
5 | * See lib/config/default.js in the agent distribution for a more complete
6 | * description of configuration variables and their potential values.
7 | */
8 | exports.config = {
9 | /**
10 | * Array of application names.
11 | */
12 | app_name: ['Prime CMS'],
13 | /**
14 | * Your New Relic license key.
15 | */
16 | license_key: process.env.NEW_RELIC_LICENSE_KEY,
17 | logging: {
18 | /**
19 | * Level at which to log. 'trace' is most useful to New Relic when diagnosing
20 | * issues with the agent, 'info' and higher will impose the least overhead on
21 | * production applications.
22 | */
23 | level: 'info'
24 | },
25 | /**
26 | * When true, all request headers except for those listed in attributes.exclude
27 | * will be captured for all traces, unless otherwise specified in a destination's
28 | * attributes include/exclude lists.
29 | */
30 | allow_all_headers: true,
31 | attributes: {
32 | /**
33 | * Prefix of attributes to exclude from all destinations. Allows * as wildcard
34 | * at end.
35 | *
36 | * NOTE: If excluding headers, they must be in camelCase form to be filtered.
37 | *
38 | * @env NEW_RELIC_ATTRIBUTES_EXCLUDE
39 | */
40 | exclude: [
41 | 'request.headers.cookie',
42 | 'request.headers.authorization',
43 | 'request.headers.proxyAuthorization',
44 | 'request.headers.setCookie*',
45 | 'request.headers.x*',
46 | 'response.headers.cookie',
47 | 'response.headers.authorization',
48 | 'response.headers.proxyAuthorization',
49 | 'response.headers.setCookie*',
50 | 'response.headers.x*'
51 | ]
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/canner/generated/canner.cloud.js:
--------------------------------------------------------------------------------
1 | const {FirebaseCredential} = require("canner-credential");
2 | const {MemoryDataSource} = require('@gqlify/server');
3 |
4 | exports.cms = {
5 | logo: {
6 | src: "https://cdn.canner.io/images/logo/logo-word-white.png",
7 | width: "140px",
8 | height: "50px",
9 | href: "#",
10 | backgroundColor: "#6ba4be"
11 | },
12 | style: {
13 | sidebarTheme: "dark",
14 | navbarTheme: "light",
15 | navbarStyle: {
16 | lineHeight: "50px",
17 | height: "50px"
18 | },
19 | navbarMenuStyle: {
20 | lineHeight: "50px"
21 | },
22 | sidebarMenuStyle: {
23 | height: 'calc(100% - 50px)',
24 | background: '#4c6574'
25 | },
26 | sidebarStyle: {
27 | width: "200px",
28 | },
29 | theme: {
30 | "primary-color": "#f19b90",
31 | "btn-primary-bg": "#f19b90",
32 |
33 | "menu-dark-item-active-bg": "#415663",
34 | "menu-dark-bg": "#415663",
35 | "menu-dark-color": "#eee",
36 |
37 | // common
38 | "border-radius-base": "3px",
39 |
40 | // header
41 | "layout-header-background": "#fff",
42 |
43 | // body
44 | "layout-body-background": "#ecf2f6"
45 | }
46 | },
47 | sidebarMenu: [{
48 | title: "Posts",
49 | pathname: "posts",
50 | icon: "read"
51 | }, {
52 | title: "Categories",
53 | pathname: "categories",
54 | icon: "tag"
55 | }],
56 | }
57 |
58 | exports.graphql = {
59 | dataSources: {
60 | // "default" environment is the required in dataSources
61 | "default": []
62 |
63 | /* See https://www.canner.io/docs/credential-firebase.html to learn how to get */
64 | // "default": [new FirebaseCredential(require("./cert.json"))],
65 |
66 | /* See https://www.canner.io/docs/credential-prisma.html to learn how to get prisma configuration files */
67 | // "default": [new PrismaCredential("path to yaml")],
68 |
69 | /* for PREMIUM plan, you can use more than one env */
70 | // "test": [new FirebaseCredential(require("path to cert.json"))]
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Headless CMS comparison
2 |
3 | Continuation of my [post about Headless CMS comparison](https://dev.to/stereobooster/headless-graphql-cms-51id).
4 |
5 | Comparison of open source headless CMS. Inspired by [MicheleBertoli/css-in-js](https://github.com/MicheleBertoli/css-in-js).
6 |
7 | ## Features
8 |
9 | More ticks doesn't mean "better", it depends on your needs.
10 |
11 | | | GraphQL | Mutations | Custom Fields | D&D Editor | Rich Text Editor | Group Fields | Media Library | Image Manipulation | Image Crops | Asset CDN | Previews | Releases | Localization | Localized fields | Revision history | Webhooks |
12 | | ------ | ------- | --------- | ------------- | ---------- | ---------------- | ------------ | ------------- | ------------------ | ----------- | --------- | -------- | -------- | ------------ | ---------------- | ---------------- | -------- |
13 | | Prime | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 3rd-party | 3rd-party | ✅ | 3rd-party | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
14 | | Strapi | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | 3rd-party | 3rd-party | ❌ | 3rd-party | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
15 |
16 | ## Alternatives
17 |
18 | - https://github.com/netlify/headlesscms.org/tree/master/content/projects
19 | - https://github.com/gentics/headless-cms-comparison
20 | - http://www.cmsmatrix.org/
21 | - https://docs.primecms.app/#/features
22 | - [List of content management systems](https://en.wikipedia.org/wiki/List_of_content_management_systems)
23 |
24 | ## Contributing
25 |
26 | If your CMS is not listed here, feel free to add it.
27 |
28 | 1. Create a new folder named CMS-name in the root folder.
29 | 2. Add `docker-compose.yml`
30 | 3. Add a new entry to `Readme.md`
31 |
32 | ## Other
33 |
34 | ### Database to API
35 |
36 | - [hasura](https://hasura.io/) - Instant Realtime GraphQL on Postgres
37 | - [PostGraphile](https://www.graphile.org/postgraphile/) - Instantly spin-up a GraphQL API server by pointing PostGraphile at your existing PostgreSQL database
38 | - [PostgREST](http://postgrest.org) is a standalone web server that turns your PostgreSQL database directly into a RESTful API
39 | - [tuql](https://github.com/bradleyboy/tuql) is a simple tool that turns a sanely formatted sqlite database into a graphql endpoint
40 |
41 | ### Admin generators
42 |
43 | - [administrate](https://github.com/thoughtbot/administrate) RoR
44 | - [godmin](https://github.com/varvet/godmin) RoR
45 | - [activeadmin](https://github.com/activeadmin/activeadmin) RoR
46 | - [rails_admin](https://github.com/sferik/rails_admin) RoR
47 | - [trestle](https://github.com/TrestleAdmin/trestle) RoR
48 | - [react-admin](https://github.com/marmelab/react-admin) React
49 | - [canner](https://github.com/Canner/canner) React and co
50 |
--------------------------------------------------------------------------------
/canner/generated/schema/posts.schema.js:
--------------------------------------------------------------------------------
1 | import CannerScript, { Tabs, Default } from "canner-script";
2 |
3 | const columns = [
4 | {
5 | title: "Title",
6 | dataIndex: "title"
7 | },
8 | {
9 | title: "Cover",
10 | dataIndex: "coverPicture"
11 | },
12 | {
13 | title: "Published",
14 | dataIndex: "draft",
15 | render: isDraft => {
16 | if (isDraft) return "❌";
17 | return "✔️";
18 | }
19 | }
20 | ];
21 |
22 | const Posts = ({ attributes }) => (
23 |
32 |
33 |
34 |
40 |
41 | {/* reference: https://www.cannercms.com/docs/schema-toolbar-tags#lt-export-gt */}
42 |
47 | {/* reference: https://www.cannercms.com/docs/schema-toolbar-tags#lt-import-gt */}
48 |
57 | {/* reference: https://www.cannercms.com/docs/schema-toolbar-tags#lt-filter-gt-1 */}
58 |
59 |
60 |
61 |
62 |
91 |
92 |
93 |
94 |
95 |
96 |
102 |
110 |
111 |
116 |
117 |
118 |
119 |
133 |
134 |
135 |
136 | );
137 |
138 | export default Posts;
139 |
--------------------------------------------------------------------------------
/canner/generated/canner.server.js:
--------------------------------------------------------------------------------
1 | /** Firebase required packages
2 | *
3 | * https://www.cannercms.com/docs/data-source-firebase
4 | * const {FirebaseDataSource} = require('@gqlify/firebase');
5 | * const admin = require('firebase-admin');
6 | * const cert = require('./cert.json');
7 | */
8 |
9 | /** Firestore required packages
10 | * https://www.cannercms.com/docs/data-source-firestore
11 | * const {FirestoreDataSource} = require('@gqlify/firestore);
12 | * const admin = require('firebase-admin');
13 | * const cert = require('./cert.json');
14 | */
15 |
16 |
17 | exports.common = {
18 | hostname: 'http://localhost:3000',
19 | // cannerSchemaPath?: string;
20 | // cookieKeys?: string[];
21 | // public?: boolean;
22 | // clientId?: string;
23 | // clientSecret?: string;
24 | }
25 |
26 | exports.cms = {
27 | logo: {
28 | src: "https://cdn.canner.io/images/logo/logo-word-white.png",
29 | width: "140px",
30 | height: "50px",
31 | href: "#",
32 | backgroundColor: "#6ba4be"
33 | },
34 | style: {
35 | sidebarTheme: "dark",
36 | navbarTheme: "light",
37 | navbarStyle: {
38 | lineHeight: "50px",
39 | height: "50px"
40 | },
41 | navbarMenuStyle: {
42 | lineHeight: "50px"
43 | },
44 | sidebarMenuStyle: {
45 | height: 'calc(100% - 50px)',
46 | background: '#4c6574'
47 | },
48 | sidebarStyle: {
49 | width: "200px",
50 | },
51 | theme: {
52 | "primary-color": "#f19b90",
53 | "btn-primary-bg": "#f19b90",
54 |
55 | "menu-dark-item-active-bg": "#415663",
56 | "menu-dark-bg": "#415663",
57 | "menu-dark-color": "#eee",
58 |
59 | // common
60 | "border-radius-base": "3px",
61 |
62 | // header
63 | "layout-header-background": "#fff",
64 |
65 | // body
66 | "layout-body-background": "#ecf2f6"
67 | }
68 | },
69 | // find more icons https://ant.design/components/icon/
70 | sidebarMenu: [{
71 | title: "Posts",
72 | pathname: "posts",
73 | icon: "read"
74 | }, {
75 | title: "Categories",
76 | pathname: "categories",
77 | icon: "tag"
78 | }],
79 | // hostname?: string;
80 | // staticsPath?: string;
81 | // clientBundledDir?: string;
82 |
83 | // /**
84 | // * OIDC config
85 | // * If `oidc` is null, all oidc features will be disabled
86 | // */
87 | // oidc?: {
88 | // // issuer
89 | // // via Discovery
90 | // discoveryUrl?: string;
91 | // // manually
92 | // issuer?: string;
93 | // authorizationEndpoint?: string;
94 | // tokenEndpoint?: string;
95 | // userinfoEndpoint?: string;
96 | // jwksUri?: string;
97 |
98 | // // client
99 | // clientId?: string;
100 | // clientSecret?: string;
101 |
102 | // // What attribute of claim should we use as username
103 | // usernameClaim?: string;
104 | // // Additional scopes we ask in authorization
105 | // additionalScopes?: string[];
106 | // // Whether we should force SSO to kill session as well or not during logout process
107 | // forceSsoLogout?: boolean;
108 | // // Customize SSO provider's logout procedure
109 | // ssoLogout?: (ctx: Context) => Promise;
110 | // } | null;
111 |
112 | // /**
113 | // * Fully auth customizable middleware
114 | // */
115 | // beforeRenderCms?: (ctx: Context, next: () => Promise) => Promise;
116 | // authCallback?: (ctx: Context, next: () => Promise) => Promise;
117 | // logout?: (ctx: Context, next: () => Promise) => Promise;
118 |
119 | // /**
120 | // * Cookie
121 | // */
122 | // cookieKeys?: string[];
123 | }
124 |
125 | exports.graphql = {
126 | dataSources: {
127 | // the keys below is correspoing the `name` of `dataSource` property in your schema.
128 | // eg:
129 | // new FirebaseDataSource({
135 | // config: {
136 | // credential: admin.credential.cert(cert),
137 | // databaseURL: `https://${cert.project_id}.firebaseio.com`,
138 | // },
139 | // path: args.key
140 | // }),
141 | // firestore: args => new FirebaseDataSource({
142 | // config: {
143 | // credential: admin.credential.cert(cert),
144 | // databaseURL: `https://${cert.project_id}.firebaseio.com`,
145 | // },
146 | // collection: args.key
147 | // })
148 | }
149 | }
150 |
151 | exports.auth = {
152 | // mountPath?: string;
153 | accounts: [{
154 | username: 'canner',
155 | password: 'canner',
156 | }]
157 | }
158 |
--------------------------------------------------------------------------------