Build container for 2.0.0rc2

This commit is contained in:
Ramon Bartl 2020-10-13 23:39:35 +02:00
parent ab27790cc2
commit 07259cb50a
No known key found for this signature in database
GPG key ID: 359669D35BDDF79B
7 changed files with 386 additions and 0 deletions

69
2.0.0rc2/Dockerfile Normal file
View file

@ -0,0 +1,69 @@
# Use an official Python runtime as a parent image
FROM python:2.7-stretch
# Set one or more individual labels
LABEL maintainer="Ramon Bartl"
LABEL email="rb@ridingbytes.com"
LABEL senaite.core.version="2.0.0rc2"
# Set environment variables
ENV PLONE_MAJOR=5.2 \
PLONE_VERSION=5.2.2 \
PLONE_MD5=a603eddfd3abb0528f0861472ebac934 \
PLONE_UNIFIED_INSTALLER=Plone-5.2.2-UnifiedInstaller \
SENAITE_HOME=/home/senaite \
SENAITE_USER=senaite \
SENAITE_INSTANCE_HOME=/home/senaite/senaitelims \
SENAITE_DATA=/data \
SENAITE_FILESTORAGE=/data/filestorage \
SENAITE_BLOBSTORAGE=/data/blobstorage
# Create the senaite user
RUN useradd --system -m -d $SENAITE_HOME -U -u 500 $SENAITE_USER
# Create direcotries
RUN mkdir -p $SENAITE_INSTANCE_HOME $SENAITE_FILESTORAGE $SENAITE_BLOBSTORAGE
# Copy the package config
COPY packages.txt /
# Install package dependencies
RUN apt-get update && apt-get install -y --no-install-recommends $(grep -vE "^\s*#" /packages.txt | tr "\n" " ")
# Fetch unified installer
RUN wget -O Plone.tgz https://launchpad.net/plone/$PLONE_MAJOR/$PLONE_VERSION/+download/$PLONE_UNIFIED_INSTALLER.tgz \
&& echo "$PLONE_MD5 Plone.tgz" | md5sum -c - \
&& tar -xzf Plone.tgz \
&& cp -rv /$PLONE_UNIFIED_INSTALLER/base_skeleton/* $SENAITE_INSTANCE_HOME \
&& cp -v /$PLONE_UNIFIED_INSTALLER/buildout_templates/buildout.cfg $SENAITE_INSTANCE_HOME/buildout-base.cfg \
&& cd $SENAITE_HOME \
&& rm -rf /$PLONE_UNIFIED_INSTALLER /Plone.tgz
# Change working directory
WORKDIR $SENAITE_INSTANCE_HOME
# Copy Buildout
COPY requirements.txt buildout.cfg ./
# Buildout
RUN pip install -r requirements.txt \
&& buildout \
&& ln -s $SENAITE_FILESTORAGE/ var/filestorage \
&& ln -s $SENAITE_BLOBSTORAGE/ var/blobstorage \
&& chown -R senaite:senaite $SENAITE_HOME $SENAITE_DATA
# Mount external volume
VOLUME /data
# Copy startup scripts
COPY docker-initialize.py docker-entrypoint.sh /
# Expose instance port
EXPOSE 8080
# Add instance healthcheck
HEALTHCHECK --interval=1m --timeout=5s --start-period=1m \
CMD nc -z -w5 127.0.0.1 8080 || exit 1
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["start"]

35
2.0.0rc2/buildout.cfg Normal file
View file

@ -0,0 +1,35 @@
[buildout]
extends =
buildout-base.cfg
extensions =
index = https://pypi.python.org/simple/
var-dir=/data
user=admin:admin
effective-user = senaite
buildout-user = senaite
eggs-directory=../buildout-cache/eggs
download-cache=../buildout-cache/downloads
parts +=
zeo
eggs +=
senaite.lims
[client1]
recipe =
[zeo]
<= zeoserver_base
recipe = plone.recipe.zeoserver
zeo-address = 8080
[versions]
setuptools=42.0.2
zc.buildout=2.13.3
senaite.lims=2.0.0rc2

View file

@ -0,0 +1,11 @@
version: "2"
services:
senaite:
image: senaite
volumes:
- data:/data
ports:
- "8080:8080"
volumes:
data:

56
2.0.0rc2/docker-entrypoint.sh Executable file
View file

@ -0,0 +1,56 @@
#!/bin/bash
set -e
COMMANDS="debug help logtail show stop adduser fg kill quit run wait console foreground logreopen reload shell status"
START="start restart zeoserver"
CMD="bin/instance"
gosu senaite python /docker-initialize.py
if [ -e "custom.cfg" ]; then
if [ ! -e "bin/develop" ]; then
gosu senaite /home/senaite/senaitelims/bin/buildout -c custom.cfg
gosu senaite python /docker-initialize.py
fi
fi
if [[ "$1" == "zeo"* ]]; then
CMD="bin/$1"
fi
if [ -z "$HEALTH_CHECK_TIMEOUT" ]; then
HEALTH_CHECK_TIMEOUT=1
fi
if [ -z "$HEALTH_CHECK_INTERVAL" ]; then
HEALTH_CHECK_INTERVAL=1
fi
if [[ $START == *"$1"* ]]; then
_stop() {
gosu senaite $CMD stop
kill -TERM $child 2>/dev/null
}
trap _stop SIGTERM SIGINT
gosu senaite $CMD start
gosu senaite $CMD logtail &
child=$!
pid=`$CMD status | sed 's/[^0-9]*//g'`
if [ ! -z "$pid" ]; then
echo "Application running on pid=$pid"
sleep "$HEALTH_CHECK_TIMEOUT"
while kill -0 "$pid" 2> /dev/null; do
sleep "$HEALTH_CHECK_INTERVAL"
done
else
echo "Application didn't start normally. Shutting down!"
_stop
fi
else
if [[ $COMMANDS == *"$1"* ]]; then
exec gosu senaite bin/instance "$@"
fi
exec "$@"
fi

