How to do custom docker image that has certain features disabled

Hi, I'm relatively new to Docker, and I would like to make a custom docker image of Kibana based on the official one, docker.elastic.co/kibana/kibana:6.2.4, that includes Canvas. My Dockerfile looks like:

FROM docker.elastic.co/kibana/kibana:6.2.4

RUN NODE_OPTIONS="--max-old-space-size=4096" ./bin/kibana-plugin install \
https://download.elastic.co/kibana/canvas/kibana-canvas-0.1.1949.zip

That's working nicely, but I'm still trying to take this a little bit further:

  1. Install canvas-extras plugin from a zip file
  2. Disable some unused x-pack features, such as graph and reporting

[1]. To enable part 1, I've created a build of canvas-extras and I'm copying the build file into my docker image, and trying to install the zip with kibana-plugin install

~/elastic-canvas/kibana-extra/canvas-extras(master|✔) % yarn run build
yarn run v1.6.0
$ plugin-helpers build
? What version of Kibana are you building for? 6.2.4
✨  Done in 8.53s.
mv build/canvas-extras-0.4.0.zip ~/elastic/elastic-stack-docker/kibana

Then I add the following to my Dockerfile:

COPY canvas-extras*.zip .

RUN NODE_OPTIONS="--max-old-space-size=4096" ./bin/kibana-plugin install \
file://${PWD}/$(ls canvas-extras*.zip)

Now, when I build, canvas-extras takes quite a long time to "Optimize and cache browser bundles" but eventually it exits with an error code:

Attempting to transfer from file:///usr/share/kibana/canvas-extras-0.4.0.zip
Transferring 9050519 bytes....................
Transfer complete
Retrieving metadata from plugin archive
Extracting plugin archive
Extraction complete
Optimizing and caching browser bundles...

The command '/bin/sh -c NODE_OPTIONS="--max-old-space-size=4096" ./bin/kibana-plugin install file://${PWD}/$(ls canvas-extras*.zip)' returned a non-zero code: 137

Am I right that returned a non-zero code: 137 means that kibana-plugin ran out of memory? I have given Docker 4G in Docker for Mac preferences, and I'm using the --max-old-space-size option whenever I install a plugin. Thinking that memory is the problem, I figure I probably need to disable some features of x-pack so that less code is re-bundled when plugin installer optimizes. That gets me to [2].

[2]. To disable some features of x-pack that I don't expect to use, I add some ENV lines to my Dockerfile. The entire file now looks like:

FROM docker.elastic.co/kibana/kibana:6.2.4

ENV XPACK_REPORTING_ENABLED false
ENV XPACK_GRAPH_ENABLED false

RUN NODE_OPTIONS="--max-old-space-size=4096" ./bin/kibana-plugin install \
https://download.elastic.co/kibana/canvas/kibana-canvas-0.1.1949.zip

COPY canvas-extras*.zip .

RUN NODE_OPTIONS="--max-old-space-size=4096" ./bin/kibana-plugin install \
file://${PWD}/$(ls canvas-extras*.zip)

Still, this leads to kibana-plugin install exiting with code 137. It really doesn't even seem to matter if I keep the canvas-extras plugin with the ENV lines in place. Say I comment out the last 3 lines of the Dockerfile and only have Canvas installed, the plugin installer exits with that error code.

So, does adding ENV to disable a UI feature in Kibana actually incur MORE memory usage by the plugin installer? Or am I doing something wrong here?

This is building for me with Docker natively on Linux.

What is happening is you're telling Node to use up to 4GB of memory, which it will do. Since your Docker VM is also set to 4GB your running into issues since there is also OS level overhead and the docker machine daemon.

I suggest removing setting max-old-space-size - it really shouldn't be necessary, or increase the memory limit for the Docker VM.

Thanks for that suggestion! Removing the max-old-space-size put me forwards and my image can build successfully now.

However, when I start a container with this image, Kibana kicks up another optimization cycle before it can fully start. The goal was to have all the optimization taken care of when building the image, so I'm a bit frustrated here.

You need to run Kibana - check out the Kibana docker template as an example: https://github.com/elastic/kibana-docker/blob/master/templates/Dockerfile.j2

Appending the following should accomplish what you're looking for.

USER kibana

CMD ["/usr/local/bin/kibana-docker"]

I've added that to my Dockerfile, so what I have now is:

FROM docker.elastic.co/kibana/kibana:6.2.4

ENV XPACK_GRAPH_ENABLED='false'
ENV XPACK_ML_ENABLED='false'
ENV XPACK_MONITORING_ENABLED='true'
ENV XPACK_REPORTING_ENABLED='false'
ENV XPACK_SECURITY_ENABLED='false'
ENV XPACK_WATCHER_ENABLED='false'

