Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Docker

This folder is not a module of the project. It can be used in standalone.

Container Ship

Good article here.

  • First, get Docker on your system.
    On a Raspberry Pi, you can also try this:
    $ curl -sSL https://get.docker.com | sh
  • For a Raspberry Pi, also see here, and here.

To install Docker on Raspbian OS

  • sudo apt-get update && sudo apt-get upgrade
  • curl -fsSL https://get.docker.com -o get-docker.sh
  • sudo sh get-docker.sh
  • sudo usermod -aG docker [user_name, like pi]
  • newgrp docker

If problem on Buster, see https://www.raspberrypi.org/forums/viewtopic.php?t=273388

Then

  • docker version
  • docker info

To clean docker's cache (deep cleaning..., be careful):

$ docker system prune

To get started...

After installing Docker, try this:

 $ [sudo] docker run hello-world
 $ [sudo] docker run docker/whalesay cowsay Hello there!

This would tell you if your installation was successful.

Pre-defined Docker images

This project also provides a script that will build pre-defined Docker images (different OS's, with various features). Look into the script, the images are defined by the files *.Dockerfile.

Just run image.builder.sh (may require a sudo...):

 $ [sudo] ./image.builder.sh
+-------------- D O C K E R   I M A G E   B U I L D E R ---------------+
+------------------- Build and run a docker image. --------------------+
|  1. Nav Server, Debian                                               |
| 1p. Nav Server, Debian, with proxy                                   |
|  2. Web Components, Debian                                           |
|  3. To run on a Raspberry Pi, Java, Raspberry Coffee, Web Components |
|  4. Node PI, to run on a Raspberry Pi                                |
|  5. Node PI, to run on Debian                                        |
|  6. GPS-mux, to run on a Raspberry Pi (logger)                       |
|  7. Golang, basics                                                   |
|  8. Raspberry Pi, MATE, with java, node, web comps, VNC              |
|  9. Debian, Java, Scala, Spark                                       |
| 10. Ubuntu MATE, TensorFlow, Python3, VNC                            |
+----------------------------------------------------------------------+
| Q. Oops, nothing, thanks, let me out.                                |
+----------------------------------------------------------------------+
== You choose =>

This script takes care of building different docker images. docker commands can be pretty lengthy..., the script takes care of everything. Look into the script for details.

Let's go

docker's commands are described here.

Using image.builder.sh, choose option 1, it takes some time, the server is started by docker, and you can log on to the image if you want (it's not necessary):

$ docker run -it oliv-nav:latest /bin/bash
#     #
##    #    ##    #    #
# #   #   #  #   #    #
#  #  #  #    #  #    #
#   # #  ######  #    #
#    ##  #    #   #  #
#     #  #    #    ##

 #####
#     #  ######  #####   #    #  ######  #####
#        #       #    #  #    #  #       #    #
 #####   #####   #    #  #    #  #####   #    #
      #  #       #####   #    #  #       #####
#     #  #       #   #    #  #   #       #   #
 #####   ######  #    #    ##    ######  #    #

git version 2.11.0
node:v9.11.2
npm:5.6.0
openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-1~deb9u1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)
root@1d4ff153852b:/workdir/raspberry-coffee/RESTNavServer#

From the host (where the docker command was fired), reach for example http://localhost:8080/oplist

[{
"verb": "GET",
"path": "/oplist",
"description": "List of all available operations, on all request managers.",
"fn": {}
},
{
"verb": "GET",
"path": "/ww/composite-hierarchy",
"description": "Retrieve the list of the composites already available on the file system",
"fn": {}
},
{
"verb": "GET",
"path": "/astro/oplist",
"description": "List of all available operations, on astro request manager.",
"fn": {}
},
{
"verb": "GET",
"path": "/astro/positions-in-the-sky",
"description": "Get the Sun's and Moon's position (D & GHA) for an UTC date passed as QS prm named 'at', in DURATION Format. Optional: 'fromL' and 'fromG', 'wandering' (true|[false]).",
"fn": {}
},
{
"verb": "POST",
"path": "/astro/sun-now",
"description": "Create a request for Sun data now. Requires body payload (GeoPoint)",
"fn": {}
 ...

Yeah!

You can also reach http://localhost:8080/web/index.html from a browser.

From another shell:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
a335f585deb0        oliv-image          "/bin/bash"              36 minutes ago      Exited (0) 35 minutes ago                       confident_proskuriakova
f36550370ea8        445821efd8a0        "/bin/sh -c 'echo “g…"   44 minutes ago      Exited (2) 44 minutes ago                       affectionate_davinci

Get the CONTAINER ID like a335f585deb0

$ docker stop a335f585deb0

To drop the image:

$ docker rmi oliv-image

The scripts rm.container.sh and rm.images.sh are here to help...

Examples

$ docker build -f webcomponents.Dockerfile -t oliv-image .
$ docker run -p 8081:8080 -it oliv-image /bin/bash
root@7e754f8732a0:/workdir/WebComponents# node server.js

Then reach http://localhost:8081/oliv-components/index.html

etc, etc...

Note: there is an image published on docker-hub.
You can run docker run olivierlediouris/navserver from a Raspberry Pi, and you're all set.

Case Study

  • The case: You have a nodejs project you want to share with others.

The application reads GPS data through a Serial port, and feeds a WebSocket server. The data can then be visualized through a Web interface using Web Component(s).

To enable everything, you need to:

  1. Have a Raspberry Pi
  2. Flash its SD card and connect it to a network
  3. Install the required build tools
  4. Install git
  5. Install Node.js and npm
  6. Clone the right git repository, and its right branch
  7. Install all the required node modules
  8. Drill down into the right directory
  9. Start the right node server with the right script
  10. Access the Raspberry Pi from another machine on the same network, and reach the right HTML page.

This is certainly not difficult, but there are indeed many ways to do several mistakes at each step of the process.

In the list above, Docker can take care of the steps 3 to 9. It will build the image, and then run it. The image can also be pushed to a repository, so users would not have to build it. Just to run it after downloading it.

The only pre-requisite would be to have installed Docker on the machine (the Raspberry Pi here), as explained at the top of this document.

In this case, the full Docker image creation (named oliv-nodepi below) comes down to one command:

 $ docker build -f node-pi.Dockerfile -t oliv-nodepi .
Sending build context to Docker daemon  752.6kB
Step 1/20 : FROM resin/raspberrypi3-debian:latest
 ---> c542b8f7a388
Step 2/20 : MAINTAINER Olivier LeDiouris <olivier@lediouris.net>
 ---> Using cache
 ---> b2ff0d7c489f
Step 3/20 : ADD nodepi.banner.sh /
 ---> 535733298dd1
Step 4/20 : RUN echo "alias ll='ls -lisah'" >> $HOME/.bashrc
 ---> Running in 09baf7261a55
Removing intermediate container 09baf7261a55
 ---> 71e1e4c95663
Step 5/20 : RUN apt-get update
 ---> Running in 5d817a941a14
Get:1 http://security.debian.org jessie/updates InRelease [94.4 kB]
Get:2 http://archive.raspbian.org jessie InRelease [14.9 kB]
Get:3 http://archive.raspberrypi.org jessie InRelease [22.9 kB]

...

npm notice created a lockfile as package-lock.json. You should commit this file.
added 166 packages in 81.166s
Removing intermediate container 13986530db28
 ---> 051eb94b8a3c
Step 19/20 : EXPOSE 9876
 ---> Running in 67b587845fe0
Removing intermediate container 67b587845fe0
 ---> 46973b7ba9ac
Step 20/20 : CMD ["npm", "start"]
 ---> Running in 153bf2ea02ad
Removing intermediate container 153bf2ea02ad
 ---> 6bf3d76d38ae
Successfully built 6bf3d76d38ae
Successfully tagged oliv-nodepi:latest
ed9a7d9042dddd3939b1788cf0e89d16f5273192a6456266507f072f90ce91bc
 $

Once the step above is completed, plug in your GPS, and run (on the Raspberry Pi where docker is running, the one where the image built above is available)

 $ docker run -p 9876:9876 -t -i --privileged -v /dev/ttyUSB0:/dev/ttyUSB0 -d oliv-nodepi:latest

Then from a machine seeing the Raspberry Pi on its network (it can be the Raspberry Pi itself), reach http://raspi:9876/data/demos/gps.demo.wc.html in a browser.

Running

This shows you the position the GPS has computed, and the satellites in sight.

You can also login to the image:

 $ docker run -it oliv-nodepi:latest /bin/bash

#     #                                 ######    ###
##    #   ####   #####   ######         #     #    #
# #   #  #    #  #    #  #              #     #    #
#  #  #  #    #  #    #  #####   #####  ######     #
#   # #  #    #  #    #  #              #          #
#    ##  #    #  #    #  #              #          #
#     #   ####   #####   ######         #         ###

git version 2.1.4
node:v9.11.1
npm:5.6.0
root@b9679d0d65a7:/workdir/node.pi#

... and do whatever you like.

The build operation needs to be done only once. There is no need to do it again as long as no change in the image is required.

Stuff...

 $ CID=$(docker run -d oliv-go:latest)
 $ docker logs $CID
 Hello go world!
 $
Save, and re-use

Let's say you run a container, you make modifications to the hosted system, you exit, but you want to later on reconnect and find the modifications you did before.

You run a new container:

Terminal-1$ docker run --interactive --tty --rm --publish 5901:5901 --publish 8888:8888 --env USER=root --volume tensorflow:/root/workdir/shared oliv-tf-vnc:latest /bin/bash
git version 2.1.4
node:v9.11.1
npm:5.6.0
root@b9679d0d65a7:/workdir/docker#

And you make your modifications.

Still connected to the container above (you've not exited), from another terminal (on the machine where docker runs):

Terminal-2$ docker export --output myarchive.tar [CONTAINER-ID]

Then you can exit your docker session above.

root@b9679d0d65a7:/workdir/docker# exit

To restore your container:

Terminal-X$ docker import myarchive.tar restored:new

This creates a new docker image, named restored, with the label new. Then you

Terminal-X$ docker run -it --rm -p 5901:5901 -p 8888:8888 -e USER=root -v tensorflow:/root/workdir/shared restored:new /bin/bash

The docker image you're now on reflects the changes done before the container was exported.

If Docker.raw (on Mac OS) becomes too big...
 $ docker system prune

Docker reminder

To be able to save the state of a docker container, and then reuse it, you need to do the following:

  • Let's say you've run the commands above, to build the APEX instance
  • From the host, run a
 $ docker ps -a
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS                  PORTS                                              NAMES
20b372c88eb6        oracle/database:18.4.0-xe   "/bin/sh -c 'exec $O…"   23 hours ago        Up 23 hours (healthy)   0.0.0.0:51521->1521/tcp, 0.0.0.0:55500->5500/tcp   myxedb
 $
  • Then you can save the container state into a new image
 $ docker commit 20b372c88eb6 apex:2020-09-20
  • You can exit the docker session.
[oracle@73018a29f867 /]$ exit
  • To reuse the image, as it was when archived by the commit
$ docker run --name myxedb -d -p 51521:1521 -p 55500:5500 -e ORACLE_PWD=mysecurepassword -e ORACLE_CHARACTERSET=AL32UT apex:2020-09-20
  • Send a file to a running container
$ docker ps
CONTAINER ID   IMAGE                       COMMAND       CREATED         STATUS         PORTS                    NAMES
5ca873ab5074   oliv-devenv-ubuntu:latest   "/bin/bash"   5 minutes ago   Up 5 minutes   0.0.0.0:5901->5901/tcp   adoring_nobel
$ docker cp tides.zip 5ca873ab5074:~/tides.zip

The docker cp command can use Container ID, or name.

  • Connect to a running docker container
$ docker exec -it <container-id> bash
  • Stop a running container
$ docker stop <container-id> 

Docker Registry

At https://hub.docker.com/

To push an image to Docker Hub

  • docker tag de1ddc31533e olivierlediouris/navserver:latest (de1ddc31533e is the image-id, returned by docker images)
  • docker login --username olivierlediouris --password xxxxxx
  • docker push olivierlediouris/navserver:latest

The local image can then be removed, and it can now be run like

  • docker run olivierlediouris/navserver