diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6c63f9bed57d26020d55cab52c288c1c2c103c3a..0a0f941effc4a86aa2708591e05d218b0f27fc0b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,5 +1,3 @@
-variables:
-  GIT_SUBMODULE_STRATEGY: recursive
 build:
   image: docker:latest
   stage: build
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..ef0dbef035ae5e40a1c1e15cd42243cb31a12776
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,73 @@
+ARG product_version=7.3.3
+ARG build_number=50
+ARG oo_root='/var/www/onlyoffice/documentserver'
+
+## Setup
+FROM onlyoffice/documentserver:${product_version}.${build_number} as setup-stage
+ARG product_version
+ARG build_number
+ARG oo_root
+
+ENV PRODUCT_VERSION=${product_version}
+ENV BUILD_NUMBER=${build_number}
+
+ARG build_deps="git make g++ nodejs npm jq"
+RUN apt-get update && apt-get install -y ${build_deps}
+RUN npm install -g pkg grunt grunt-cli
+
+WORKDIR /build
+
+
+
+## Clone
+FROM setup-stage as clone-stage
+ARG tag=v${PRODUCT_VERSION}.${BUILD_NUMBER}
+
+RUN git clone --quiet --branch $tag --depth 1 https://github.com/ONLYOFFICE/build_tools.git /build/build_tools
+RUN git clone --quiet --branch $tag --depth 1 https://github.com/ONLYOFFICE/server.git      /build/server
+
+COPY server.patch /build/server.patch
+RUN cd /build/server   && git apply /build/server.patch
+
+
+## Build
+FROM clone-stage as build-stage
+
+# build server with license checks patched
+WORKDIR /build/server
+RUN make
+RUN pkg /build/build_tools/out/linux_64/onlyoffice/documentserver/server/FileConverter --targets=node14-linux -o /build/converter
+RUN pkg /build/build_tools/out/linux_64/onlyoffice/documentserver/server/DocService --targets=node14-linux --options max_old_space_size=4096 -o /build/docservice
+
+RUN mv /etc/onlyoffice/documentserver/default.json /etc/onlyoffice/documentserver/default-origin.json
+COPY default-override.json /etc/onlyoffice/documentserver/
+RUN jq -s '.[0] * .[1]' /etc/onlyoffice/documentserver/default-origin.json /etc/onlyoffice/documentserver/default-override.json -r > /etc/onlyoffice/documentserver/default.json
+
+RUN git clone --quiet https://github.com/ONLYOFFICE/plugin-jitsi.git /build/plugin-jitsi && \
+    sed "s/meet.jit.si/meet.liiib.re/" -i /build/plugin-jitsi/scripts/code.js
+RUN git clone --quiet https://github.com/ONLYOFFICE/plugin-doc2md.git /build/plugin-doc2md
+RUN git clone --quiet https://github.com/ONLYOFFICE/plugin-languagetool.git /build/plugin-languagetool
+
+
+## Final image
+FROM registry.libre.sh/fonts:latest as fonts
+FROM onlyoffice/documentserver:${product_version}.${build_number}
+ARG oo_root
+
+#server
+COPY --from=build-stage /build/converter  ${oo_root}/server/FileConverter/converter
+COPY --from=build-stage /build/docservice ${oo_root}/server/DocService/docservice
+
+# plugins
+COPY --from=build-stage --chown=ds:ds /build/plugin-jitsi ${oo_root}/sdkjs-plugins/jitsi
+COPY --from=build-stage --chown=ds:ds /build/plugin-doc2md ${oo_root}/sdkjs-plugins/doc2md
+COPY --from=build-stage --chown=ds:ds /build/plugin-languagetool ${oo_root}/sdkjs-plugins/languagetool
+
+# fonts
+COPY --from=fonts /fonts/ /usr/share/fonts/custom/
+RUN /usr/bin/documentserver-generate-allfonts.sh true
+
+# config
+COPY --from=build-stage /etc/onlyoffice/documentserver/default.json /etc/onlyoffice/documentserver/default.json
+
+ENV GENERATE_FONTS=false
diff --git a/README.md b/README.md
index 87acf0b3eae53d4d51415b546879851b070aaf8a..64fe767c53fb27af066193ddb770a185097cdec1 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,3 @@
 # OnlyOffice
 
