+Docker Deploy Daemon
+Orchestrates the deployment of applications as Docker containers.
+
+
Warning
+
The administrator is responsible for the security actions taken to configure the Docker daemon connected to the Nextcloud instance.
+
These schemes are only examples of possible configurations.
+
We recommend that you use the AppAPI Docker Socket Proxy or AIO Docker Socket Proxy container.
+
+There are several Docker Daemon Deploy configurations (example schemes):
+
+
+Nextcloud and Docker on the same host (via socket or DockerSocketProxy)
+Nextcloud on the host and Docker on a remote host (via DockerSocketProxy with HTTPS)
+Nextcloud and ExApps in the same Docker (via DockerSocketProxy)
+Nextcloud in AIO Docker and ExApps in the same Docker (via AIO DockerSocketProxy)
+
+
+
+NC & Docker on the Same-Host
+The simplest configuration is when Nextcloud is installed on the host and Docker is on the same host and applications are deployed to it.
+
+ stateDiagram-v2
+ classDef docker fill: #1f97ee, color: transparent, font-size: 34px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
+ classDef nextcloud fill: #006aa3, color: transparent, font-size: 34px, stroke: #045987, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/nextcloud.svg) no-repeat center center / contain
+ classDef python fill: #1e415f, color: white, stroke: #364c53, stroke-width: 1px
+
+ Host
+
+ state Host {
+ Nextcloud --> Daemon : /var/run/docker.sock
+ Daemon --> Containers
+
+ state Containers {
+ ExApp1
+ --
+ ExApp2
+ --
+ ExApp3
+ }
+ }
+
+ class Nextcloud nextcloud
+ class Daemon docker
+ class ExApp1 python
+ class ExApp2 python
+ class ExApp3 python
+
+- Suggested config values(template Custom default):
+Daemon host: /var/run/docker.sock
+HTTPS checkbox: not supported using docker socket
+Network: host
+HaProxy password: not supported using raw docker socket, should be empty
+
+
+
+—
+Suggested way to communicate with Docker via Docker Socket Proxy container.
+
+ stateDiagram-v2
+ classDef docker fill: #1f97ee, color: transparent, font-size: 34px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
+ classDef nextcloud fill: #006aa3, color: transparent, font-size: 34px, stroke: #045987, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/nextcloud.svg) no-repeat center center / contain
+ classDef python fill: #1e415f, color: white, stroke: #364c53, stroke-width: 1px
+
+ Host
+
+ state Host {
+ Nextcloud --> DockerSocketProxy: by port
+ Docker --> Containers
+ Docker --> DockerSocketProxy : /var/run/docker.sock
+
+ state Containers {
+ DockerSocketProxy --> ExApp1
+ DockerSocketProxy --> ExApp2
+ DockerSocketProxy --> ExApp3
+ }
+ }
+
+ class Nextcloud nextcloud
+ class Docker docker
+ class ExApp1 python
+ class ExApp2 python
+ class ExApp3 python
+
+- Suggested config values(template Docker Socket Proxy):
+
+- Daemon host:
localhost:2375
+- Choose A or B option:
+Docker Socket Proxy should be deployed with network=host
and BIND_ADDRESS=127.0.0.1
+Docker Socket Proxy should be deployed with network=bridge
and it’s port should be published to host’s 127.0.0.1(e.g. -p 127.0.0.1:2375:2375)
+
+
+
+
+
+
+HTTPS checkbox: disabled
+Network: host
+HaProxy password: should not be empty
+
+
+
+
+
Warning
+
Be careful with option A
, by default Docker Socket Proxy binds to *
if BIND_ADDRESS
is not specified during container creation.
+Check opened ports after finishing configuration.
+
+
+
+Docker on a remote host
+Distributed configuration occurs when Nextcloud is installed on one host and Docker is located on a remote host, resulting in the deployment of applications on the remote host.
+Benefit: no performance impact on Nextcloud host.
+In this case, the AppAPI uses a Docker Socket Proxy deployed on remote host to access docker socket and ExApps.
+
+ stateDiagram-v2
+ classDef docker fill: #1f97ee, color: transparent, font-size: 34px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
+ classDef nextcloud fill: #006aa3, color: transparent, font-size: 34px, stroke: #045987, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/nextcloud.svg) no-repeat center center / contain
+ classDef python fill: #1e415f, color: white, stroke: #364c53, stroke-width: 1px
+
+ Direction LR
+
+ Host1 --> Host2 : by port
+
+ state Host1 {
+ Nextcloud
+ }
+
+ state Host2 {
+ [*] --> DockerSocketProxy : by port
+ Daemon --> Containers
+
+ state Containers {
+ [*] --> DockerSocketProxy : /var/run/docker.sock
+ DockerSocketProxy --> ExApp1
+ DockerSocketProxy --> ExApp2
+ DockerSocketProxy --> ExApp3
+ }
+ }
+
+ class Nextcloud nextcloud
+ class Daemon docker
+ class ExApp1 python
+ class ExApp2 python
+ class ExApp3 python
+
+- Suggested config values(template Docker Socket Proxy):
+Daemon host: ADDRESS_OF_REMOTE_MACHINE (e.g. server_name.com:2375)
+HTTPS checkbox: enabled
+Network: host
+HaProxy password: should not be empty
+
+
+
+
+
+NC & ExApps in the same Docker
+Applications are deployed in the same docker where Nextcloud resides.
+Suggested way to communicate with Docker: via docker-socket-proxy
.
+
+ stateDiagram-v2
+ classDef docker fill: #1f97ee, color: transparent, font-size: 34px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
+ classDef nextcloud fill: #006aa3, color: transparent, font-size: 34px, stroke: #045987, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/nextcloud.svg) no-repeat center center / contain
+ classDef python fill: #1e415f, color: white, stroke: #364c53, stroke-width: 1px
+
+ Host
+
+ state Host {
+ Daemon --> Containers
+
+ state Containers {
+ [*] --> DockerSocketProxy : /var/run/docker.sock
+ Nextcloud --> DockerSocketProxy: by port
+ --
+ DockerSocketProxy --> ExApp1
+ DockerSocketProxy --> ExApp2
+ }
+ }
+
+ class Nextcloud nextcloud
+ class Daemon docker
+ class ExApp1 python
+ class ExApp2 python
+ class ExApp3 python
+
+- Suggested config values(template Docker Socket Proxy):
+Daemon host: nextcloud-appapi-dsp:2375
+HTTPS checkbox: disabled
+Network: user defined network
+HaProxy password: should not be empty
+
+
+
+
+
Note
+
Network should not be the default docker’s bridge as it does not support DNS resolving by container names.
+
This means that Docker Socket Proxy, Nextcloud and ExApps containers should all be in the same docker network, different from the default bridge.
+
+
+
+Nextcloud in Docker AIO (all-in-one)
+In case of AppAPI is in Docker AIO setup (installed in Nextcloud container).
+
+
Note
+
AIO Docker Socket Proxy container must be enabled.
+
+
+ stateDiagram-v2
+ classDef docker fill: #1f97ee, color: transparent, font-size: 34px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
+ classDef docker2 fill: #1f97ee, color: transparent, font-size: 20px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
+ classDef nextcloud fill: #006aa3, color: transparent, font-size: 34px, stroke: #045987, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/nextcloud.svg) no-repeat center center / contain
+ classDef python fill: #1e415f, color: white, stroke: #364c53, stroke-width: 1px
+
+ Host
+
+ state Host {
+ Daemon --> Containers
+
+ state Containers {
+ [*] --> NextcloudAIOMasterContainer : /var/run/docker.sock
+ [*] --> DockerSocketProxy : /var/run/docker.sock
+ NextcloudAIOMasterContainer --> Nextcloud
+ AppAPI --> Nextcloud : installed in
+ Nextcloud --> DockerSocketProxy
+ DockerSocketProxy --> ExApp1
+ DockerSocketProxy --> ExApp2
+ DockerSocketProxy --> ExApp3
+ }
+ }
+
+ class Nextcloud nextcloud
+ class Daemon docker
+ class Daemon2 docker2
+ class ExApp1 python
+ class ExApp2 python
+ class ExApp3 python
+
AppAPI will automatically create default default DaemonConfig to use AIO Docker Socket Proxy as orchestrator to create ExApp containers.
+
+
Note
+
Default DaemonConfig will be created only if the default DaemonConfig is not already registered.
+
+
+Default AIO Deploy Daemon
+Nextcloud AIO has a specifically created Docker Socket Proxy container to be used as the Deploy Daemon in AppAPI.
+It has fixed parameters:
+
+Name: docker_aio
+Display name: AIO Docker Socket Proxy
+Accepts Deploy ID: docker-install
+Protocol: http
+Host: nextcloud-aio-docker-socket-proxy:2375
+Compute device: CPU
+Network: nextcloud-aio
+Nextcloud URL (passed to ExApps): https://$NC_DOMAIN
+
+
+
+Docker Socket Proxy security
+AIO Docker Socket Proxy has strictly limited access to the Docker APIs described in HAProxy configuration.
+
+
+
+
+NC to ExApp Communication
+Each type of DeployDaemon necessarily implements the resolveExAppUrl
function.
+It has such prototype:
+public function resolveExAppUrl(
+ string $appId, string $protocol, string $host, array $deployConfig, int $port, array &$auth
+) {}
+
+
+where:
+
+protocol is daemon protocol value
+host is daemon host value, can be DNS:port or IP:PORT or even path to docker socket.
+port is an integer with ExApp port
+deployConfig can be custom for each Daemon type
+auth is an optional array, with Basic Authentication data if needed to access ExApp
+
+
+
Note
+
Starting with AppAPI version 2.5.0
, the optional additional parameter OVERRIDE_APP_HOST can be used to
+override the host that will be used for ExApp binding.
+
It can be 0.0.0.0
in some specific configurations, when VPN is used
+or both Nextcloud instance and ExApps are one the same physical machine but different virtual environments.
+
Also you can specify something like 10.10.2.5
and in this case ExApp
wil try to bind to that address and
+AppAPI will try to send request s directly to this address assuming that ExApp itself bound on it.
+
+The simplest implementation is in Manual-Install deploy type:
+public function resolveExAppUrl(
+ string $appId, string $protocol, string $host, array $deployConfig, int $port, array &$auth
+): string {
+ $auth = [];
+ if (isset($deployConfig['additional_options']['OVERRIDE_APP_HOST']) &&
+ $deployConfig['additional_options']['OVERRIDE_APP_HOST'] !== ''
+ ) {
+ $wideNetworkAddresses = ['0.0.0.0', '127.0.0.1', '::', '::1'];
+ if (!in_array($deployConfig['additional_options']['OVERRIDE_APP_HOST'], $wideNetworkAddresses)) {
+ $host = $deployConfig['additional_options']['OVERRIDE_APP_HOST'];
+ }
+ }
+ return sprintf('%s://%s:%s', $protocol, $host, $port);
+}
+
+
+Here we see that AppAPI send requests to host:port specified during daemon creation.
+Now let’s take a look at the Docker Daemon implementation of resolveExAppUrl
:
+public function resolveExAppUrl(
+ string $appId, string $protocol, string $host, array $deployConfig, int $port, array &$auth
+): string {
+ $auth = [];
+ if (isset($deployConfig['additional_options']['OVERRIDE_APP_HOST']) &&
+ $deployConfig['additional_options']['OVERRIDE_APP_HOST'] !== ''
+ ) {
+ $wideNetworkAddresses = ['0.0.0.0', '127.0.0.1', '::', '::1'];
+ if (!in_array($deployConfig['additional_options']['OVERRIDE_APP_HOST'], $wideNetworkAddresses)) {
+ return sprintf(
+ '%s://%s:%s', $protocol, $deployConfig['additional_options']['OVERRIDE_APP_HOST'], $port
+ );
+ }
+ }
+ $host = explode(':', $host)[0];
+ if ($protocol == 'https') {
+ $exAppHost = $host;
+ } elseif (isset($deployConfig['net']) && $deployConfig['net'] === 'host') {
+ $exAppHost = 'localhost';
+ } else {
+ $exAppHost = $appId;
+ }
+ if (isset($deployConfig['haproxy_password']) && $deployConfig['haproxy_password'] !== '') {
+ $auth = [self::APP_API_HAPROXY_USER, $deployConfig['haproxy_password']];
+ }
+ return sprintf('%s://%s:%s', $protocol, $exAppHost, $port);
+}
+
+
+Here we have much more complex algorithm of detecting to where requests should be send.
+First of all if protocol is set to https
AppAPI always send requests to daemon host,
+and this is in case of https
it is a HaProxy that will forward requests to ExApps that will be listen on localhost
+Briefly it will look like this(haproxy_host==daemon host value):
+NC –> https –> haproxy_host:ex_app_port
–> http –> localhost:ex_app_port
+When protocol is not https
but http
, then what will be the endpoint where to send requests is determined by $deployConfig['net']
value.
+If net
is defined and equal to host
then AppAPI assumes that ExApp is installed somewhere in the current host network and will be available on localhost
loop-back adapter.
+NC –> http –> localhost:ex_app_port
+In all other cases ExApp should be available by it’s name: e.g. when using docker custom bridge network all containers available by DNS.
+NC –> http –> app_container_name:ex_app_port
+This three different types of communication covers all most popular configurations.
+
+