COPY canvas-extras*.zip .

RUN ./bin/kibana-plugin install https://download.elastic.co/kibana/canvas/kibana-canvas-0.1.1949.zip

RUN ./bin/kibana-plugin install file://${PWD}/$(ls canvas-extras*.zip)

USER kibana

CMD ["/usr/local/bin/kibana-docker"]

The image took some time to optimize when installing the plugins one by one. Right after it logged that the pointer was on CMD ["/usr/local/bin/kibana-docker"], the build exited successfully immediately, so I had some suspicions:

% docker build -t tsullivan/kibana-canvas-xpack-lite:6.2.4 .
Sending build context to Docker daemon   9.06MB
Step 1/12 : FROM docker.elastic.co/kibana/kibana:6.2.4
 ---> 327c6538ba4c
Step 2/12 : ENV XPACK_GRAPH_ENABLED='false'
 ---> Using cache
 ---> e6f60ba83ce4
Step 3/12 : ENV XPACK_ML_ENABLED='false'
 ---> Using cache
 ---> d1e1a76591bd
Step 4/12 : ENV XPACK_MONITORING_ENABLED='true'
 ---> Using cache
 ---> 363f7ab99e34
Step 5/12 : ENV XPACK_REPORTING_ENABLED='false'
 ---> Using cache
 ---> 1e99787271bc
Step 6/12 : ENV XPACK_SECURITY_ENABLED='false'
 ---> Using cache
 ---> 7972f146262e
Step 7/12 : ENV XPACK_WATCHER_ENABLED='false'
 ---> Using cache
 ---> a733c1e0e64e
Step 8/12 : COPY canvas-extras*.zip .
 ---> 7f0bd1617663
Step 9/12 : RUN ./bin/kibana-plugin install https://download.elastic.co/kibana/canvas/kibana-canvas-0.1.1949.zip
 ---> Running in a2e6c619c788
Attempting to transfer from https://download.elastic.co/kibana/canvas/kibana-canvas-0.1.1949.zip
Transferring 13108504 bytes....................
Transfer complete
Retrieving metadata from plugin archive
Extracting plugin archive
Extraction complete
Optimizing and caching browser bundles...
Plugin installation complete
Removing intermediate container a2e6c619c788
 ---> ca994e35c0da
Step 10/12 : RUN ./bin/kibana-plugin install file://${PWD}/$(ls canvas-extras*.zip)
 ---> Running in 04bd941ddb9a
Attempting to transfer from file:///usr/share/kibana/canvas-extras-0.4.0.zip
Transferring 9050519 bytes....................
Transfer complete
Retrieving metadata from plugin archive
Extracting plugin archive
Extraction complete
Optimizing and caching browser bundles...
Plugin installation complete
Removing intermediate container 04bd941ddb9a
 ---> 76e920ce245e
Step 11/12 : USER kibana
 ---> Running in 57978384ca8c
Removing intermediate container 57978384ca8c
 ---> 1762eb6672db
Step 12/12 : CMD ["/usr/local/bin/kibana-docker"]
 ---> Running in ba8b29e11860
Removing intermediate container ba8b29e11860
 ---> 6fd7e0a33fcb
Successfully built 6fd7e0a33fcb
Successfully tagged tsullivan/kibana-canvas-xpack-lite:6.2.4

I brought up containers in the compose file, then looked at what Kibana was doing:

~/elastic/elastic-stack-docker(add-canvas-extras↑4|✔) % docker-compose up -d
Creating network "elastic-stack-docker_default" with the default driver
Creating my-es1               ... done
Creating my-es-proxy          ... done
Creating my-logstash-avocados ... done
Creating my-kibana            ... done
Creating my-apm1              ... done
Creating my-chatbot           ... done
Creating my-web               ... done
~/elastic/elastic-stack-docker(add-canvas-extras↑4|✔) % docker-compose logs -f kibana
Attaching to my-kibana
my-kibana        | {"type":"log","@timestamp":"2018-05-16T16:50:03Z","tags":["info","optimize"],"pid":1,"message":"Optimizing and caching bundles for stateSessionStorageRedirect, status_page, timelion, canvas, monitoring, dashboardViewer, apm and kibana. This may take a few minutes"}

So adding the CMD didn't seem to result in an image that is built with optimization done. 🤷

Looks like this issue is what this feature request is about: https://github.com/elastic/kibana/issues/6057, that seems like it would be a really helpful addition.

I think I have what I need now. I waited for the optimization to finish in the container (5 1/2 minutes) and then used docker commit to create a new image. When I restarted everything in my docker-compose file, Kibana started up and was ready as soon as Elasticsearch was.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.