Howto - Docker container oder Applikation bei Bedarf starten (bei Netzwerk Zugriff)

Status
Für weitere Antworten geschlossen.

remoh

Benutzer
Mitglied seit
06. Jan 2019
Beiträge
6
Punkte für Reaktionen
0
Punkte
0
Hallo,

ich habe vor kurzem ein Synology NAS gekauft (DS218+). Darauf habe ich einen seafile docker container am laufen, mich aber darüber geärgert das dieser verhindert das die Festplatten herunterfahren können. Daher habe ich eine Lösung dafür gesucht und gebaut die ich hier gerne weitergeben möchte da sind nicht auf seafile begrenzt ist sondern für alle möglichen Dienste verwendet werden kann welche den Festplatten Schlafmodus verhindern aber trotzdem nutzbar sein sollen.

Hintergund ist das der Dienst (in diesem Fall seafile als docker container) nur bei Bedarf gestartet wird, automatisch bei Netzwerk Zugriff und ohne das eine Anfrage ins Leere läuft. Nach 10 min ohne netzwerkzugriff wird der Dienst wieder gestoppt und die Festplatten können wieder in den Ruhezustand gehen.

Ich hatte die Anleitung gleich in englisch geschrieben, aber das Englische Synology Forum https://community.synology.com/forum/ ist irgendwie seltsam...
Daher hier erstmal alles in englisch. Gibt es hier im Forum einen Howto Bereich? habe nichts derartiges gefunden.


Startup a docker container or application to run on demand (on network access)

On my Synology DS218+ i am running a seafile docker container. It runs fine so far, but as long as seafile is running the harddisks never spin down.
Since i do not need seafile all the time this a waste of energy and the hard disks do run unnecessarily long, which is not good for its lifetime.

I searched for a solution and found something that is maybe usefull for other applications that prevent spindown of harddisks, too.

It is based on the idea that the service only should startup when someone uses it.
After some research i found the systemd-socket-proxyd would be useful for this. It listens on a port and do something when traffic to this port comes in.
So when someone accesses the port it can start for example an application or in my case a docker container.
When the application or conainer is up and ready to serve the request it will forward it without interrupt.
This way i can have my seafile container turned off and it will only be started when accessed, the application will not get a not available message, it will just wait for some seconds until the application is up.
When seafile has not been used for 10 mintues it will shutdown its container so the harddiks may spin down again.


An example how it works:

Client -> https://mydomain.com (Port 443, <IP of SynologyNAS>)
Request to seafile website

-> 443:<IP of SynologyNAS> (SynologyNAS reverse proxy application)
The reverse Proxy of Synology redirects the traffic to the CentOS docker container

-> 81:<IP of SynologyNAS> (CentOS docker container)
The CentOS cocker container listens on this port, it will start the seafile container and redirect the traffic there
It will monitor open connections to the port, after 10 minutes without open connections it will shutdown the docker container.
This will be done by logging with ssh from docker container to Synology NAS IP and executing the appropriate command.

-> 82:<IP of SynologyNAS> (seafile docker container)
The seafile docker container listens on this port (internally port 80) will answer the request
 

remoh

Benutzer
Mitglied seit
06. Jan 2019
Beiträge
6
Punkte für Reaktionen
0
Punkte
0
What we need (Docker, two docker images, some Folders, SSH access to Diskstation, Reverse Proxy config, some scripts)
Docker:
Goto Package center and install "Docker"

Docker Images of CentOS with systemd and seafile:
Goto Packages Center -> Installed -> Docker -> Open -> Registry
search for "centos systemd", download "centos/systemd"
search for "centos systemd", download "seafileltd/seafile"

Create folder for docker container persistent data (i just took my folder path):
Goto File Station, create folders "replicated/docker/centos-systemd_seafile_control/shared"
Goto File Station, create folders "replicated/docker/seafile/shared"

We need to use ssh on synology, so we activate it and change to port 222 for security reasons:
Goto Control Panel -> Terminal & SNMP. Enable SSH service, port 222

In this case i use the Synology reverse proxy to have seafile available under port 80 and 443:
Goto Control Panel -> Application Portal -> Reverse Proxy -> Create
Description: seafile_https
Source
Protocol: HTTPS
Hostname: mydomain.com
Port: 443
Enable HSTS: disabled
Enable HTTP/2: disabled
Enable access control: disabled
Destination:
Protocol: HTTP
Hostname: <IP SynologyNAS>
Port: 81


