diff --git a/Dockerfile b/Dockerfile index 4fd66f3a8c..9db3b818db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,14 +34,22 @@ FROM --platform=$TARGETPLATFORM nginx:1-alpine # environmental variables ENV PORT=80 +# install dependencies +RUN apk update \ + && apk add --no-cache jq=1.7.1-r0 + # copy artifact build from the 'build environment' COPY --from=build /app/dist/browser /usr/share/nginx/html # copy nginx config COPY ./nginx/default.conf.template /etc/nginx/templates/default.conf.template +# copy entrypoint script +COPY ./docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh + # expose port: defaults to 80 EXPOSE $PORT -# run nginx -CMD ["nginx", "-g", "daemon off;"] +# run docker-entrypoint.sh +WORKDIR /usr/share/nginx/html +CMD ["docker-entrypoint.sh"] diff --git a/README.md b/README.md index 9945917249..aa45e35b4d 100644 --- a/README.md +++ b/README.md @@ -425,6 +425,10 @@ docker compose up -d Additionally to accessing the web app from your browser at `http://localhost`, you can set up WebDAV synchronization with base url `http://localhost/webdav/`. +### Other configuration of docker container + +You can provide the default values for WebDAV settings in the "Sync" section of the "Settings" page, via setting some environment variables of the docker container. This could be used for single user instances. Check out `docker-compose.yaml` in this repository for available environment variables. + ## Custom themes (desktop only) In addition to color coding your projects and tags and to the dark and light theme you can also load completely custom CSS to restyle everything. To load a custom theme you simply need to put them into a new file named `styles.css` directly in the [user data folder](#user-data-folder). diff --git a/docker-compose.yaml b/docker-compose.yaml index f9b3deb017..4d092b77b5 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -4,10 +4,21 @@ services: ports: - 80:80 environment: - - WEBDAV_BACKEND=http://webdav # Optional + # WebDAV backend served at `/webdav/` subdirectory (Optional) + # Used with "webdav" container below + - WEBDAV_BACKEND=http://webdav - # Optional: WebDAV backend server - # (used with the WEBDAV_BACKEND environment variable) + # Default values in "Sync" section in "Settings" page (Optional) + # Useful for single user instances + - WEBDAV_BASE_URL= + - WEBDAV_USERNAME= + - WEBDAV_SYNC_FOLDER_PATH= + - SYNC_INTERVAL= + - IS_COMPRESSION_ENABLED= + - IS_ENCRYPTION_ENABLED= + + # WebDAV backend server (Optional) + # Used with the WEBDAV_BACKEND environment variable webdav: image: hacdias/webdav:latest volumes: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 0000000000..5047e807cf --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +# Generate ./assets/sync-config-default-override.json from environment variables +JSON="{}" +JSON_PATH=./assets/sync-config-default-override.json +if [ -n "${WEBDAV_BASE_URL}" ]; then + JSON=$(echo "$JSON" | jq ".webDav.baseUrl |= \"$WEBDAV_BASE_URL\"") +fi +if [ -n "${WEBDAV_USERNAME}" ]; then + JSON=$(echo "$JSON" | jq ".webDav.userName |= \"$WEBDAV_USERNAME\"") +fi +if [ -n "${WEBDAV_SYNC_FOLDER_PATH}" ]; then + JSON=$(echo "$JSON" | jq ".webDav.syncFolderPath |= \"$WEBDAV_SYNC_FOLDER_PATH\"") +fi +if [ "$JSON" != "{}" ]; then + # Change syncProvider if previous variables are set + JSON=$(echo "$JSON" | jq '.syncProvider |= "WebDAV"') +fi +if [ -n "${SYNC_INTERVAL}" ]; then + JSON=$(echo "$JSON" | jq ".syncInterval |= $(expr $SYNC_INTERVAL \* 60000)") +fi +if [ -n "${IS_COMPRESSION_ENABLED}" ]; then + JSON=$(echo "$JSON" | jq ".isCompressionEnabled |= $IS_COMPRESSION_ENABLED") +fi +if [ -n "${IS_ENCRYPTION_ENABLED}" ]; then + JSON=$(echo "$JSON" | jq ".isEncryptionEnabled |= $IS_ENCRYPTION_ENABLED") +fi +if [ "$JSON" != "{}" ]; then + # Write the resultant json + echo "$JSON" >$JSON_PATH +fi + +# run nginx +nginx -g "daemon off;" diff --git a/src/app/imex/sync/sync-config.service.ts b/src/app/imex/sync/sync-config.service.ts index d1d46d61ce..cdf0d1ea05 100644 --- a/src/app/imex/sync/sync-config.service.ts +++ b/src/app/imex/sync/sync-config.service.ts @@ -1,9 +1,9 @@ import { inject, Injectable } from '@angular/core'; import { PfapiService } from '../../pfapi/pfapi.service'; import { GlobalConfigService } from '../../features/config/global-config.service'; -import { combineLatest, Observable } from 'rxjs'; +import { combineLatest, from, of, Observable } from 'rxjs'; import { SyncConfig } from '../../features/config/global-config.model'; -import { map, tap } from 'rxjs/operators'; +import { switchMap, tap } from 'rxjs/operators'; import { PrivateCfgByProviderId, SyncProviderId } from '../../pfapi/api'; import { DEFAULT_GLOBAL_CONFIG } from '../../features/config/default-global-config.const'; @@ -26,7 +26,7 @@ export class SyncConfigService { this._globalConfigService.sync$, this._pfapiService.currentProviderPrivateCfg$, ]).pipe( - map(([syncCfg, currentProviderCfg]) => { + switchMap(([syncCfg, currentProviderCfg]) => { // Base config with defaults const baseConfig = { ...DEFAULT_GLOBAL_CONFIG.sync, @@ -35,10 +35,23 @@ export class SyncConfigService { // If no provider is active, return base config with empty encryption key if (!currentProviderCfg) { - return { - ...baseConfig, - encryptKey: '', - }; + return from( + fetch('/assets/sync-config-default-override.json') + .then((res) => res.json()) + .then((defaultOverride) => { + return { + ...baseConfig, + ...defaultOverride, + encryptKey: '', + }; + }) + .catch(() => { + return { + ...baseConfig, + encryptKey: '', + }; + }), + ); } const prop = PROP_MAP_TO_FORM[currentProviderCfg.providerId]; @@ -57,7 +70,7 @@ export class SyncConfigService { result[prop] = currentProviderCfg.privateCfg; } - return result; + return of(result); }), tap((v) => console.log('syncSettingsForm$', v)), ); diff --git a/src/assets/sync-config-default-override.json b/src/assets/sync-config-default-override.json new file mode 100644 index 0000000000..76ec6679e1 --- /dev/null +++ b/src/assets/sync-config-default-override.json @@ -0,0 +1,3 @@ +{ + "_comment": "This JSON file will be regenerated by docker-entrypoint.sh based on environment variables in docker environment." +}