-Based on [n-goncalves/onlyoffice-ce-docker-license](https://github.com/n-goncalves/onlyoffice-ce-docker-license) with mobile editing enabled and an unlimited amount of concurrent users.
-
-We added some popular fonts and auto-save back to Nextcloud every minute.
+With an unlimited amount of concurrent users, some popular fonts and auto-save back to Nextcloud every minute.
diff --git a/base b/base
deleted file mode 160000
index 8746ac88e7f5d47669e8b237f677a974d30f85ba..0000000000000000000000000000000000000000
--- a/base
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 8746ac88e7f5d47669e8b237f677a974d30f85ba
diff --git a/ci/package.sh b/ci/package.sh
index cbcb12c89d2d0be8aab7fcd3936820fa03fb73b9..49d93c3b6455aaec49f3ab9a9a18a2ca5e87b4e9 100755
--- a/ci/package.sh
+++ b/ci/package.sh
@@ -1,22 +1,20 @@
 #!/bin/sh
 
-(cd base && git apply ../dockerfile.patch)
-
-PRODUCT_VERSION=$(grep "ARG product_version=" base/Dockerfile | sed "s/ARG product_version=//")
-BUILD_NUMBER=$(grep "ARG build_number=" base/Dockerfile | sed "s/ARG build_number=//")
+PRODUCT_VERSION=$(grep "ARG product_version=" Dockerfile | sed "s/ARG product_version=//")
+BUILD_NUMBER=$(grep "ARG build_number=" Dockerfile | sed "s/ARG build_number=//")
 
 if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then
   docker build --pull \
       -t libresh/onlyoffice \
       -t libresh/onlyoffice:$PRODUCT_VERSION.$BUILD_NUMBER \
       -t libresh/onlyoffice:$PRODUCT_VERSION.$BUILD_NUMBER-$CI_COMMIT_SHORT_SHA \
-      -f base/Dockerfile .
+      .
 else
   docker build --pull \
       -t libresh/onlyoffice:$CI_COMMIT_BRANCH \
       -t libresh/onlyoffice:$CI_COMMIT_BRANCH-$PRODUCT_VERSION.$BUILD_NUMBER \
       -t libresh/onlyoffice:$CI_COMMIT_BRANCH-$PRODUCT_VERSION.$BUILD_NUMBER-$CI_COMMIT_SHORT_SHA\
-      -f base/Dockerfile .
+      .
 fi
 
 docker push -a libresh/onlyoffice
diff --git a/server.patch b/server.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0fd5405ef188c51f823defed28c44a6e02bdc453
--- /dev/null
+++ b/server.patch
@@ -0,0 +1,103 @@
+diff --git a/Common/sources/constants.js b/Common/sources/constants.js
+index b9c2906..4124680 100644
+--- a/Common/sources/constants.js
++++ b/Common/sources/constants.js
+@@ -84,7 +84,7 @@ exports.LICENSE_RESULT = {
+   UsersViewCountOS: 15
+ };
+ 
+-exports.LICENSE_CONNECTIONS = 20;
++exports.LICENSE_CONNECTIONS = 9999;
+ exports.LICENSE_EXPIRE_USERS_ONE_DAY = 24 * 60 * 60; // day in seconds
+ 
+ exports.AVS_OFFICESTUDIO_FILE_UNKNOWN =  0x0000;
+diff --git a/Common/sources/license.js b/Common/sources/license.js
+index 1b617c6..4f5d25f 100644
+--- a/Common/sources/license.js
++++ b/Common/sources/license.js
+@@ -45,23 +45,23 @@ exports.readLicense = function*() {
+ 		count: 1,
+ 		type: c_LR.Success,
+ 		light: false,
+-		packageType: constants.PACKAGE_TYPE_OS,
++		packageType: constants.PACKAGE_TYPE_I,
+ 		mode: constants.LICENSE_MODE.None,
+-		branding: false,
++		branding: true,
+ 		connections: constants.LICENSE_CONNECTIONS,
+ 		connectionsView: constants.LICENSE_CONNECTIONS,
+-		customization: false,
+-		advancedApi: false,
+-		usersCount: 0,
+-		usersViewCount: 0,
++		customization: true,
++		advancedApi: true,
++		usersCount: constants.LICENSE_CONNECTIONS,
++		usersViewCount: constants.LICENSE_CONNECTIONS,
+ 		usersExpire: constants.LICENSE_EXPIRE_USERS_ONE_DAY,
+-		hasLicense: false,
+-		plugins: false,
++		hasLicense: true,
++		plugins: true,
+ 		buildDate: oBuildDate,
+ 		startDate: startDate,
+-		endDate: null,
++		endDate: new Date("2099-01-01T23:59:59.000Z"),
+ 		customerId: "",
+-		alias: ""
++		alias: "community"
+ 	}, null];
+ };
+ 
+diff --git a/Common/sources/tenantManager.js b/Common/sources/tenantManager.js
+index 66dbb96..3fc932b 100644
+--- a/Common/sources/tenantManager.js
++++ b/Common/sources/tenantManager.js
+@@ -140,6 +140,10 @@ function getTenantLicense(ctx) {
+         ctx.logger.error('getTenantLicense error: missing "alias" field');
+       }
+     } else {
++      // This might need to be changed
++      // xbeeant chose to always return a static object, it might break in multitenant mode ?
++      // Maybe you can use the generation to retrieve the one defined in license.js [res] = yield* license.readLicense(licensePath);
++      // Or it might work just like that.
+       res = licenseInfo;
+     }
+     return res;
+diff --git a/DocService/sources/server.js b/DocService/sources/server.js
+index 74a00b0..0c7e4e7 100644
+--- a/DocService/sources/server.js
++++ b/DocService/sources/server.js
+@@ -111,7 +111,6 @@ if (!(cfgTokenEnableBrowser && cfgTokenEnableRequestInbox && cfgTokenEnableReque
+ 
+ if (!tenantManager.isMultitenantMode()) {
+ 	updateLicense();
+-	fs.watchFile(cfgLicenseFile, updateLicense);
+ 	setInterval(updateLicense, 86400000);
+ }
+ 
+diff --git a/FileConverter/sources/convertermaster.js b/FileConverter/sources/convertermaster.js
+index 2a0b366..96468f9 100644
+--- a/FileConverter/sources/convertermaster.js
++++ b/FileConverter/sources/convertermaster.js
+@@ -93,7 +93,6 @@ if (cluster.isMaster) {
+   updateLicense();
+ 
+   if (!tenantManager.isMultitenantMode()) {
+-    fs.watchFile(cfgLicenseFile, updateLicense);
+     setInterval(updateLicense, 86400000);
+   }
+ } else {
+diff --git a/Makefile b/Makefile
+index e8e1308..23f7e2e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -87,7 +87,7 @@ DEBUG = $(BRANDING_DIR)/debug.js
+ .PHONY: all clean install uninstall build-date
+ 
+ .NOTPARALLEL:
+-all: $(SPELLCHECKER_DICTIONARIES) $(TOOLS) $(SCHEMA) $(CORE_FONTS) $(DOCUMENT_TEMPLATES) $(LICENSE) $(WELCOME) $(INFO) build-date
++all: $(SCHEMA) $(LICENSE) $(WELCOME) $(INFO) build-date
+ 
+ build-date: $(GRUNT_FILES)
+ 	sed "s|\(const buildVersion = \).*|\1'${PRODUCT_VERSION}';|" -i $(COMMON_DEFINES_JS)