Now we need to configure the seafile container:
I will not explain seafile itself here, refer to https://github.com/haiwen/seafile-docker
My config looks like this:
Goto Packages Center -> Installed -> Docker -> Open -> Image
Select seafileltd/seafile:latest -> click Launch
Container Name: seafile
Execute container using high privilege: disabled
Enable ressource limitation: disabled
Advanced Settings
Enable auto-restart: enabled
Create shortcut on desktop: disabled
Volume:
Add folder:
File/Folder: replicated/docker/seafile/shared Mount path: /shared
Port Settings
Local Port: 82 Container Port: 80
Links:
nothing
Environment
+
variable: SEAFILE_ADMIN_PASSWORD value: <choose your password>
+
variable: SEAFILE_ADMIN_EMAIL value: <choose your mailaddress>
+
variable: SEAFILE_SERVER_HOSTNAME value: <choose your domain, in this example mydomain.com, needs to be the one you use for access it in web browser>
Apply and run the container


Once you have seafile up and running and can connect to it (http://<IP of SynologyNAS>:82) we can set up the CentOS container:
Before setting up the container itself we need to create the necessary scripts that will do all the things to start and stop the seafile container.
Put them all in /volume1/replicated/docker/centos-systemd_seafile_control/shared
When finished there should be:
check_for_shutdown_seafile.sh
check_if_active.sh
seafile-docker.service
seafile-http.socket
seafile-http.service
start_docker.sh
stop_docker.sh
startup.sh
startup-sh.service

Replace all the things within the scripts marked with <blabla> with your settings

File name: check_for_shutdown_seafile.sh
This script will check for open connections and stop the container when time is up
Start content *******************
#!/bin/bash
#seconds until container should shut down after last open connections
sectowait=600

sleep 60
offline=0
while true; do
active=0
#check for active connections
if netstat -an | grep :81 | grep -v 0.0.0.0:81 > /dev/null
then
active=1
fi
#if netstat -an | grep :8080 | grep -v 0.0.0.0:8080 > /dev/null
#then
# active=1
#fi
if [ $active -eq 1 ]
then
#still active
offline=0
sleep 1
else
if [ $offline -eq 0 ]
then
i=0
#if no more connection is active, start to count up sconds to wait
while true; do
active=0
#check for active connections
if netstat -an | grep :81 | grep -v 0.0.0.0:81 > /dev/null
then
active=1
fi
#if netstat -an | grep :8080 | grep -v 0.0.0.0:8080 > /dev/null
#then
# active=1
#fi
#if an open connection is detected, stop counting
if [ $active -eq 1 ]
then
#still active
break
else
i=$((i+1))
sleep 1
fi
#if time to stop has been reached, stop docker and systemd service
if [ $i -eq $sectowait ]
then
/shared/stop_docker.sh
systemctl stop seafile-http.service
offline=1
break
fi
done
fi
sleep 1
fi
done
End content *********************


File name: check_if_active.sh
This script will check if the service is ready after startup of docker container.
It searches for the strin "input" (input field for login) in the html response, if it exists the service should be up
Start content *******************
#!/bin/bash
#max seconds to wait
sectowait=90
i=0
while true; do
if wget <IP of SynologyNAS>:81 -q -O - | grep input > /dev/null
then
exit 0
else
if [ $i -eq $sectowait ]
then
exit 0
fi
fi
sleep 1
i=$((i+1))
done
End content *********************


File name: seafile-docker.service
systemd service to start docker container seafile and the script which will not end until the service is up
Start content *******************
[Unit]
Description=seafile container

[Service]
ExecStart=/shared/start_docker.sh
ExecStartPost=/shared/check_if_active.sh
End content *********************


File name: seafile-http.socket
systemd file to open socket, this will only listen on the port and execute the correspondig service "seafile-http.service" on demand
Start content *******************
[Socket]
ListenStream=81

[Install]
WantedBy=sockets.target
End content *********************


File name: seafile-http.service
Service to start the systemd-socket-proxyd and the docker container by starting "seafile-docker.service"
Start content *******************
[Unit]
Requires=seafile-docker.service
After=seafile-docker.service

[Service]
ExecStart=/lib/systemd/systemd-socket-proxyd <IP of SynologyNAS>:82
End content *********************


File name: start_docker.sh
Script to start docker container
Start content *******************
#!/bin/sh
sshpass -p<your_synology_password> ssh -oStrictHostKeyChecking=no -p 222 <admin account of SynologyNAS, in my case admin>@<IP of SynologyNAS> "echo <your_synology_password> | sudo -S /usr/local/bin/docker start seafile"
exit 0
End content *********************


File name: stop_docker.sh
Script to start docker container
Start content *******************
#!/bin/sh
sshpass -p<your_synology_password> ssh -oStrictHostKeyChecking=no -p 222 <admin account of SynologyNAS, in my case admin>@<IP of SynologyNAS> "echo <your_synology_password> | sudo -S /usr/local/bin/docker stop seafile"
exit 0
End content *********************


File name: startup.sh
script will be executed on container startup. Installs necessary tools, copy files to target locations, start script to monitor ports
Start content *******************
#!/bin/bash
yum install -y sshpass openssh-clients net-tools wget
yes | cp /shared/seafile-http.socket /etc/systemd/system/
yes | cp /shared/seafile-http.service /etc/systemd/system/
yes | cp /shared/seafile-docker.service /etc/systemd/system/
systemctl enable seafile-http.socket
systemctl start seafile-http.socket
/shared/check_for_shutdown_seafile.sh
End content *********************


File name: startup-sh.service
systemd service file to execute startup script
Start content *******************
[Unit]
Description=startup script

[Service]
Type=simple
ExecStart=/shared/startup.sh

[Install]
WantedBy=default.target
End content *********************


We need to change the permissions of the files:
Login with ssh to your SynologyNAS
cd to
/volume1/replicated/docker/centos-systemd_seafile_control/shared
chmod 755 *
chmod 666 startup-sh.service


Now we can create the CentOS container:
Goto Packages Center -> Installed -> Docker -> Open -> Image
Select centos/systemd:latest -> click Launch
Container Name: centos-systemd_control_seafile
Execute container using high privilege: enabled
Enable ressource limitation: disabled
Advanced Settings
Enable auto-restart: enabled
Create shortcut on desktop: disabled
Volume:
Add folder:
File/Folder: replicated/docker/centos-systemd_control_seafile/shared Mount path: /shared
Add file:
File/Folder: replicated/docker/centos-systemd_control_seafile/shared/startup-sh.service Mount path: /etc/systemd/system/multi-user.target.wants/startup-sh.service
Port Settings
Local Port: 81 Container Port: 81
Links:
nothing
Environment
nothing
Apply and run the container

Thats it, the seafile container should now shutdown after 10 minutes of no access. If shutted down and you access it by opening https://mydomain.com the seafile container should startup and serve your request.
With these scripts as templates, other services could be set up to start on demand, too.
 

Arni

Benutzer
Mitglied seit
05. Okt 2012
Beiträge
405
Punkte für Reaktionen
4
Punkte
24
Nur eine Idee:
Es würde die Lesbarkeit deines Postes #2 erheblich verbessern, wenn du die Skripte mit der Formatierung [ CODE][ /CODE] umschließt.
 

remoh

Benutzer
Mitglied seit
06. Jan 2019
Beiträge
6
Punkte für Reaktionen
0
Punkte
0
Ja, gute Idee. Bei mir steht zwar unten das ich die Berechtigung habe Beiträge zu ändern, einen Button oder irgendwas anderes dazu habe ich aber nicht. Bin ich nur blind?
 

Arni

Benutzer
Mitglied seit
05. Okt 2012
Beiträge
405
Punkte für Reaktionen
4
Punkte
24
Meine mich dunkel daran zu erinnern, daß man dazu eine gewisse Anzahl an Beiträgen haben muß. Steht irgendwo in den Nutzungsbedingungen. Also einfach noch ein paar Thread wie oben und alles wird gut ;)
 

