Remark42

Command-Line Interface parameters

Required parameters

Most of the parameters have sane defaults and don't require customization. There are only a few parameters the user has to define:

  1. SECRET - secret key, can be any long and hard-to-guess string
  2. REMARK_URL - URL pointing to your Remark42 server, i.e., https://demo.remark42.com
  3. At least one OAuth2 provider, either via AUTH_<PROVIDER>_CID + AUTH_<PROVIDER>_CSEC or via AUTH_CUSTOM_*

The minimal docker-compose.yml has to include all required parameters:

version: "2"

services:
  remark42:
    image: ghcr.io/umputun/remark42:latest
    restart: always
    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_ANON=true # enable anonymous commenting
      - AUTH_GITHUB_CID=12345667890 # OAuth2 client ID
      - AUTH_GITHUB_CSEC=abcdefg12345678 # OAuth2 client secret
    volumes:
      - ./var:/srv/var # persistent volume to store all Remark42 data

Complete parameters list

Command lineEnvironmentDefaultDescription
urlREMARK_URLURL to Remark42 server, required
secretSECRETthe shared secret key used to sign JWT, should be a random, long, hard-to-guess string, required
siteSITEremarksite name(s), multi
store.typeSTORE_TYPEbolttype of storage, bolt or rpc
store.bolt.pathSTORE_BOLT_PATH./varparent directory for the bolt files
store.bolt.timeoutSTORE_BOLT_TIMEOUT30sboltdb access timeout
store.rpc.apiSTORE_RPC_APIrpc extension api url
store.rpc.timeoutSTORE_RPC_TIMEOUThttp timeout (default: 5s)
store.rpc.auth_userSTORE_RPC_AUTH_USERbasic auth user name
store.rpc.auth_passwdSTORE_RPC_AUTH_PASSWDbasic auth user password
admin.typeADMIN_TYPEsharedtype of admin store, shared or rpc
admin.rpc.apiADMIN_RPC_APIrpc extension api url
admin.rpc.timeoutADMIN_RPC_TIMEOUThttp timeout (default: 5s)
admin.rpc.auth_userADMIN_RPC_AUTH_USERbasic auth user name
admin.rpc.auth_passwdADMIN_RPC_AUTH_PASSWDbasic auth user password
admin.rpc.secret_per_siteADMIN_RPC_SECRET_PER_SITEenable JWT secret retrieval per aud, which is site_id in this case
admin.shared.idADMIN_SHARED_IDadmin IDs (list of user IDs), multi
admin.shared.emailADMIN_SHARED_EMAILadmin@${REMARK_URL}admin emails, multi
backupBACKUP_PATH./var/backupbackups location
max-backMAX_BACKUP_FILES10max backup files to keep
cache.typeCACHE_TYPEmemtype of cache, redis_pub_sub or mem or none
cache.redis_addrCACHE_REDIS_ADDR127.0.0.1:6379address of Redis PubSub instance, turn redis_pub_sub cache on for distributed cache
cache.max.itemsCACHE_MAX_ITEMS1000max number of cached items, 0 - unlimited
cache.max.valueCACHE_MAX_VALUE65536max size of the cached value, 0 - unlimited
cache.max.sizeCACHE_MAX_SIZE50000000max size of all cached values, 0 - unlimited
avatar.typeAVATAR_TYPEfstype of avatar storage, fs, bolt, or uri
avatar.fs.pathAVATAR_FS_PATH./var/avatarsavatars location for fs store
avatar.bolt.fileAVATAR_BOLT_FILE./var/avatars.dbavatars bolt file location
avatar.uriAVATAR_URI./var/avatarsavatars store URI
avatar.rsz-lmtAVATAR_RESIZE0 (disabled)max image size for resizing avatars on save
image.typeIMAGE_TYPEfstype of image storage, fs, bolt or rpc
image.fs.pathIMAGE_FS_PATH./var/picturespermanent location of images
image.fs.stagingIMAGE_FS_STAGING./var/pictures.stagingstaging location of images
image.fs.partitionsIMAGE_FS_PARTITIONS100number of image partitions
image.bolt.fileIMAGE_BOLT_FILE/var/pictures.dbimages bolt file location
image.rpc.apiIMAGE_RPC_APIrpc extension api url
image.rpc.timeoutIMAGE_RPC_TIMEOUThttp timeout (default: 5s)
image.rpc.auth_userIMAGE_RPC_AUTH_USERbasic auth user name
image.rpc.auth_passwdIMAGE_RPC_AUTH_PASSWDbasic auth user password
image.max-sizeIMAGE_MAX_SIZE5000000max size of image file
image.resize-widthIMAGE_RESIZE_WIDTH2400width of a resized image
image.resize-heightIMAGE_RESIZE_HEIGHT900height of a resized image
auth.ttl.jwtAUTH_TTL_JWT5mJWT TTL
auth.ttl.cookieAUTH_TTL_COOKIE200hcookie TTL
auth.send-jwt-headerAUTH_SEND_JWT_HEADERfalsesend JWT as a header instead of a server-set cookie; with this enabled, frontend stores the JWT in a client-side cookie. See security considerations.
auth.same-siteAUTH_SAME_SITEdefaultset same site policy for cookies (default, none, lax or strict)
auth.apple.cidAUTH_APPLE_CIDApple client ID (App ID or Services ID)
auth.apple.tidAUTH_APPLE_TIDApple service ID
auth.apple.kidAUTH_APPLE_KIDApple Private key ID
auth.apple.private-key-filepathAUTH_APPLE_PRIVATE_KEY_FILEPATH/srv/var/apple.p8Apple Private key file location
auth.google.cidAUTH_GOOGLE_CIDGoogle OAuth client ID
auth.google.csecAUTH_GOOGLE_CSECGoogle OAuth client secret
auth.facebook.cidAUTH_FACEBOOK_CIDFacebook OAuth client ID
auth.facebook.csecAUTH_FACEBOOK_CSECFacebook OAuth client secret
auth.microsoft.cidAUTH_MICROSOFT_CIDMicrosoft OAuth client ID
auth.microsoft.csecAUTH_MICROSOFT_CSECMicrosoft OAuth client secret
auth.microsoft.tenantAUTH_MICROSOFT_TENANTcommonAzure AD tenant ID, domain, or "common"
auth.github.cidAUTH_GITHUB_CIDGitHub OAuth client ID
auth.github.csecAUTH_GITHUB_CSECGitHub OAuth client secret
auth.patreon.cidAUTH_PATREON_CIDPatreon OAuth Client ID
auth.patreon.csecAUTH_PATREON_CSECPatreon OAuth Client Secret
auth.discord.cidAUTH_DISCORD_CIDDiscord OAuth Client ID
auth.discord.csecAUTH_DISCORD_CSECDiscord OAuth Client Secret
auth.custom.nameAUTH_CUSTOM_NAMEcustom OAuth provider name (used in /auth/<name>/...)
auth.custom.cidAUTH_CUSTOM_CIDcustom OAuth client ID
auth.custom.csecAUTH_CUSTOM_CSECcustom OAuth client secret
auth.custom.auth-urlAUTH_CUSTOM_AUTH_URLcustom OAuth authorization endpoint
auth.custom.token-urlAUTH_CUSTOM_TOKEN_URLcustom OAuth token endpoint
auth.custom.info-urlAUTH_CUSTOM_INFO_URLcustom OAuth user info endpoint
auth.custom.scopesAUTH_CUSTOM_SCOPESnonecustom OAuth scopes, comma-separated
auth.custom.id-fieldAUTH_CUSTOM_ID_FIELDsubuser info field used as unique id
auth.custom.name-fieldAUTH_CUSTOM_NAME_FIELDnameuser info field used as display name
auth.custom.picture-fieldAUTH_CUSTOM_PICTURE_FIELDpictureuser info field used as avatar URL
auth.custom.email-fieldAUTH_CUSTOM_EMAIL_FIELDemailuser info field used as email