184
2.0.0rc2/docker-initialize.py Executable file
View file

@ -0,0 +1,184 @@
#!/usr/local/bin/python
import re
import os
import warnings
warnings.simplefilter('always', DeprecationWarning)
class Environment(object):
""" Configure container via environment variables
"""
def __init__(
self,
env=os.environ,
zope_conf="/home/senaite/senaitelims/parts/instance/etc/zope.conf",
custom_conf="/home/senaite/senaitelims/custom.cfg",
zeopack_conf="/home/senaite/senaitelims/bin/zeopack",
zeoserver_conf="/home/senaite/senaitelims/parts/zeoserver/etc/zeo.conf"):
self.env = env
self.zope_conf = zope_conf
self.custom_conf = custom_conf
self.zeopack_conf = zeopack_conf
self.zeoserver_conf = zeoserver_conf
def zeoclient(self):
""" ZEO Client
"""
server = self.env.get("ZEO_ADDRESS", None)
if not server:
return
config = ""
with open(self.zope_conf, "r") as cfile:
config = cfile.read()
# Already initialized
if "<blobstorage>" not in config:
return
read_only = self.env.get("ZEO_READ_ONLY", "false")
zeo_ro_fallback = self.env.get("ZEO_CLIENT_READ_ONLY_FALLBACK", "false")
shared_blob_dir = self.env.get("ZEO_SHARED_BLOB_DIR", "off")
zeo_storage = self.env.get("ZEO_STORAGE", "1")
zeo_client_cache_size = self.env.get("ZEO_CLIENT_CACHE_SIZE", "128MB")
zeo_conf = ZEO_TEMPLATE.format(
zeo_address=server,
read_only=read_only,
zeo_client_read_only_fallback=zeo_ro_fallback,
shared_blob_dir=shared_blob_dir,
zeo_storage=zeo_storage,
zeo_client_cache_size=zeo_client_cache_size
)
pattern = re.compile(r"<blobstorage>.+</blobstorage>", re.DOTALL)
config = re.sub(pattern, zeo_conf, config)
with open(self.zope_conf, "w") as cfile:
cfile.write(config)
def zeopack(self):
""" ZEO Pack
"""
server = self.env.get("ZEO_ADDRESS", None)
if not server:
return
if ":" in server:
host, port = server.split(":")
else:
host, port = (server, "8100")
with open(self.zeopack_conf, 'r') as cfile:
text = cfile.read()
text = text.replace('address = "8100"', 'address = "%s"' % server)
text = text.replace('host = "127.0.0.1"', 'host = "%s"' % host)
text = text.replace('port = "8100"', 'port = "%s"' % port)
with open(self.zeopack_conf, 'w') as cfile:
cfile.write(text)
def zeoserver(self):
""" ZEO Server
"""
pack_keep_old = self.env.get("ZEO_PACK_KEEP_OLD", '')
if pack_keep_old.lower() in ("false", "no", "0", "n", "f"):
with open(self.zeoserver_conf, 'r') as cfile:
text = cfile.read()
if 'pack-keep-old' not in text:
text = text.replace(
'</filestorage>',
' pack-keep-old false\n</filestorage>'
)
with open(self.zeoserver_conf, 'w') as cfile:
cfile.write(text)
def buildout(self):
""" Buildout from environment variables
"""
# Already configured
if os.path.exists(self.custom_conf):
return
eggs = self.env.get("PLONE_ADDONS",
self.env.get("ADDONS", "")).strip().split()
if not eggs:
eggs = self.env.get("BUILDOUT_EGGS", "").strip().split()
if eggs:
warnings.warn(
"BUILDOUT_EGGS is deprecated. Please use "
"PLONE_ADDONS instead !!!", DeprecationWarning)
zcml = self.env.get("PLONE_ZCML",
self.env.get("ZCML", "")).strip().split()
if not zcml:
zcml = self.env.get("BUILDOUT_ZCML", "").strip().split()
if zcml:
warnings.warn(
"BUILDOUT_ZCML is deprecated. Please use "
"PLONE_ZCML instead !!!", DeprecationWarning)
develop = self.env.get("PLONE_DEVELOP",
self.env.get("DEVELOP", "")).strip().split()
if not develop:
develop = self.env.get("BUILDOUT_DEVELOP", "").strip().split()
if develop:
warnings.warn(
"BUILDOUT_DEVELOP is deprecated. Please use "
"PLONE_DEVELOP instead !!!", DeprecationWarning)
if not (eggs or zcml or develop):
return
buildout = BUILDOUT_TEMPLATE.format(
eggs="\n\t".join(eggs),
zcml="\n\t".join(zcml),
develop="\n\t".join(develop)
)
with open(self.custom_conf, 'w') as cfile:
cfile.write(buildout)
def setup(self, **kwargs):
self.buildout()
self.zeoclient()
self.zeopack()
self.zeoserver()
__call__ = setup
ZEO_TEMPLATE = """
<zeoclient>
read-only {read_only}
read-only-fallback {zeo_client_read_only_fallback}
blob-dir /data/blobstorage
shared-blob-dir {shared_blob_dir}
server {zeo_address}
storage {zeo_storage}
name zeostorage
var /home/senaite/senaitelims/parts/instance/var
cache-size {zeo_client_cache_size}
</zeoclient>
""".strip()
BUILDOUT_TEMPLATE = """
[buildout]
extends = develop.cfg
develop += {develop}
eggs += {eggs}
zcml += {zcml}
"""
def initialize():
""" Configure Plone instance as ZEO Client
"""
environment = Environment()
environment.setup()
if __name__ == "__main__":
initialize()

28
2.0.0rc2/packages.txt Normal file
View file

@ -0,0 +1,28 @@
dpkg-dev
gcc
gosu
libbz2-dev
libc6-dev
libcairo2
libffi-dev
libgdk-pixbuf2.0-0
libjpeg62
libjpeg62-turbo-dev
libopenjp2-7
libopenjp2-7-dev
libpango-1.0-0
libpangocairo-1.0-0
libpcre3-dev
libssl-dev
libtiff5
libtiff5-dev
libxml2
libxml2-dev
libxslt1-dev
libxslt1.1
lynx
netcat
rsync
wget
wv
zlib1g-dev

View file

@ -0,0 +1,3 @@
setuptools==42.0.2
zc.buildout==2.13.3
wheel