remoh

Benutzer
Mitglied seit
06. Jan 2019
Beiträge
6
Punkte für Reaktionen
0
Punkte
0
OK, dann mal schauen, vielleicht reicht ja diese Antwort :D
 

remoh

Benutzer
Mitglied seit
06. Jan 2019
Beiträge
6
Punkte für Reaktionen
0
Punkte
0
Da ich meine ersten Beiträge nicht bearbeiten kann sondern nur neuere, hier nochmal der zweite Post mit besserer Codedarstellung


What we need (Docker, two docker images, some Folders, SSH access to Diskstation, Reverse Proxy config, some scripts)
Docker:
Goto Package center and install "Docker"

Docker Images of CentOS with systemd and seafile:
Goto Packages Center -> Installed -> Docker -> Open -> Registry
search for "centos systemd", download "centos/systemd"
search for "centos systemd", download "seafileltd/seafile"

Create folder for docker container persistent data (i just took my folder path):
Goto File Station, create folders "replicated/docker/centos-systemd_seafile_control/shared"
Goto File Station, create folders "replicated/docker/seafile/shared"

We need to use ssh on synology, so we activate it and change to port 222 for security reasons:
Goto Control Panel -> Terminal & SNMP. Enable SSH service, port 222

In this case i use the Synology reverse proxy to have seafile available under port 80 and 443:
Goto Control Panel -> Application Portal -> Reverse Proxy -> Create
Description: seafile_https
Source
Protocol: HTTPS
Hostname: mydomain.com
Port: 443
Enable HSTS: disabled
Enable HTTP/2: disabled
Enable access control: disabled
Destination:
Protocol: HTTP
Hostname: <IP SynologyNAS>
Port: 81