Custom OAuth2 integration currently supports only one custom provider at a time, and AUTH_CUSTOM_NAME must match ^[a-z0-9][a-z0-9_-]*$.

| auth.telegram | AUTH_TELEGRAM | false | Enable Telegram auth (telegram.token must be present) |
| 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 |
| auth.anon | AUTH_ANON | false | enable anonymous login |
| auth.email.enable | AUTH_EMAIL_ENABLE | false | enable auth via email |
| auth.email.from | AUTH_EMAIL_FROM | | email from (e.g. john.doe@example.com or "John Doe"<john.doe@example.com>) |
| auth.email.subj | AUTH_EMAIL_SUBJ | remark42 confirmation | email subject |
| auth.email.content-type | AUTH_EMAIL_CONTENT_TYPE | text/html | email content type |
| notify.users | NOTIFY_USERS | none | type of user notifications (telegram, email), multi |
| notify.admins | NOTIFY_ADMINS | none | type of admin notifications (telegram, slack, webhook and/or email), multi |
| notify.queue | NOTIFY_QUEUE | 100 | size of notification queue |
| notify.telegram.chan | NOTIFY_TELEGRAM_CHAN | | the ID of telegram channel for admin notifications |
| notify.slack.token | NOTIFY_SLACK_TOKEN | | Slack token |
| notify.slack.chan | NOTIFY_SLACK_CHAN | general | Slack channel for admin notifications |
| notify.webhook.url | NOTIFY_WEBHOOK_URL | | Webhook notification URL for admin notifications |
| notify.webhook.template | NOTIFY_WEBHOOK_TEMPLATE | {"text": {{.Text | escapeJSONString}}} | Webhook payload template |
| notify.webhook.headers | NOTIFY_WEBHOOK_HEADERS | | HTTP header in format Header1:Value1,Header2:Value2,... |
| notify.webhook.timeout | NOTIFY_WEBHOOK_TIMEOUT | 5s | Webhook connection timeout |
| notify.email.from_address | NOTIFY_EMAIL_FROM | | from email address (e.g. john.doe@example.com or "John Doe"<john.doe@example.com>) |
| notify.email.verification_subj | NOTIFY_EMAIL_VERIFICATION_SUBJ | Email verification | verification message subject |
| telegram.token | TELEGRAM_TOKEN | | Telegram token (used for auth and Telegram notifications) |
| telegram.timeout | TELEGRAM_TIMEOUT | 5s | Telegram connection timeout |
| smtp.host | SMTP_HOST | | SMTP host |
| smtp.port | SMTP_PORT | | SMTP port |
| smtp.username | SMTP_USERNAME | | SMTP user name |
| smtp.password | SMTP_PASSWORD | | SMTP password |
| smtp.login_auth | SMTP_LOGIN_AUTH | false | enable LOGIN auth instead of PLAIN | | smtp.tls | SMTP_TLS |false| enable TLS for SMTP | | smtp.starttls | SMTP_STARTTLS |false| enable StartTLS for SMTP | | smtp.insecure_skip_verify | SMTP_INSECURE_SKIP_VERIFY |false| skip certificate verification for SMTP | | smtp.timeout | SMTP_TIMEOUT |10s| SMTP TCP connection timeout | | ssl.type | SSL_TYPE | none |none-HTTP,static-HTTPS,auto-HTTPS + le | | ssl.port | SSL_PORT |8443| port for HTTPS server | | ssl.cert | SSL_CERT | | path to the cert.pem file | | ssl.key | SSL_KEY | | path to the key.pem file | | ssl.acme-location | SSL_ACME_LOCATION |./var/acme| dir where obtained le-certs will be stored | | ssl.acme-email | SSL_ACME_EMAIL | | admin email for receiving notifications from LE | | max-comment | MAX_COMMENT_SIZE |2048| comment's size limit | | min-comment | MIN_COMMENT_SIZE |0| comment's minimal size limit,0- unlimited | | max-votes | MAX_VOTES |-1| votes limit per comment,-1- unlimited | | votes-ip | VOTES_IP |false| restrict votes from the same IP | | anon-vote | ANON_VOTE |false| allow voting for anonymous users, require VOTES_IP to be enabled as well | | votes-ip-time | VOTES_IP_TIME |5m| same IP vote restriction time,0s- unlimited | | low-score | LOW_SCORE |-5| low score threshold | | critical-score | CRITICAL_SCORE |-10| critical score threshold | | positive-score | POSITIVE_SCORE |false| restricts comment's score to be only positive | | restricted-words | RESTRICTED_WORDS | | words banned in comments (can use*), _multi_ | | restricted-names | RESTRICTED_NAMES | | names prohibited to use by the user, _multi_ | | edit-time | EDIT_TIME |5m| edit window; set to0to disable comment editing and staged image cleanup | | admin-edit | ADMIN_EDIT |false| unlimited edit for admins | | read-age | READONLY_AGE | | read-only age of comments, days | | image-proxy.http2https | IMAGE_PROXY_HTTP2HTTPS |false| enable HTTP->HTTPS proxy for images | | image-proxy.cache-external | IMAGE_PROXY_CACHE_EXTERNAL |false| enable caching external images to current image storage | | emoji | EMOJI |false| enable emoji support | | simple-view | SIMPLE_VIEW |false| minimized UI with basic info only | | proxy-cors | PROXY_CORS |false| disable internal CORS and delegate it to proxy | | allowed-hosts | ALLOWED_HOSTS | enable all | limit hosts/sources allowed to embed comments via CSP 'frame-ancestors' | | address | REMARK_ADDRESS | all interfaces | web server listening address | | port | REMARK_PORT |8080| web server port | | web-root | REMARK_WEB_ROOT |./web| web server root directory | | update-limit | UPDATE_LIMIT |0.5| updates/sec limit | | subscribers-only | SUBSCRIBERS_ONLY |false| enable commenting only for Patreon subscribers | | disable-signature | DISABLE_SIGNATURE |false| disable server signature in headers | | disable-fancy-text-formatting | DISABLE_FANCY_HTML_FORMATTING |false| disable fancy comments text formatting (replacement of quotes, dashes, fractions, etc) | | admin-passwd | ADMIN_PASSWD | none (disabled) | password foradminbasic auth | | dbg | DEBUG |false` | debug mode |

  • command-line parameters are long-form --<key>=value, i.e., --site=https://demo.remark42.com
  • multi parameters separated by , in the environment or repeated with command-line keys, like --site=s1 --site=s2 ...
  • required parameters have to be presented in the environment or provided in the command-line

