Skip to content

Using S-Filer Portal lightweight distributions

This manual

Who this guide is for

This guide is intended for S-Filer Portal administrators.

To enable S-Filer Portal administrators to easily install an instance of the solution or create custom Docker images, we have made available a lightweight distribution of each of the solution components. This distribution contains only the files required to run a working instance of the solution, and does not include any utilities to facilitate installation of the solution.

Components

The following SFiler / Portal components are shipped with the lightweight distribution:

ComponentUtility
sfiler-serverThis is the main component of the S-Filer Portal solution
sfiler-gatewayThis is the externally exposed component that receives files via a set of protocols
sfiler-config-cliCommand-line tool used to configure the S-Filer Portal solution
sfiler-admin-cliCommand-line tool used to administer the S-Filer Portal solution
sfiler-cliCommand-line tool used to access, download and upload files with the S-Filer Portal solution

System requirements

To use the lightweight distribution, you'll need a valid Java Runtime Environment (JDK). Any JDK should work (provided you're using the appropriate version). Normally, using the installer or publicly available Dockers images, the Eclipse Temurin JDK is the one used.

The S-Filer Portal lightweight distribution also comes with a compiled version of sfiler-admin-cli and sfiler-cli for Windows. Therefore, a JRE is not required to use only one or the other of these components.

Retrieving the distribution