Now we need to configure the seafile container:
I will not explain seafile itself here, refer to https://github.com/haiwen/seafile-docker
My config looks like this:
Goto Packages Center -> Installed -> Docker -> Open -> Image
Select seafileltd/seafile:latest -> click Launch
Container Name: seafile
Execute container using high privilege: disabled
Enable ressource limitation: disabled
Advanced Settings
Enable auto-restart: enabled
Create shortcut on desktop: disabled
Volume:
Add folder:
File/Folder: replicated/docker/seafile/shared Mount path: /shared
Port Settings
Local Port: 82 Container Port: 80
Links:
nothing
Environment
+
variable: SEAFILE_ADMIN_PASSWORD value: <choose your password>
+
variable: SEAFILE_ADMIN_EMAIL value: <choose your mailaddress>
+
variable: SEAFILE_SERVER_HOSTNAME value: <choose your domain, in this example mydomain.com, needs to be the one you use for access it in web browser>
Apply and run the container


Once you have seafile up and running and can connect to it (http://<IP of SynologyNAS>:82) we can set up the CentOS container:
Before setting up the container itself we need to create the necessary scripts that will do all the things to start and stop the seafile container.
Put them all in /volume1/replicated/docker/centos-systemd_seafile_control/shared
When finished there should be:
check_for_shutdown_seafile.sh
check_if_active.sh
seafile-docker.service
seafile-http.socket
seafile-http.service
start_docker.sh
stop_docker.sh
startup.sh
startup-sh.service

Replace all the things within the scripts marked with <blabla> with your settings

File name: check_for_shutdown_seafile.sh
This script will check for open connections and stop the container when time is up
Rich (BBCode):
#!/bin/bash
#seconds until container should shut down after last open connections
sectowait=600

sleep 60
offline=0
while true; do
 active=0
 #check for active connections
 if netstat -an | grep :81 | grep -v 0.0.0.0:81 > /dev/null
 then
  active=1
 fi
 #if netstat -an | grep :8080 | grep -v 0.0.0.0:8080 > /dev/null
 #then
 # active=1
 #fi
 if [ $active -eq 1 ]
 then
  #still active
  offline=0
  sleep 1
 else
  if [ $offline -eq 0 ]
  then
   i=0
   #if no more connection is active, start to count up sconds to wait
   while true; do
    active=0
	#check for active connections
    if netstat -an | grep :81 | grep -v 0.0.0.0:81 > /dev/null
    then
     active=1
    fi
    #if netstat -an | grep :8080 | grep -v 0.0.0.0:8080 > /dev/null
    #then
    # active=1
    #fi
	#if an open connection is detected, stop counting
    if [ $active -eq 1 ]
    then
     #still active
     break
    else
     i=$((i+1))
     sleep 1
    fi
	#if time to stop has been reached, stop docker and systemd service
    if [ $i -eq $sectowait ]
    then
     /shared/stop_docker.sh
     systemctl stop seafile-http.service
     offline=1
     break
    fi
   done
  fi
  sleep 1
 fi
done


File name: check_if_active.sh
This script will check if the service is ready after startup of docker container.
It searches for the strin "input" (input field for login) in the html response, if it exists the service should be up
Rich (BBCode):
#!/bin/bash
#max seconds to wait
sectowait=90
i=0
while true; do
 if wget <IP of SynologyNAS>:81 -q -O - | grep input > /dev/null
 then
  exit 0
 else
  if [ $i -eq $sectowait ]
  then
   exit 0
  fi
 fi
 sleep 1
 i=$((i+1))
done


File name: seafile-docker.service
systemd service to start docker container seafile and the script which will not end until the service is up
Rich (BBCode):
[Unit]
Description=seafile container

[Service]
ExecStart=/shared/start_docker.sh
ExecStartPost=/shared/check_if_active.sh


File name: seafile-http.socket
systemd file to open socket, this will only listen on the port and execute the correspondig service "seafile-http.service" on demand
Rich (BBCode):
[Socket]
ListenStream=81

[Install]
WantedBy=sockets.target


File name: seafile-http.service
Service to start the systemd-socket-proxyd and the docker container by starting "seafile-docker.service"
Rich (BBCode):
[Unit]
Requires=seafile-docker.service
After=seafile-docker.service

[Service]
ExecStart=/lib/systemd/systemd-socket-proxyd <IP of SynologyNAS>:82


File name: start_docker.sh
Script to start docker container
Rich (BBCode):
#!/bin/sh
sshpass -p<your_synology_password> ssh -oStrictHostKeyChecking=no -p 222 <admin account of SynologyNAS, in my case admin>@<IP of SynologyNAS> "echo <your_synology_password> | sudo -S /usr/local/bin/docker start seafile"
exit 0


File name: stop_docker.sh
Script to start docker container
Rich (BBCode):
#!/bin/sh
sshpass -p<your_synology_password> ssh -oStrictHostKeyChecking=no -p 222 <admin account of SynologyNAS, in my case admin>@<IP of SynologyNAS> "echo <your_synology_password> | sudo -S /usr/local/bin/docker stop seafile"
exit 0


File name: startup.sh
script will be executed on container startup. Installs necessary tools, copy files to target locations, start script to monitor ports
Rich (BBCode):
#!/bin/bash
yum install -y sshpass openssh-clients net-tools wget
yes | cp /shared/seafile-http.socket /etc/systemd/system/
yes | cp /shared/seafile-http.service /etc/systemd/system/
yes | cp /shared/seafile-docker.service /etc/systemd/system/
systemctl enable seafile-http.socket
systemctl start seafile-http.socket
/shared/check_for_shutdown_seafile.sh


File name: startup-sh.service
systemd service file to execute startup script
Rich (BBCode):
[Unit]
Description=startup script

[Service]
Type=simple
ExecStart=/shared/startup.sh

[Install]
WantedBy=default.target


We need to change the permissions of the files:
Login with ssh to your SynologyNAS
cd to
/volume1/replicated/docker/centos-systemd_seafile_control/shared
chmod 755 *
chmod 666 startup-sh.service


Now we can create the CentOS container:
Goto Packages Center -> Installed -> Docker -> Open -> Image
Select centos/systemd:latest -> click Launch
Container Name: centos-systemd_control_seafile
Execute container using high privilege: enabled
Enable ressource limitation: disabled
Advanced Settings
Enable auto-restart: enabled
Create shortcut on desktop: disabled
Volume:
Add folder:
File/Folder: replicated/docker/centos-systemd_control_seafile/shared Mount path: /shared
Add file:
File/Folder: replicated/docker/centos-systemd_control_seafile/shared/startup-sh.service Mount path: /etc/systemd/system/multi-user.target.wants/startup-sh.service
Port Settings
Local Port: 81 Container Port: 81
Links:
nothing
Environment
nothing
Apply and run the container

Thats it, the seafile container should now shutdown after 10 minutes of no access. If shutted down and you access it by opening https://mydomain.com the seafile container should startup and serve your request.
With these scripts as templates, other services could be set up to start on demand, too.
 
Zuletzt bearbeitet:

meschmesch

Benutzer
Mitglied seit
11. Mai 2010
Beiträge
42
Punkte für Reaktionen
0
Punkte
0
Hallo,
zunächst vielen Dank für die große Mühe!

Mein Problem ist, dass sobald ich den CentOS container gestartet habe alle anderen (x-beliebigen) Docker Container nicht mehr gestartet werden können und eine Fehlermeldung auftritt "Docker-API ist fehlgeschlagen". Weitere Infos im Protokoll. Im Protokoll findet sich dann aber nichts. Der Start über die Kommandozeile liefert irgend etwas in der Art, dass eine ID schon vorhanden ist. Die einzige Möglichkeit, die anderen Docker dann wieder zu starten ist den CentOS Container zu deaktiveren und anschließend einen Reboot des Systems zu machen (Das Docker-Moduls als solches zu deaktivieren und aktivieren reicht nicht aus).

Hat jemand eine Idee?
Danke und viele Grüße.
 

remoh

Benutzer
Mitglied seit
06. Jan 2019
Beiträge
6
Punkte für Reaktionen
0
Punkte
0
Ein Problem mit CentOS habe ich auch seit dem letzten oder vorletzten Synology update. Bei mir startet allerdings der CentOS container mit systemd nicht.
Habe dazu das hier gefunden (https://www.forum-nas.fr/viewtopic.php?t=4872&start=10), hilft mir erstmal:

sudo mkdir /sys/fs/cgroup/systemd
sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
 
Status
Für weitere Antworten geschlossen.
 

Kaffeautomat

Wenn du das Forum hilfreich findest oder uns unterstützen möchtest, dann gib uns doch einfach einen Kaffee aus.

Als Dankeschön schalten wir deinen Account werbefrei.

:coffee:

Hier gehts zum Kaffeeautomat