diff --git a/.dockerignore b/.dockerignore index 31445978..e6f1136f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,7 +5,7 @@ /web/public/ /.vscode/ /.idea/ -/.git/objects/ +/.git/ # source files docker-compose.yml @@ -19,3 +19,5 @@ debug debug.test *.prof *.test +/bin/ +remark42 diff --git a/.drone.yml b/.drone.yml index a7cf619a..2e375596 100644 --- a/.drone.yml +++ b/.drone.yml @@ -7,13 +7,16 @@ pipeline: build: image: golang:1.10-alpine commands: + - sleep 5 + - nslookup mongo + - nslookup mongo | grep Address | awk '{print $3}' > backend/.mongo - cd backend/app - go build -v ./... docker_master: image: plugins/docker repo: umputun/remark42 - secrets: [ docker_username, docker_password ] + secrets: [ docker_username, docker_password] build_args: - DRONE=${DRONE} - DRONE_TAG=${DRONE_TAG} @@ -39,6 +42,17 @@ pipeline: when: event: tag + artifacts_tag: + image: plugins/docker + dockerfile: Dockerfile.artifacts + build_args: + - DRONE=${DRONE} + - DRONE_TAG=${DRONE_TAG} + - DRONE_COMMIT=${DRONE_COMMIT} + - GITHUB_TOKEN=${GITHUB_TOKEN} + when: + event: tag + docker_branch: image: plugins/docker repo: umputun/remark42 @@ -79,3 +93,9 @@ pipeline: secrets: [ email_username, email_password ] when: status: [ changed, failure ] + +services: + mongo: + image: mongo:3.6 + command: [ --smallfiles ] + diff --git a/.gitignore b/.gitignore index fba2a845..1ab85900 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ debug.test *.test /rest-client.env.json .DS_Store +.mongo +remark42 +/bin/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 9cb6efc1..01016812 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,9 @@ install: - docker-compose --version script: + - docker run -d --name=mongo mongo:3.6 && sleep 3 + - export MONGO_TEST=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mongo) + - echo "running mongo on $MONGO_TEST" - docker build --build-arg COVERALLS_TOKEN=$COVERALLS_TOKEN --build-arg CI=$CI @@ -16,4 +19,7 @@ script: --build-arg TRAVIS_PULL_REQUEST_SHA=$TRAVIS_PULL_REQUEST_SHA --build-arg TRAVIS_REPO_SLUG=$TRAVIS_REPO_SLUG --build-arg TRAVIS_TAG=$TRAVIS_TAG + --build-arg MONGO_TEST=$MONGO_TEST . + - docker rm -f mongo + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 0c844e33..5006297e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,34 +19,46 @@ ARG DRONE_BRANCH ARG DRONE_PULL_REQUEST ARG SKIP_BACKEND_TEST +ARG MONGO_TEST WORKDIR /go/src/github.com/umputun/remark/backend ADD backend /go/src/github.com/umputun/remark/backend -RUN cd app && \ +# run tests +RUN \ + if [ -f .mongo ] ; then export MONGO_TEST=$(cat .mongo) ; fi && \ + cd app && \ if [ -z "$SKIP_BACKEND_TEST" ] ; then go test ./... ; \ else echo "skip backend test" ; fi +RUN echo "mongo=${MONGO_TEST}" >> /etc/hosts + +# linters RUN if [ -z "$SKIP_BACKEND_TEST" ] ; then \ + if [ -f .mongo ] ; then export MONGO_TEST=$(cat .mongo) ; fi && \ gometalinter --disable-all --deadline=300s --vendor --enable=vet --enable=vetshadow --enable=golint \ - --enable=staticcheck --enable=ineffassign --enable=goconst --enable=errcheck --enable=unconvert \ + --enable=staticcheck --enable=ineffassign --enable=errcheck --enable=unconvert \ --enable=deadcode --enable=gosimple --enable=gas --exclude=test --exclude=mock --exclude=vendor ./... ; \ else echo "skip backend linters" ; fi -# coverage test, submit to coverals if COVERALLS_TOKEN in env -RUN if [ -z "$COVERALLS_TOKEN" ] ; then \ - echo coverall not enabled ; \ - else \ - mkdir -p target && /script/coverage.sh && \ - goveralls -coverprofile=.cover/cover.out -service=travis-ci -repotoken $COVERALLS_TOKEN || echo "coverall failed!"; fi +# coverage report +RUN if [ -z "$SKIP_BACKEND_TEST" ] ; then \ + if [ -f .mongo ] ; then export MONGO_TEST=$(cat .mongo) ; fi && \ + mkdir -p target && /script/coverage.sh ; \ + else echo "skip backend coverage" ; fi -# get revision from git. if DRONE presented use DRONE_* git env to make version +# submit coverage to coverals if COVERALLS_TOKEN in env +RUN if [ -z "$COVERALLS_TOKEN" ] ; then \ + echo "coverall not enabled" ; \ + else goveralls -coverprofile=.cover/cover.out -service=travis-ci -repotoken $COVERALLS_TOKEN || echo "coverall failed!"; fi + +# if DRONE presented use DRONE_* git env to make version RUN \ if [ -z "$DRONE" ] ; then \ echo "runs outside of drone" && version="local"; \ else version=${DRONE_TAG}${DRONE_BRANCH}${DRONE_PULL_REQUEST}-${DRONE_COMMIT:0:7}-$(date +%Y%m%d-%H:%M:%S); fi && \ echo "version=$version" && \ - go build -o remark -ldflags "-X main.revision=${version} -s -w" ./app + go build -o remark42 -ldflags "-X main.revision=${version} -s -w" ./app FROM node:10.6-alpine as build-frontend-deps @@ -56,15 +68,16 @@ ARG CI RUN apk add --no-cache --update git ADD web/package.json /srv/web/package.json ADD web/package-lock.json /srv/web/package-lock.json -RUN cd /srv/web && npm ci +RUN cd /srv/web && CI=true npm ci FROM node:10.6-alpine as build-frontend ARG CI ARG SKIP_FRONTEND_TEST +ARG NODE_ENV=production -ADD web /srv/web COPY --from=build-frontend-deps /srv/web/node_modules /srv/web/node_modules +ADD web /srv/web RUN cd /srv/web && \ if [ -z "$SKIP_FRONTEND_TEST" ] ; then npx run-p lint test build ; \ else echo "skip frontend tests and lint" ; npm run build ; fi && \ @@ -75,16 +88,19 @@ FROM umputun/baseimage:app-latest WORKDIR /srv -ADD backend/scripts/*.sh /srv/ -ADD start.sh /srv/start.sh -RUN chmod +x /srv/*.sh +ADD entrypoint.sh /entrypoint.sh +ADD backend/scripts/backup.sh /usr/local/bin/backup +ADD backend/scripts/restore.sh /usr/local/bin/restore +ADD backend/scripts/import.sh /usr/local/bin/import +RUN chmod +x /entrypoint.sh /usr/local/bin/backup /usr/local/bin/restore /usr/local/bin/import -COPY --from=build-backend /go/src/github.com/umputun/remark/backend/remark /srv/ +COPY --from=build-backend /go/src/github.com/umputun/remark/backend/remark42 /srv/remark42 COPY --from=build-frontend /srv/web/public/ /srv/web RUN chown -R app:app /srv +RUN ln -s /srv/remark42 /usr/bin/remark42 EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=3s CMD curl --fail http://localhost:8080/ping || exit 1 -CMD ["/srv/start.sh"] -ENTRYPOINT ["/init.sh"] +CMD ["server"] +ENTRYPOINT ["/entrypoint.sh"] diff --git a/Dockerfile.artifacts b/Dockerfile.artifacts new file mode 100644 index 00000000..ee1254f8 --- /dev/null +++ b/Dockerfile.artifacts @@ -0,0 +1,91 @@ +FROM node:10.6-alpine as build-frontend-deps + +ARG CI +ENV SKIP_FRONTEND_TEST=true + +RUN apk add --no-cache --update git +ADD web/package.json /srv/web/package.json +ADD web/package-lock.json /srv/web/package-lock.json +RUN cd /srv/web && CI=true npm ci + +FROM node:10.6-alpine as build-frontend + +ARG CI +ARG NODE_ENV=production +ENV SKIP_FRONTEND_TEST=true + +COPY --from=build-frontend-deps /srv/web/node_modules /srv/web/node_modules +ADD web /srv/web +RUN cd /srv/web && \ + npm run build && \ + rm -rf ./node_modules + + +FROM umputun/baseimage:buildgo-latest as build-backend + +ARG GITHUB_TOKEN +ENV SKIP_BACKEND_TEST=true + +WORKDIR /go/src/github.com/umputun/remark/backend +ADD backend /go/src/github.com/umputun/remark/backend +ADD README.md /go/src/github.com/umputun/remark/ +ADD LICENSE /go/src/github.com/umputun/remark/ +COPY --from=build-frontend /srv/web/public/ web + +RUN \ + export WEB_ROOT=/go/src/github.com/umputun/remark/backend/web && \ + sed -i "s|https://demo.remark42.com|http://127.0.0.1:8080|g" ${WEB_ROOT}/*.js && \ + sed -i "/REMOVE-START/,/REMOVE-END/d" ${WEB_ROOT}/iframe.html && \ + go get -v github.com/rakyll/statik && \ + statik --src=${WEB_ROOT} --dest=/go/src/github.com/umputun/remark/backend/app/rest -p api -f && \ + ls -la /go/src/github.com/umputun/remark/backend/app/rest/api/statik.go && \ + ls -la /go/src/github.com/umputun/remark/backend/web/ + +# if DRONE presented use DRONE_* git env to make version +RUN \ + if [ -z "$DRONE" ] ; then \ + echo "runs outside of drone" && version="local"; \ + else version=${DRONE_TAG}${DRONE_BRANCH}${DRONE_PULL_REQUEST}-${DRONE_COMMIT:0:7}-$(date +%Y%m%d-%H:%M:%S); fi && \ + echo "version=$version" && \ + GOOS=linux GOARCH=amd64 go build -o remark42.linux-amd64 -ldflags "-X main.revision=${version} -s -w" ./app && \ + GOOS=linux GOARCH=386 go build -o remark42.linux-386 -ldflags "-X main.revision=${version} -s -w" ./app && \ + GOOS=linux GOARCH=arm64 go build -o remark42.linux-arm64 -ldflags "-X main.revision=${version} -s -w" ./app && \ + GOOS=windows GOARCH=amd64 go build -o remark42.windows-amd64.exe -ldflags "-X main.revision=${version} -s -w" ./app && \ + GOOS=darwin GOARCH=amd64 go build -o remark42.darwin-amd64 -ldflags "-X main.revision=${version} -s -w" ./app + +RUN \ + if [ -z "$DRONE_TAG" ] ; then \ + echo "runs outside of drone" && tag=""; \ + else tag=_${DRONE_TAG}; fi && \ + apk add --no-cache --update zip && \ + tar cvzf remark42${tag}.linux-amd64.tar.gz remark42.linux-amd64 ../LICENSE ../README.md && \ + tar cvzf remark42${tag}.linux-386.tar.gz remark42.linux-386 ../LICENSE ../README.md && \ + tar cvzf remark42${tag}.linux-arm64.tar.gz remark42.linux-arm64 ../LICENSE ../README.md && \ + tar cvzf remark42${tag}.darwin-amd64.tar.gz remark42.darwin-amd64 ../LICENSE ../README.md && \ + zip remark42${tag}.windows-amd64.zip remark42.windows-amd64.exe ../LICENSE ../README.md + +# upload to github +RUN \ + if [ -z "$DRONE_TAG" ] ; then \ + echo "skip upload to github" ; \ + else \ + curl -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/gzip" --data-binary @remark42_${DRONE_TAG}.linux-amd64.tar.gz \ + "https://uploads.github.com/repos/umputun/remark/releases/${DRONE_TAG}/assets?name=remark_${DRONE_TAG}.linux-amd64.tar.gz" && \ + curl -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/gzip" --data-binary @remark42_${DRONE_TAG}.linux-386.tar.gz \ + "https://uploads.github.com/repos/umputun/remark/releases/${DRONE_TAG}/assets?name=remark_${DRONE_TAG}.linux-386.tar.gz" && \ + curl -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/gzip" --data-binary @remark42_${DRONE_TAG}.linux-arm64.tar.gz \ + "https://uploads.github.com/repos/umputun/remark/releases/${DRONE_TAG}/assets?name=remark_${DRONE_TAG}.linux-arm64.tar.gz" && \ + curl -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/gzip" --data-binary @remark42_${DRONE_TAG}.darwin-amd64.tar.gz \ + "https://uploads.github.com/repos/umputun/remark/releases/${DRONE_TAG}/assets?name=remark_${DRONE_TAG}.darwin-amd64.tar.gz" && \ + curl -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/zip" --data-binary @remark42_${DRONE_TAG}.windows-amd64.zip \ + "https://uploads.github.com/repos/umputun/remark/releases/${DRONE_TAG}/assets?name=remark_${DRONE_TAG}.windows-amd64.zip"; fi + +FROM alpine +COPY --from=build-backend /go/src/github.com/umputun/remark/backend/remark42.* /artifacts/ +RUN ls -la /artifacts/* +CMD ["sleep", "100"] diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..fa3b1872 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +OS=linux +ARCH=amd64 + +bin: + docker build -f Dockerfile.artifacts -t remark42.bin . + - @docker rm -f remark42.bin 2>/dev/null || exit 0 + docker run -d --name=remark42.bin remark42.bin + docker cp remark42.bin:/artifacts/remark42.$(OS)-$(ARCH) remark42 + docker rm -f remark42.bin + +docker: + docker build -t umputun/remark42 --build-arg SKIP_FRONTEND_TEST=true --build-arg SKIP_BACKEND_TEST=true . + +deploy: + docker build -f Dockerfile.artifacts -t remark42.bin . + - @docker rm -f remark42.bin 2>/dev/null || exit 0 + - @mkdir -p bin + docker run -d --name=remark42.bin remark42.bin + docker cp remark42.bin:/artifacts/remark42.linux-amd64.tar.gz bin/remark42.linux-amd64.tar.gz + docker cp remark42.bin:/artifacts/remark42.linux-386.tar.gz bin/remark42.linux-386.tar.gz + docker cp remark42.bin:/artifacts/remark42.linux-arm64.tar.gz bin/remark42.linux-arm64.tar.gz + docker cp remark42.bin:/artifacts/remark42.darwin-amd64.tar.gz bin/remark42.darwin-amd64.tar.gz + docker cp remark42.bin:/artifacts/remark42.windows-amd64.zip bin/remark42.windows-amd64.zip + docker rm -f remark42.bin + +.PHONY: bin \ No newline at end of file diff --git a/README.md b/README.md index 14831503..8a7d17a9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Remark42 is a self-hosted, lightweight, and simple (yet functional) comment engi * Social login via Google, Facebook, Github and Yandex * Multi-level nested comments with both tree and plain presentations -* Import from disqus +* Import from disqus and wordpress * Markdown support * Moderator can remove comments and block users * Voting, pinning and verification system @@ -14,57 +14,113 @@ Remark42 is a self-hosted, lightweight, and simple (yet functional) comment engi * Export data to json with automatic backups * No external databases, everything embedded in a single data file * Fully dockerized and can be deployed in a single command +* Self-contained executable can be deployed directly to Linux, Windows and MacOS * Clean, lightweight and fully customizable UI * Multi-site mode from a single instance * Integration with automatic ssl via [nginx-le](https://github.com/umputun/nginx-le) * [Privacy focused](#privacy) +# + + - [Install](#install) + - [Backend](#backend) + - [With Docker](#with-docker) + - [Without docker](#without-docker) + - [Parameters](#parameters) + - [Required parameters](#required-parameters) + - [Register oauth2 providers](#register-oauth2-providers) + - [Google Auth Provider](#google-auth-provider) + - [GitHub Auth Provider](#github-auth-provider) + - [Facebook Auth Provider](#facebook-auth-provider) + - [Yandex Auth Provider](#yandex-auth-provider) + - [Initial import from Disqus](#initial-import-from-disqus) + - [Initial import from WordPress](#initial-import-from-wordpress) + - [Backup and restore](#backup-and-restore) + - [Automatic backups](#automatic-backups) + - [Manual backup](#manual-backup) + - [Restore from backup](#restore-from-backup) + - [Backup format](#backup-format) + - [Admin users](#admin-users) + - [Setup on your website](#setup-on-your-website) + - [Comments](#comments) + - [Last comments](#last-comments) + - [Counter](#counter) + - [Build from the source](#build-from-the-source) + - [Development](#development) + - [Backend development](#backend-development) + - [Frontend development](#frontend-development) + - [Build](#build) + - [Devserver](#devserver) + - [API](#api) + - [Authorization](#authorization) + - [Commenting](#commenting) + - [RSS feeds](#rss-feeds) + - [Admin](#admin) + - [Privacy](#privacy) + - [Technical details](#technical-details) + + ## Install ### Backend +#### With Docker + +_this is the recommended way to run remark42_ + * copy provided `docker-compose.yml` and customize for your needs -* prepare user id for container `` export USER=`id -u $USER` `` * make sure you **don't keep** `DEV_PASSWD=something...` for any non-development deployments -* pull prepared images from docker hub and start - `docker-compose pull && docker-compose up -d` -* alternatively compile from sources - `docker-compose build && docker-compose up -d` +* pull prepared images from the docker hub and start - `docker-compose pull && docker-compose up -d` +* alternatively compile from the sources - `docker-compose build && docker-compose up -d` + +#### Without docker + +* download archive for [stable release](https://github.com/umputun/remark/releases) or [development version](https://remark42.com/downloads) +* unpack with `gunzip` (linux, mac os) or with `zip` (windows) +* run as `remark42.{os}-{arch} server {parameters...}`, i.e. `remark42.linux-amd64 server --secret=12345 --url=http://127.0.0.1:8080` +* alternatively compile from the sources - `make OS=[linux|darwin|windows] ARCH=[amd64,386,arm64,arm32]` #### Parameters -| Command line | Environment | Default | Description | -| ------------------ | ------------------ | --------------------- | ---------------------------------------------- | -| url | REMARK_URL | | url to remark42 server, _required_ | -| secret | SECRET | | secret key, _required_ | -| store.bolt.path | STORE_BOLT_PATH | `./var` | path to data directory | -| store.bolt.timeout | STORE_BOLT_TIMEOUT | `30s` | boltdb access timeout | -| site | SITE | `remark` | site name(s), _multi_ | -| admin | ADMIN | | admin names (list of user ids), _multi_ | -| admin-email | ADMIN_EMAIL | `admin@${REMARK_URL}` | admin email | -| backup | BACKUP_PATH | `./var/backup` | backups location | -| max-back | MAX_BACKUP_FILES | `10` | max backup files to keep | -| cache.max.items | CACHE_MAX_ITEMS | `1000` | max number of cached items, `0` - unlimited | -| cache.max.value | CACHE_MAX_VALUE | `65536` | max size of cached value, `0` - unlimited | -| cache.max.size | CACHE_MAX_SIZE | `50000000` | max size of all cached values, `0` - unlimited | -| avatar.path | AVATAR_FS_PATH | `./var/avatars` | avatars location | -| avatar.rsz-lmt | AVATAR_RSZ_LMT | 0 | max image size for resizing avatars on save | -| max-comment | MAX_COMMENT_SIZE | 2048 | comment's size limit | -| auth.ttl.jwt | AUTH_TTL_JWT | 5m | jwt TTL | -| auth.ttl.cookie | AUTH_TTL_COOKIE | 200h | cookie TTL | -| auth.google.cid | AUTH_GOOGLE_CID | | Google OAuth client ID | -| auth.google.csec | AUTH_GOOGLE_CSEC | | Google OAuth client secret | -| auth.facebook.cid | AUTH_FACEBOOK_CID | | Facebook OAuth client ID | -| auth.facebook.csec | AUTH_FACEBOOK_CSEC | | Facebook OAuth client secret | -| auth.github.cid | AUTH_GITHUB_CID | | Github OAuth client ID | -| auth.github.csec | AUTH_GITHUB_CSEC | | Github OAuth client secret | -| auth.yandex.cid | AUTH_YANDEX_CID | | Yandex OAuth client ID | -| auth.yandex.csec | AUTH_YANDEX_CSEC | | Yandex OAuth client secret | -| auth.dev | AUTH_DEV | false | local oauth2 server, development mode only | -| low-score | LOW_SCORE | `-5` | low score threshold | -| critical-score | CRITICAL_SCORE | `-10` | critical score threshold | -| edit-time | EDIT_TIME | `5m` | edit window | -| img-proxy | IMG_PROXY | `false` | enable http->https proxy for images | -| dbg | DEBUG | `false` | debug mode | -| dev-passwd | DEV_PASSWD | | password for `dev` user | +| Command line | Environment | Default | Description | +| ------------------ | ------------------ | --------------------- | ------------------------------------------------ | +| url | REMARK_URL | | url to remark42 server, _required_ | +| secret | SECRET | | secret key, _required_ | +| site | SITE | `remark` | site name(s), _multi_ | +| store.type | STORE_TYPE | `bolt` | type of storage, `bolt` or `mongo` | +| store.bolt.path | STORE_BOLT_PATH | `./var` | path to data directory | +| store.bolt.timeout | STORE_BOLT_TIMEOUT | `30s` | boltdb access timeout | +| mongo.url | MONGO_URL | | mongo url for all stores using mongodb | +| mongo.db | MONGO_DB | | mongo database | +| admin.shared.id | ADMIN_SHARED_ID | | admin names (list of user ids), _multi_ | +| admin.shared.email | ADMIN_SHARED_EMAIL | `admin@${REMARK_URL}` | admin email | +| backup | BACKUP_PATH | `./var/backup` | backups location | +| max-back | MAX_BACKUP_FILES | `10` | max backup files to keep | +| cache.max.items | CACHE_MAX_ITEMS | `1000` | max number of cached items, `0` - unlimited | +| cache.max.value | CACHE_MAX_VALUE | `65536` | max size of cached value, `0` - unlimited | +| cache.max.size | CACHE_MAX_SIZE | `50000000` | max size of all cached values, `0` - unlimited | +| avatar.type | AVATAR_TYPE | `fs` | type of avatar storage, `fs`, 'bolt`, or `mongo` | +| avatar.fs.path | AVATAR_FS_PATH | `./var/avatars` | avatars location for `fs` store | +| avatar.bolt.file | AVATAR_BOLT_FILE | `./var/avatars.db` | file name for `bolt` store | +| avatar.rsz-lmt | AVATAR_RSZ_LMT | 0 | max image size for resizing avatars on save | +| auth.ttl.jwt | AUTH_TTL_JWT | 5m | jwt TTL | +| auth.ttl.cookie | AUTH_TTL_COOKIE | 200h | cookie TTL | +| auth.google.cid | AUTH_GOOGLE_CID | | Google OAuth client ID | +| auth.google.csec | AUTH_GOOGLE_CSEC | | Google OAuth client secret | +| auth.facebook.cid | AUTH_FACEBOOK_CID | | Facebook OAuth client ID | +| auth.facebook.csec | AUTH_FACEBOOK_CSEC | | Facebook OAuth client secret | +| auth.github.cid | AUTH_GITHUB_CID | | Github OAuth client ID | +| auth.github.csec | AUTH_GITHUB_CSEC | | Github OAuth client secret | +| auth.yandex.cid | AUTH_YANDEX_CID | | Yandex OAuth client ID | +| auth.yandex.csec | AUTH_YANDEX_CSEC | | Yandex OAuth client secret | +| auth.dev | AUTH_DEV | false | local oauth2 server, development mode only | +| max-comment | MAX_COMMENT_SIZE | 2048 | comment's size limit | +| low-score | LOW_SCORE | `-5` | low score threshold | +| critical-score | CRITICAL_SCORE | `-10` | critical score threshold | +| edit-time | EDIT_TIME | `5m` | edit window | +| img-proxy | IMG_PROXY | `false` | enable http->https proxy for images | +| dbg | DEBUG | `false` | debug mode | +| dev-passwd | DEV_PASSWD | | password for `dev` user | * command line parameters are long form `--=value`, i.e. `--site=https://demo.remark42.com` * _multi_ parameters separated by `,` in the environment or repeated with command line key, like `--site=s1 --site=s2 ...` @@ -75,8 +131,8 @@ Remark42 is a self-hosted, lightweight, and simple (yet functional) comment engi Most of the parameters have sane defaults and don't require customization. There are only a few parameters user has to define: 1. `SECRET` - secret key, can be any long and hard-to-guess string. -1. `REMARK_URL` - url pointing to your remark42 server, i.e. `https://demo.reamark42.com` -2. At least one pair of `AUTH__CID` and `AUTH__CSEC` defining oauth2 provider(s) +2. `REMARK_URL` - url pointing to your remark42 server, i.e. `https://demo.reamark42.com` +3. At least one pair of `AUTH__CID` and `AUTH__CSEC` defining oauth2 provider(s) The minimal `docker-compose.yml` has to include all required parameters: @@ -90,10 +146,10 @@ services: container_name: "remark42" environment: - REMARK_URL=https://demo.remark42.com # url pointing to your remark42 server + - SITE=YOUR_SITE_ID # site ID, same as used for `site_id`, see "Setup on your website" - SECRET=abcd-123456-xyz-$%^& # secret key - AUTH_GITHUB_CID=12345667890 # oauth2 client ID - AUTH_GITHUB_CSEC=abcdefg12345678 # oauth2 client secret - - USER=1001 # UID on the host machine, i.e `id -u` volumes: - ./var:/srv/var # persistent volume to store all remark42 data ``` @@ -154,7 +210,13 @@ For more details refer to [Yandex OAuth](https://tech.yandex.com/oauth/doc/dg/co 1. Disqus provides an export of all comments on your site in a g-zipped file. This is found in your Moderation panel at Disqus Admin > Setup > Export. The export will be sent into a queue and then emailed to the address associated with your account once it's ready. Direct link to export will be something like `https://.disqus.com/admin/discussions/export/`. See [importing-exporting](https://help.disqus.com/customer/portal/articles/1104797-importing-exporting) for more details. 2. Move this file to your remark42 host within `./var` and unzip, i.e. `gunzip .xml.gz`. -3. Run import command - `docker-compose exec remark42 /srv/import-disqus.sh .xml ` +3. Run import command - `docker exec -it remark42 import -p disqus -f {disqus-export-name}.xml -s {your site id}` + +#### Initial import from WordPress + +1. Install WordPress [plugin](https://wordpress.org/plugins/wp-exporter/) to export comments and follow it instructions. The plugin should produce a xml-based file with site content including comments. +2. Move this file to your remark42 host within `./var` +3. Run import command - `docker exec -it remark42 import -p wordpress -f {wordpress-export-name}.xml -s {your site id}` #### Backup and restore @@ -163,20 +225,19 @@ Remark42 by default makes daily backup files under `${BACKUP_PATH}` (default `./ For safety and security reasons restore functionality not exposed outside of your server by default. The recommended way to restore from the backup is to use provided `scripts/restore-backup.sh`. It can run inside the container: -`docker-compose exec remark42 /srv/restore-backup.sh {backup-filename.gz} {your site id}` - -##### Schema migration - -One special case for backup/restore is schema migration. Some versions or remark42 may extend or change the schema -and for such upgrades migration required. Provided migration script `scripts/migrate-data.sh` makes a fresh backup and then loads it back to your remark42 instance. - -`docker-compose exec remark42 /srv/migrate-data.sh {your site id}` +`docker exec -it remark42 restore -f {backup-filename.gz} -s {your site id}` ##### Manual backup -In addition to automatic backups user can make a backup manually. This command makes `userbackup-{site id}-{timestamp}.gz` +In addition to automatic backups user can make a backup manually. This command makes `userbackup-{site id}-{timestamp}.gz` by default. -`docker-compose exec remark42 /srv/create-backup.sh {your site id}` +`docker exec -it remark42 backup -s {your site id}` + +##### Restore from backup + +Restore will clean all comments first and then will processed with complete import from a given file. + +`docker exec -it remark42 restore -f {backup file name} -s {your site id}` ##### Backup format @@ -195,50 +256,9 @@ Admins/moderators should be defined in `docker-compose.yml` as a list of user ID To get user id just login and click on your username or any other user you want to promote to admins. It will expand login info and show full user ID. +### Setup on your website -### Frontend - -Frontend part is building automatically along with backend if you use `docker-compose`. - -For manual building: - -* install [Node.js 8](https://nodejs.org/en/) or higher; -* install [NPM 6.1.0](https://www.npmjs.com/package/npm) or higher; -* run `npm install` inside `./web`; -* run `npm run build` there; -* result files will be saved in `./web/public`. - -For development mode use `npm start` instead of `npm run build`. -In this case `webpack` will serve files using `webpack-dev-server` on `localhost:8080`. - -URLs for development: - -* `localhost:8080` — page with embedded script from `REMARK_URL` (default: `https://demo.remark42.com`); -* `localhost:8080/dev.html` — page with embedded script from local folder; -* `localhost:8080/last-comments.html` — page with embedded script for last comments; -* `localhost:8080/counter.html` — page with embedded script for counter with examples. - -#### Testing - -Also you can use fully functional local version to develop and test both frontend & backend. - -To bring it up run: - -```bash -docker-compose -f compose-dev-frontend.yml build -docker-compose -f compose-dev-frontend.yml up -``` - -It starts Remark42 on `localhost:8080` -and adds local OAuth2 provider “Dev”. To access UI demo page go to `localhost:8080/web`. - -That `compose-dev.yml` (you can find it in the root of the project) also defines if default logged user admin or not. -By default, it will be the admin, and to switch it to regular user comment or remove `-ADMIN=dev_user` there. You can also select -any other user name from the login dialog. - -#### Usage - -##### Comments +#### Comments It's a main widget which renders list of comments. @@ -268,7 +288,7 @@ And then add this node in the place where you want to see Remark42 widget: After that widget will be rendered inside this node. -##### Last comments +#### Last comments It's a widget which renders list of last comments from your site. @@ -296,7 +316,7 @@ And then add this node in the place where you want to see last comments widget: `data-max` sets the max amount of comments (default: `15`). -##### Counter +#### Counter It's a widget which renders a number of comments for the specified page. @@ -305,7 +325,7 @@ Add this snippet to the bottom of web page: ```html + + diff --git a/web/dev.ejs b/web/dev.ejs deleted file mode 100644 index 77ff7d5f..00000000 --- a/web/dev.ejs +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - remark42 - - - - -
-
-
- - - - diff --git a/web/iframe.html b/web/iframe.html index bc7d0933..e9dc515c 100644 --- a/web/iframe.html +++ b/web/iframe.html @@ -1,10 +1,15 @@ - + remark42 + @@ -70,6 +79,13 @@