First, you need to access the lightweight distribution files. To do this, connect to the Okiok S-Filer Portal instance (https://sfiler.okiok.com/sfiler/) using the credentials provided to you. You can retrieve the files using several protocols, such as SFTP or HTTPS. The lightweight S-Filer Portal distribution is uploaded to a share called S-Filer_Portal_Distributions. Distributions are sorted internally by major version (e.g. 4.19.x) and then by version (e.g. 4.19.0).

The official Docker images are based on the Alpine Linux version of Eclipse Temurin, Alpine being a lightweight Linux distribution based on BusyBox. If you need your Docker images to be based on another specific Linux distribution, you'll have to build them yourself.

Using the lightweight distribution

The following sections describe how to build custom Docker images for S-Filer Portal components. If you don't need to build custom Docker images, you can simply use the official publicly available Docker images.

Note

The files in the following sections are provided as examples only, and can be modified to suit your own use of the solution.

Note

While Dockerfiles are typically used to configure the environment for the use of certain software, Entrypoints are Bash scripts used to define the commands to be executed when the container is started.

Building a custom Docker image for the S-Filer config-cli

The following Dockerfile can be used to build a Docker image for the S-Filer config-cli:

Dockerfile
FROM eclipse-temurin:17-jre-alpine
LABEL maintainer="support@okiok.com"

RUN apk update && apk add --no-cache dos2unix bash gettext

COPY ./sfiler-config-cli/sfiler-config-cli-dist-linux.zip ./sfiler-config-cli-dist-linux.zip
RUN unzip sfiler-config-cli-dist-linux.zip && rm sfiler-config-cli-dist-linux.zip && mv ./sfiler-config-cli/ ./app/

# Add docker-compose-wait tool -------------------
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.12.0/wait /dockerWait
RUN chmod +x /dockerWait

WORKDIR /app

COPY entrypoint-config-cli.sh ./entrypoint.sh
RUN dos2unix ./entrypoint.sh

RUN ln -s /opt/java/openjdk ./jre

RUN mkdir /app/conf && touch /app/conf/sfiler.conf

RUN chgrp -R 0 * && chmod -R 770 *

VOLUME /app/conf
VOLUME /app/ext/lib

ENTRYPOINT ["bash", "./entrypoint.sh"]

The entrypoint-server.sh file:

shell
#!/bin/bash
set -e

if [ ! -z $CONFIG_DB_PASSWORD_FILE ]; then
  CONFIG_DB_PASSWORD=$(cat $CONFIG_DB_PASSWORD_FILE)
  echo "CONFIG_DB_PASSWORD_FILE provided, using it to set CONFIG_DB_PASSWORD"
fi

export WAIT_HOSTS=$(echo "$CONFIG_DB_URL" | sed -n 's/jdbc:[^:]\+:\/\/\([^/]\+\)\/.*/\1/p')
export WAIT_TIMEOUT=7200
export WAIT_SLEEP_INTERVAL=20

/dockerWait

{
  echo "cfg.server.local.config.url=$CONFIG_DB_URL"
  echo "cfg.server.local.config.driver=$CONFIG_DB_DRIVER"
  echo "cfg.server.local.config.hibernate.dialect=$CONFIG_DB_HIBERNATE_DIALECT"
} >> ./conf/sfiler.conf

echo "Saved local configuration to ./conf/sfiler.conf"

echo "====== < ./conf/sfiler.conf > ======"
cat ./conf/sfiler.conf
echo "====== < ./conf/sfiler.conf > ======"

echo "Substituting environment variables in /app/script.sfiler"
mkdir -p /app/int
envsubst < /app/script.sfiler > /app/script.sfiler.tmp
mv /app/script.sfiler.tmp /app/int/script.sfiler

if [ ! -s "/app/script.sfiler" ] && [ -z "$CONFIG_CLI_COMMAND" ]; then
  echo -e "\e[31mError: You need to provide at least one command to the SFiler Configuration CLI \e[0m"
  echo "Provide only 1 command using the CONFIG_CLI_COMMAND environment variable"
  echo "or provide multiple configuration commands by binding a file to the /app/script.sfiler file, inside of the container"
  exit 1
fi

if [ -n "$CONFIG_CLI_COMMAND" ]; then
    echo "Executing ./sfiler-config-cli.sh -cf ./conf/sfiler.conf -l $CONFIG_DB_USER -p <CONFIG_DB_PASSWORD> $CONFIG_CLI_COMMAND"
    ./sfiler-config-cli.sh -cf ./conf/sfiler.conf -l "$CONFIG_DB_USER" -p "$CONFIG_DB_PASSWORD" "$CONFIG_CLI_COMMAND"
fi

if [ -s /app/script.sfiler ]; then
  echo "Executing SFiler configuration script"
  echo "Executing ./sfiler-config-cli.sh -x /app/script.sfiler -cf ./conf/sfiler.conf -l $CONFIG_DB_USER -p <CONFIG_DB_PASSWORD>"
  ./sfiler-config-cli.sh -x /app/int/script.sfiler -cf ./conf/sfiler.conf -l "$CONFIG_DB_USER" -p "$CONFIG_DB_PASSWORD"
fi

echo "Exporting Gateway configuration..."
./sfiler-config-cli.sh -cf ./conf/sfiler.conf -l "$CONFIG_DB_USER" -p "$CONFIG_DB_PASSWORD" export-config -n ${SFILER_GATEWAY_INSTANCE_NAME} -ccf /app/configs/sfiler.conf

echo "Exporting GUI configuration..."
./sfiler-config-cli.sh -cf ./conf/sfiler.conf -l "$CONFIG_DB_USER" -p "$CONFIG_DB_PASSWORD" export-config -n ${SFILER_GUI_INSTANCE_NAME} -ccf /app/configs/gui.conf

Building a custom Docker image for the S-Filer server

The following Dockerfile can be used to build a Docker image for the S-Filer Server:

Dockerfile
FROM eclipse-temurin:17-jre-alpine
LABEL maintainer="support@okiok.com"

RUN apk update && apk add --no-cache dos2unix bash curl libc6-compat gcompat openssl

WORKDIR /app

COPY ./sfiler-server/ ./
COPY ./entrypoint-server.sh ./entrypoint.sh
COPY ./sfiler-server/cli-admin.jar bin/cli-admin.jar
COPY ./sfiler-server/config-cli-commands ./

RUN dos2unix ./entrypoint.sh

RUN ["mkdir", "/app/tmp"]
RUN ["mkdir", "/app/logs"]
RUN ["mkdir", "/app/files"]

RUN ["rm", "-rf", "ext/lib"]
RUN ["ln", "-s", "/ext/lib", "ext/lib"]

RUN ["ln", "-s", "/opt/java/openjdk", "../jre"]
RUN ["sed", "-i", "s/XXX_SFILER_SERVER_JRE_XXX/java/", "/app/conf/wrapper.conf"]
RUN ["sed", "-i", "s|XXX_SFILER_TEMP_FOLDER_XXX|/app/tmp|", "/app/conf/wrapper.conf"]

RUN chgrp -R 0 * && chmod -R 770 *

VOLUME /app/conf
VOLUME /app/logs
VOLUME /app/files
VOLUME /app/report

ENTRYPOINT ["bash", "./entrypoint.sh"]

The entrypoint-server.sh file:

shell
#!/bin/bash

if [ ! -z $CONFIG_DB_PASSWORD_FILE ]; then
  CONFIG_DB_PASSWORD=$(cat $CONFIG_DB_PASSWORD_FILE)
  echo "CONFIG_DB_PASSWORD_FILE provided, using it to set CONFIG_DB_PASSWORD"
fi

if [ ! -f /app/conf/sfiler.conf ]; then
  echo "cfg.sfiler.instance.name=${SFILER_SERVER_INSTANCE_NAME}" > conf/sfiler.conf
  echo "cfg.server.configurator.start=${CONFIGURATOR_START}" >> conf/sfiler.conf
  echo "cfg.server.webserver.configurator.jetty.server.ssl=${CONFIGURATOR_SSL}" >> conf/sfiler.conf
  echo "cfg.server.webserver.configurator.jetty.server.ssl.sni.host.check=${CONFIGURATOR_SSL_SNI_HOST_CHECK}" >> conf/sfiler.conf
  echo "cfg.server.webserver.configurator.jetty.server.ssl.cipher.management.mode=${CONFIGURATOR_SSL_CIPHER_MANAGEMENT_MODE}" >> conf/sfiler.conf
  echo "cfg.server.webserver.configurator.jetty.server.ssl.custom.ciphers=${CONFIGURATOR_SSL_CUSTOM_CIPHERS}" >> conf/sfiler.conf
  echo "cfg.server.webserver.configurator.jetty.server.port=${CONFIGURATOR_PORT}" >> conf/sfiler.conf
  echo "cfg.sfiler.keystore.password=${KEYSTORE_PASSWORD}" >> conf/sfiler.conf
  echo "cfg.sfiler.keystore=${KEYSTORE}" >> conf/sfiler.conf
  echo "cfg.configurator.private.key=${CONFIGURATOR_PRIVATE_KEY}" >> conf/sfiler.conf
  echo "cfg.configurator.clickjacking.protection=${CONFIGURATOR_CLICKJACKING_PROTECTION}" >> conf/sfiler.conf
  echo "cfg.configurator.hsts.header.support=${CONFIGURATOR_HSTS_HEADER_SUPPORT}" >> conf/sfiler.conf
  echo "cfg.configurator.hsts.header.support.max.age=${CONFIGURATOR_HSTS_HEADER_SUPPORT_MAX_AGE}" >> conf/sfiler.conf
  echo "cfg.server.local.config.user=${CONFIG_DB_USER}" >> conf/sfiler.conf
  echo "cfg.server.local.config.password=${CONFIG_DB_PASSWORD}" >> conf/sfiler.conf

  echo "cfg.server.local.config.url=${CONFIG_DB_URL}" >> conf/sfiler.conf
  echo "cfg.server.local.config.driver=${CONFIG_DB_DRIVER}" >> conf/sfiler.conf
  echo "cfg.server.local.config.hibernate.dialect=${CONFIG_DB_HIBERNATE_DIALECT}" >> conf/sfiler.conf
fi

sed "s/cfg.server.local.config.password=$CONFIG_DB_PASSWORD/cfg.server.local.config.password=****/g" conf/sfiler.conf

if [[ $CONFIGURATOR_START == "false" ]]; then
  CONFIGURATOR_KEY="configurator-key-$RANDOM"
  CERTIFICATES=$(./sfiler-config-cli.sh -l ${SFILER_INT_TEST_DB_USER} -p ${SFILER_INT_TEST_DB_PASSWORD} -cf ./conf/sfiler.conf list-certificates)
  if [[ $CERTIFICATES != *${CONFIGURATOR_KEY}* ]]; then
    echo "Generate ${CONFIGURATOR_KEY} ..."
    ./sfiler-config-cli.sh -l ${CONFIG_DB_USER} -p ${CONFIG_DB_PASSWORD} generate-key-pair -a $CONFIGURATOR_KEY -apply-configurator -d 10 -h ${SFILER_SERVER_INSTANCE_NAME} -ks 4096
  else
    echo "Certificate ${CONFIGURATOR_KEY} already exists."
  fi
fi

# Run the wrapper executable in the background
./wrapperLinux64 conf/wrapper.conf &
wrapperPID=$!

if [ "$LOGS" == "silent" ]; then
  wait $wrapperPID
else
  touch logs/server.log
  tail -f logs/server.log
fi

Building a custom Docker image for the S-Filer gateway

The following Dockerfile can be used to build a Docker image for the S-Filer Gateway:

Dockerfile
FROM eclipse-temurin:17-jre-alpine
LABEL maintainer="support@okiok.com"

RUN apk update && apk add --no-cache dos2unix bash openssl libc6-compat gcompat

WORKDIR /app

COPY ./sfiler-gateway/ ./
COPY ./entrypoint-gateway.sh ./entrypoint.sh

RUN dos2unix ./entrypoint.sh

RUN ["mkdir", "/app/tmp"]
RUN ["mkdir", "/app/logs"]

RUN ["ln", "-s", "/opt/java/openjdk", "../jre"]
RUN ["sed", "-i", "s/XXX_SFILER_SERVER_JRE_XXX/java/", "/app/conf/wrapper.conf"]
RUN ["sed", "-i", "s|XXX_SFILER_TEMP_FOLDER_XXX|/app/tmp|", "/app/conf/wrapper.conf"]
RUN chmod -R 744 /opt/java/openjdk/lib/security/cacerts

# Add docker-compose-wait tool -------------------
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.12.0/wait /dockerWait
RUN chmod +x /dockerWait
VOLUME /app/conf
VOLUME /app/logs

ENTRYPOINT ["bash", "./entrypoint.sh"]

The entrypoint-gateway.sh file:

shell
#!/bin/bash

if [[ "$DOCKER_COMPOSE_WAIT" == "true" ]]; then
  /dockerWait
fi

echo "Copying the generated configuration into the effective configuration that will be used by the wrapper..."
cp /app/configs/sfiler.conf /app/conf/
cp /app/configs/gui.conf /app/conf/

echo ""
echo "Using the following configuration for the Gateway:"
cat /app/conf/sfiler.conf
echo ""

echo ""
echo "Using the following configuration for the GUI:"
cat /app/conf/gui.conf
echo ""

echo ""
echo "Using the following configuration for the Wrapper:"
cat conf/wrapper.conf
echo ""

# Run the wrapper executable in the background
./wrapperLinux64 conf/wrapper.conf &
wrapperPID=$!

if [ "$LOGS" == "silent" ]; then
  wait $wrapperPID
else
  touch logs/gateway.log
  tail -f logs/gateway.log
fi