Security Considerations for auth.send-jwt-header

When auth.send-jwt-header=true is enabled:

  • Security Impact: JWT tokens are stored in client-accessible cookies that can be accessed by JavaScript
  • Vulnerability: This increases vulnerability to XSS attacks compared to server-set HttpOnly cookies
  • Implementation Mitigations:
    • SameSite=Strict cookies to prevent CSRF attacks
    • Secure flag automatically added on HTTPS connections
    • __Host- prefix added on HTTPS to prevent subdomain attacks
    • Double Submit Cookie pattern with XSRF token matching the JWT ID

This configuration should only be used when:

  1. You need cross-domain authentication support
  2. You understand and accept the increased XSS risk
  3. You have implemented strong XSS protections on your site

Deprecated parameters

The following list of command-line options is deprecated and might be removed in the next major release after the version they were deprecated. After the Remark42 version update, please check the startup log once for deprecation warning messages to avoid trouble with unrecognized command-line options in the future.

Deprecated options
Command lineReplacementEnvironmentReplacementDefaultDescriptionDeprecation version
auth.email.templatenoneAUTH_EMAIL_TEMPLATEnoneemail_confirmation_login.html.tmplcustom email message template file1.5.0
auth.email.hostsmtp.hostAUTH_EMAIL_HOSTSMTP_HOSTsmtp host1.5.0
auth.email.portsmtp.portAUTH_EMAIL_PORTSMTP_PORTsmtp port1.5.0
auth.email.usersmtp.usernameAUTH_EMAIL_USERSMTP_USERNAMEsmtp user name1.5.0
auth.email.passwdsmtp.passwordAUTH_EMAIL_PASSWDSMTP_PASSWORDsmtp password1.5.0
auth.email.tlssmtp.tlsAUTH_EMAIL_TLSSMTP_TLSfalseenable TLS1.5.0
auth.email.timeoutsmtp.timeoutAUTH_EMAIL_TIMEOUTSMTP_TIMEOUT10ssmtp timeout1.5.0
img-proxyimage-proxy.http2httpsIMG_PROXYIMAGE_PROXY_HTTP2HTTPSfalseenable HTTP->HTTPS proxy for images1.5.0
notify.typenotify.admins, notify.usersNOTIFY_TYPENOTIFY_ADMINS, NOTIFY_USERS1.9.0
notify.email.notify_adminnotify.admins=emailNOTIFY_EMAIL_ADMINNOTIFY_ADMINS=email1.9.0
notify.telegram.tokentelegram.tokenNOTIFY_TELEGRAM_TOKENTELEGRAM_TOKENTelegram token1.9.0
notify.telegram.timeouttelegram.timeoutNOTIFY_TELEGRAM_TIMEOUTTELEGRAM_TIMEOUTTelegram timeout1.9.0
auth.twitter.cidnoneAUTH_TWITTER_CIDnoneTwitter Consumer API Key1.14.0
auth.twitter.csecnoneAUTH_TWITTER_CSECnoneTwitter Consumer API Secret key1.14.0

Admin users

Admins/moderators should be defined in docker-compose.yml as a list of user IDs or passed in the command line.

environment:
  - ADMIN_SHARED_ID=github_ef0f706a79cc24b17bbbb374cd234a691a034128,github_dae9983158e9e5e127ef2b87a411ef13c891e9e5

To get a user ID just log in and click on your username or any other user you want to promote to admins. It will expand login info and show the full user ID.

Docker image

Two parameters allow customizing the Docker container on the system level:

  • APP_UID - sets UID to run Remark42 application in container (default=1001)
  • TIME_ZONE - sets time zone of Remark42 container, would be used only on the backend as comments shown with user's timezone in the web interface (default=America/Chicago)

See umputun/baseimage for more details.