<<TableOfContents(2)>> = Docker = Docker is an open platform for developers and sysadmins to build, ship, and run distributed applications. http://www.zdnet.com/article/what-is-docker-and-why-is-it-so-darn-popular/ Developers can use Docker to pack, ship, and run any application as a lightweight, portable, self sufficient LXC container that can run virtually anywhere. In a nutshell, here's what Docker can do for you: It can get more applications running on the same hardware than other technologies; it makes it easy for developers to quickly create, ready-to-run containered applications; and it makes managing and deploying applications much easier. http://en.wikipedia.org/wiki/LXC LXC (Linux Containers) is an operating system–level virtualization method for running multiple isolated Linux systems (containers) on a single control host. LXC provides operating system-level virtualization through a virtual environment that has its own process and network space, instead of creating a full-fledged virtual machine. == Tutorial == https://www.docker.com/tryit https://hub.docker.com/ https://docs.docker.com/installation https://docs.docker.com/articles/basics/ == Windows install == https://docs.docker.com/installation/windows/ The Docker Engine uses Linux-specific kernel features, so to run it on Windows we need to use a lightweight virtual machine (vm). == Hello world == {{{#!highlight sh docker run hello-world }}} == Docker SSH container Ubuntu == https://docs.docker.com/examples/running_ssh_service/ In bootDocker create ~/ssh/Dockerfile : {{{#!highlight sh # sshd # # VERSION 0.0.2 FROM ubuntu:14.04 MAINTAINER Sven Dowideit <SvenDowideit@docker.com> RUN apt-get update && apt-get install -y openssh-server RUN mkdir /var/run/sshd RUN echo 'root:screencast' | chpasswd RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"] }}} {{{#!highlight sh docker build -t eg_sshd . docker run -d -P --name test_sshd eg_sshd docker ps -l ssh root@127.0.0.1 -p49153 # password screencast sudo docker stop test_sshd # stop container test_sshd }}} == Install jdk8 in trusty == {{{#!highlight sh apt-get install software-properties-common add-apt-repository ppa:openjdk-r/ppa -y apt-get update apt-get install openjdk-8-jdk }}} Dockerfile {{{#!highlight sh FROM ubuntu:14.04 RUN apt-get update && \ apt-get install -y traceroute openssh-server software-properties-common mongodb rabbitmq-server && \ add-apt-repository ppa:openjdk-r/ppa -y && \ apt-get update && \ apt-get install -y openjdk-8-jdk RUN mkdir /var/run/sshd RUN echo 'root:12345678' | chpasswd RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile EXPOSE 22 8080 8081 8082 5672 15672 27017 80 CMD ["/usr/sbin/sshd", "-D"] }}} == Install Docker CE slack 64 14.2 == * https://slackbuilds.org/repository/14.2/system/docker/ === Install go lang === {{{#!highlight sh cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/development/google-go-lang.tar.gz tar xvzf google-go-lang.tar.gz cd google-go-lang wget https://storage.googleapis.com/golang/go1.10.1.src.tar.gz # change slackbuild to use 1.10.1 ./google-go-lang.SlackBuild # installpkg /tmp/google-go-lang-1.9.5-x86_64-1_SBo.tgz go --version # In ~/.bashrc export GOPATH="$HOME:/usr/share/gocode" go help buildmode go get golang.org/x/tools/cmd/godoc # remove support to gcc-go ! /usr/lib64/go1.10.1/go/bin/ /usr/lib64/go1.10.1/go/bin/go version # in ~/.bashrc export PATH="$PATH:/usr/lib64/go1.10.1/go/bin/" }}} === Install docker-proxy === {{{#!highlight sh cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/system/docker-proxy.tar.gz tar xvzf docker-proxy.tar.gz cd docker-proxy wget https://github.com/docker/libnetwork/archive/1b91bc9/libnetwork-1b91bc94094ecfdae41daa465cc0c8df37dfb3dd.tar.gz ./docker-proxy.SlackBuild installpkg /tmp/docker-proxy-20180314_1b91bc9-x86_64-1_SBo.tgz }}} === Install tini === {{{#!highlight sh cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/system/tini.tar.gz tar xvzf tini.tar.gz cd tini wget https://github.com/krallin/tini/archive/949e6fa/tini-949e6facb77383876aeff8a6944dde66b3089574.tar.gz ./tini.SlackBuild installpkg /tmp/tini-0.13.0_949e6fa-x86_64-1_SBo.tgz }}} === Install libseccomp === {{{#!highlight sh cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/libraries/libseccomp.tar.gz tar xvzf libseccomp.tar.gz cd libseccomp wget https://github.com/seccomp/libseccomp/archive/v2.3.3/libseccomp-2.3.3.tar.gz ./libseccomp.SlackBuild installpkg /tmp/libseccomp-2.3.3-x86_64-1_SBo.tgz }}} === Install runc === {{{#!highlight sh cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/system/runc.tar.gz tar xvzf runc.tar.gz cd runc wget https://github.com/opencontainers/runc/archive/v1.0.0-rc5/runc-1.0.0-rc5.tar.gz ./runc.SlackBuild installpkg /tmp/runc-1.0.0_rc5-x86_64-1_SBo.tgz }}} === Install containerd === {{{#!highlight sh cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/system/containerd.tar.gz tar xvzf containerd.tar.gz cd containerd wget https://github.com/containerd/containerd/archive/v1.0.2/containerd-1.0.2.tar.gz ./containerd.SlackBuild installpkg /tmp/containerd-1.0.2-x86_64-1_SBo.tgz }}} === Install docker === {{{#!highlight sh cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/system/docker.tar.gz tar xvzf docker.tar.gz cd docker wget https://github.com/docker/docker-ce/archive/v18.03.0-ce/docker-ce-18.03.0-ce.tar.gz ./docker.SlackBuild installpkg /tmp/docker-18.03.0-x86_64-1_SBo.tgz # Added option --userland-proxy=false in /etc/rc.d/rc.docker variable DOCKER_OPTS="--userland-proxy=false" cd /etc/rc.d sh rc.docker status sh rc.docker start }}} == Docker image with SSH Ubuntu Xenial 16.04 == Adapted from https://docs.docker.com/engine/examples/running_ssh_service/ Dockerfile: {{{#!highlight sh # https://docs.docker.com/engine/examples/running_ssh_service/ FROM ubuntu:16.04 RUN apt-get update && apt-get install -y openssh-server RUN mkdir /var/run/sshd RUN echo 'root:screencast' | chpasswd RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile RUN useradd userx RUN echo 'userx:userx' | chpasswd EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"] }}} Steps: {{{#!highlight sh docker build -t docker_test . docker run -d -P --name test_container1 docker_test docker ps -a ssh root@127.0.0.1 -p32771 useradd userx echo 'userx:userx' | chpasswd ssh userx@127.0.0.1 -p32771 docker exec -it test_container1 /bin/bash docker container stop test_container1 docker container rm test_container1 docker image rm docker_test }}} == Install Docker in Ubuntu Xenial (16.04.4) vagrant box == {{{#!highlight sh mkdir tmp cd tmp vagrant init ubuntu/xenial64 vagrant up vagrant ssh # inside the box with user vagrant sudo bash apt-get update apt-get install apt-transport-https ca-certificates curl software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - apt-key fingerprint 0EBFCD88 add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" apt-get update apt-get install docker-ce docker run hello-world usermod -aG docker exit exit #login again with vagrant ssh # as user vagrant docker run hello-world # install java and maven apt-get install openjdk-8-jdk apt-get install maven }}} == Commands == {{{#!highlight sh docker ps -a # showall containers # clean system including volumes without asking for permission docker system prune -a -f --volumes docker ps -a | awk '//{print $1}' | grep -v "CONTAINER" | xargs -i sh -c 'docker stop {};docker rm {}' # clear all containers docker build -t acme_app . # build image from docker file docker run -P -p 8080:80 -d acme_app # run dettached container from image acme_app mapping port 8080 to port exposed 80 }}} == Docker DNS server == * https://docs.docker.com/v17.09/engine/userguide/networking/configure-dns/ {{{ As of Docker 1.10, the docker daemon implements an embedded DNS server which provides built-in service discovery for any container created with a valid name or net-alias or aliased by link. So you should not assume the way the files such as /etc/hosts, /etc/resolv.conf are managed inside the containers and leave the files alone and use the following Docker options instead. Note: The DNS server is always at 127.0.0.11. }}} == Docker container based on GCC image == {{{#!highlight sh docker run -it gcc /bin/bash docer ps -a docker exec -it <container> /bin/bash # inside container cat /etc/os-release apt-get update }}} == Docker playground - cherrypy == * https://www.katacoda.com/courses/docker/playground === Dockerfile === {{{#!highlight sh # docker build -t image_cherrypy . # build image from Dockerfile # docker run -P -p 8080:80 -d image_cherrypy # touch cherrypytest.wsgi # links http://localhost/add/3/4 # curl -X POST -d "{\"name\":\"jkl\"}" http://localhost/hellojson --header "Content-Type:application/json" # curl -X POST -d "{\"name\":\"jkl\"}" http://localhost:1234/hellojson --header "Content-Type:application/json" FROM ubuntu:16.04 RUN apt-get update && apt-get install -y python libapache2-mod-wsgi apache2 vim links net-tools nano curl wget RUN wget https://pypi.python.org/packages/source/C/CherryPy/CherryPy-3.2.4.tar.gz RUN cp CherryPy-3.2.4.tar.gz /tmp RUN cd /tmp && tar xvzf CherryPy-3.2.4.tar.gz RUN cd /tmp/CherryPy-3.2.4 && python setup.py build && python setup.py install RUN mkdir -p /var/www/htdocs/cherrypytest/static # copy cherrypytest.wsgi from where the Dockerfile is COPY cherrypytest.wsgi /var/www/htdocs/cherrypytest/cherrypytest.wsgi RUN echo "Static Test" > /var/www/htdocs/cherrypytest/static/a.txt RUN echo "<VirtualHost *:80>\nServerName localhost\nDocumentRoot \"/var/www/htdocs/cherrypytest\"\nWSGIScriptAlias / /var/www/htdocs/cherrypytest/cherrypytest.wsgi\n<Directory \"/var/www/htdocs/cherrypytest\">\nRequire all granted\n</Directory>\n</VirtualHost>" > /etc/apache2/sites-available/000-default.conf RUN echo "#!/bin/sh\n service apache2 start \n tail -f /var/log/apache2/error.log" > /start.sh EXPOSE 80 CMD ["sh","/start.sh"] }}} === cherrypytest.wsgi === {{{#!highlight python import sys sys.stdout = sys.stderr import cherrypy cherrypy.config.update({'environment': 'embedded'}) class HelloWorld(object): @cherrypy.expose def index(self): return "Hello World CherryPy!!!!" @cherrypy.expose def add(self,param1,param2): # curl "http://localhost:1234/add/2/100" # curl "http://localhost:1234/add?param1=2¶m2=100" print "Called add" return str( int(param1)+int(param2) ) @cherrypy.expose @cherrypy.tools.json_in() @cherrypy.tools.json_out() def hellojson(self): # curl -X POST -d "{\"name\":\"jkl\"}" http://localhostcherrypytest/hellojson --header "Content-Type:application/json" # curl -X POST -d "{\"name\":\"jkl\"}" http://localhost:1234/hellojson --header "Content-Type:application/json" inj = cherrypy.request.json return {"message": "hello world " + inj['name'] } hello = HelloWorld() #static dir confx={'/static': {'tools.staticdir.on':True , 'tools.staticdir.dir':'/var/www/htdocs/cherrypytest/static' }} application = cherrypy.Application(hello, script_name=None, config=confx) }}} === Execute === {{{#!highlight sh docker build -t docker-cherrypy-image . docker run -it -P --rm --name docker-cherrypy-container docker-cherrypy-image docker ps docker exec -it docker-cherrypy-container bash # in container curl -vv localhost docker run -it -p 1234:80 --rm --name docker-cherrypy-container docker-cherrypy-image curl -vv localhost:1234 }}} == Docker - openjdk8 - hello == === Main.java === {{{#!highlight java //Main.java public class Main{ public static void main(String args[]){ System.out.println("Hello docker!"); } } }}} === Dockerfile === {{{#!highlight sh FROM openjdk:8-alpine RUN mkdir -p /usr/src/hello_docker COPY . /usr/src/hello_docker WORKDIR /usr/src/hello_docker RUN javac Main.java CMD ["java", "Main"] }}} === Execute === {{{#!highlight sh # build image hello-docker-image using Dockerfile docker build -t hello-docker-image . # run the container based on the image docker run -it --rm --name hello-docker hello-docker-image }}} == Docker - openjdk 8 - hello - maven == * mkdir -p src/main/java/com/example/artifactX === pom.xml === {{{#!highlight xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>artifactX</artifactId> <packaging>jar</packaging> <version>0.0.1</version> <name>artifactX</name> <url>http://maven.apache.org</url> <build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.4</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.example.artifactX.Main</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies> </dependencies> </project> }}} === src/main/java/com/example/artifactX/Main.java === {{{#!highlight java package com.example.artifactX; //Main.java public class Main{ public static void main(String args[]){ System.out.println("Hello docker!"); } } }}} === Dockerfile === {{{#!highlight sh FROM openjdk:8-alpine RUN apk add maven RUN mkdir -p /usr/src/hello_maven_docker COPY . /usr/src/hello_maven_docker WORKDIR /usr/src/hello_maven_docker RUN mvn clean install CMD ["java", "-jar" , "target/artifactX-0.0.1-jar-with-dependencies.jar"] }}} === Execute === {{{#!highlight sh docker build -t hello-maven-docker-image . docker run -it --rm --name hello-maven-docker hello-maven-docker-image }}} == docker - maven - springboot-test == {{{#!highlight sh touch Dockerfile touch pom.xml mkdir -p src/main/java/hello/ mkdir -p src/main/resources/templates/ touch src/main/java/hello/GreetingController.java touch src/main/java/hello/Application.java touch src/main/java/hello/ThreadTimer.java touch src/main/java/hello/WaitThread.java touch src/main/java/hello/Dummy.java touch src/main/resources/templates/greeting.html touch src/main/resources/application.properties touch src/main/resources/logback-spring.xml mvn clean install java -Dfilelog=/tmp/out.log -jar target/test-spring-boot-0.1.0.jar # http://localhost:8080/greeting }}} === Dockerfile === {{{#!highlight sh FROM openjdk:8-alpine RUN apk add maven RUN mkdir -p /usr/src/hello_springboot_docker COPY . /usr/src/hello_springboot_docker WORKDIR /usr/src/hello_springboot_docker RUN mvn clean install CMD ["java","-Dfilelog=/tmp/out.log","-jar","target/test-spring-boot-0.1.0.jar"] }}} === pom.xml === {{{#!highlight xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>hello</groupId> <artifactId>test-spring-boot</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> <properties> <start-class>hello.Application</start-class> </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestone</id> <url>http://repo.spring.io/libs-release</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-milestone</id> <url>http://repo.spring.io/libs-release</url> </pluginRepository> </pluginRepositories> </project> }}} === src/main/java/hello/GreetingController.java === {{{#!highlight java package hello; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; import java.util.ArrayList; @Controller public class GreetingController { private final Logger logger = LoggerFactory.getLogger(GreetingController.class); public GreetingController(){ logger.debug("Greeting controller created."); } @RequestMapping("/greeting") // http://localhost:8080/greeting?name=nnnn public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) { logger.info("Greeting endpoint called."); model.addAttribute("name", name); return "greeting"; } @RequestMapping(value="/dummy",produces="application/json") @ResponseBody // http://localhost:8080/dummy public List<Dummy> dummy(){ List<Dummy> list= new java.util.ArrayList<Dummy>(); Dummy dummy = new Dummy(); dummy.setFieldA("AAA"); dummy.setFieldB("CCC"); list.add(dummy); Dummy dummy2 = new Dummy(); dummy2.setFieldA("AAA2"); dummy2.setFieldB("CCC2"); list.add(dummy2); return list; } } }}} === src/main/java/hello/Application.java === {{{#!highlight java package hello; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Bean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ComponentScan @EnableAutoConfiguration public class Application { private static Logger logger; public static void main(String[] args) { logger = LoggerFactory.getLogger(Application.class); logger.info("Starting application"); SpringApplication.run(Application.class, args); } } }}} === src/main/java/hello/ThreadTimer.java === {{{#!highlight java package hello; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import java.text.MessageFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; @Component public class ThreadTimer extends Thread { private int delaySeconds; private Logger logger; private boolean running; private Object monitor=new Object(); private ArrayList<Object> subscribers; //@Autowired //WaitThread waitThread; public ThreadTimer() { this.logger = LoggerFactory.getLogger(ThreadTimer.class); logger.info("Created instance of " + this.getClass().getSimpleName()); this.running = true; this.delaySeconds = 5 * 1000; this.setName(this.getClass().getSimpleName() + "_" + this.getName()); this.subscribers = new ArrayList<Object>(); } public void addSubscriber(Object subscriber){ this.subscribers.add(subscriber); } @PostConstruct public void init() { logger.info("Starting the thread"); this.start(); } @Override public void run() { while (running) { try { Thread.sleep(this.delaySeconds); logger.info("Delay " + this.getClass().getSimpleName()); for(Object o: this.subscribers){ synchronized(o){ o.notify(); } } } catch (InterruptedException e) { logger.info("ThreadTimer interrupted exception:" + e.getMessage() ); } catch (Exception e) { e.printStackTrace(); logger.info("ThreadTimer exception:" + e.getMessage() ); stopRunning(); } } logger.info("Exited " + this.getClass().getSimpleName()); } public void startRunning() { this.running = true; } public void stopRunning() { this.running = false; } public void destroy(){ logger.info("Called destroy"); this.stopRunning(); this.interrupt(); } } }}} === src/main/java/hello/WaitThread.java === {{{#!highlight java package hello; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.text.MessageFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @Component public class WaitThread extends Thread { private Logger logger; private boolean running; private Object monitor; @Autowired ThreadTimer timerThread; public WaitThread() { this.logger = LoggerFactory.getLogger(WaitThread.class); logger.info("Created instance of " + this.getClass().getSimpleName()); this.running = true; this.setName(this.getClass().getSimpleName() + "_" + this.getName()); this.monitor=new Object(); } @PostConstruct public void init() { this.timerThread.addSubscriber(this); logger.info("Starting the thread"); this.start(); } public void run() { while (running) { try { synchronized(this){ this.wait(); logger.info("Notification received."); } } catch (InterruptedException e) { logger.info("ThreadTimer interrupted exception:" + e.getMessage() ); } catch (Exception e) { logger.info("WaitThread exception:" + e.getMessage() ); stopRunning(); } } logger.info("Exited " + this.getClass().getSimpleName()); } public void startRunning() { this.running = true; } public void stopRunning() { this.running = false; } public void destroy(){ logger.info("Called destroy"); this.stopRunning(); this.interrupt(); } } }}} === src/main/java/hello/Dummy.java === {{{#!highlight java package hello; public class Dummy{ private String fieldA; private String fieldB; public Dummy(){ } public String getFieldA(){ return fieldA; } public String getFieldB(){ return fieldB; } public void setFieldA(String arg){ fieldA = arg; } public void setFieldB(String arg){ fieldB = arg; } } }}} === src/main/resources/templates/greeting.html === {{{#!highlight xml <!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Getting Started: Serving Web Content</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p th:text="'Hello, ' + ${name} + '!'" /> </body> </html> }}} === src/main/resources/application.properties === {{{#!highlight sh logging.file=/tmp/testout.log }}} === src/main/resources/logback-spring.xml === {{{#!highlight xml <?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/> <include resource="org/springframework/boot/logging/logback/file-appender.xml" /> --> <!-- override spring logback default behaviour --> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>${filelog}</file> <encoder> <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <appender name="GREETFILE" class="ch.qos.logback.core.FileAppender"> <file>/tmp/greet.log</file> <encoder> <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%yellow(%date{ISO8601}) %green([%thread]) %highlight(%-5level) %cyan(%logger{35}) - %white(%msg%n) </Pattern> </layout> </appender> <root level="INFO"> <appender-ref ref="FILE" /> <appender-ref ref="CONSOLE"/> </root> <logger name="hello.GreetingController" level="debug" additivity="false"> <appender-ref ref="GREETFILE"/> <appender-ref ref="CONSOLE" /> </logger> </configuration> }}} === Execute === * docker build -t hello-springboot-docker-image . * docker run -P -p 8080:8080 --name hello-springboot-docker -d hello-springboot-docker-image * docker ps * docker exec -it 5ea9eaff4616 /bin/ash * docker exec -it 5ea9eaff4616 /bin/sh * curl http://localhost:8080/greeting * curl http://localhost:8080/greeting?name=asdf * curl http://localhost:8080/dummy == Docker registry == * https://hub.docker.com/_/registry {{{#!highlight bash # local registry CONTAINER_NAME=registry IMAGE_NAME=registry:2 docker run -d -p 5000:5000 --restart always --name $CONTAINER_NAME $IMAGE_NAME }}} * Check images catalog in registry * http://hostx:5000/v2/_catalog * http://hostx:5000/v2/image/tags/list == Bind mount == * https://docs.docker.com/storage/bind-mounts/ When you use a bind mount, a file or directory on the host machine is mounted into a container. {{{#!highlight sh docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app \ nginx:latest }}} == Install docker in nb200 (32 bit) == {{{#!highlight sh # install go cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/development/google-go-lang.tar.gz tar xvzf google-go-lang.tar.gz cd google-go-lang wget https://storage.googleapis.com/golang/go1.11.13.src.tar.gz nano google-go-lang.SlackBuild ./google-go-lang.SlackBuild installpkg /tmp/google-go-lang-1.11.13-i586-1_SBo.tgz go --version nano ~/.bashrc go --version source . source ~/.bashrc go --version /usr/lib/go1.11.13/go/bin/go --version /usr/lib/go1.11.13/go/bin/go version go version nano ~/.bashrc source ~/.bashrc go version echo $PATH nano ~/.bashrc exit go version which go go help buildmode echo $PATH cat /root/.bashrc export PATH="$PATH:/usr/lib64/go1.11.13/go/bin/" go help buildmode go version echo $PATH go version removepkg gcc-go-5.5.0-i586-1_slack14.2 go version echo $PATH nano ~/.bashrc source ~/.bashrc go version cat ~/.bashrc # install docker proxy cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/system/docker-proxy.tar.gz tar xvzf docker-proxy.tar.gz cd docker-proxy wget https://github.com/docker/libnetwork/archive/2cfbf9b/libnetwork-2cfbf9b1f98162a55829a21cc603c76072a75382.tar.gz ./docker-proxy.SlackBuild installpkg/tmp/docker-proxy-20181207_2cfbf9b-i586-1_SBo.tgz # install tini cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/system/tini.tar.gz tar xvzf tini.tar.gz cd tini wget https://github.com/krallin/tini/archive/v0.18.0/tini-0.18.0.tar.gz ./tini.SlackBuild installpkg/tmp/tini-0.18.0-i586-1_SBo.tgz # install libseccomp cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/libraries/libseccomp.tar.gz tar xvzf libseccomp.tar.gz cd libseccomp wget https://github.com/seccomp/libseccomp/archive/v2.4.2/libseccomp-2.4.2.tar.gz ./libseccomp.SlackBuild installpkg/tmp/libseccomp-2.4.2-i586-1_SBo.tgz # install runc cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/system/runc.tar.gz tar xvzf runc.tar.gz cd runc wget https://github.com/opencontainers/runc/archive/8084f76/runc-8084f7611e4677174c8dbeb17152f3390fa41952.tar.gz ./runc.SlackBuild installpkg /tmp/runc-1.0.0_rc6_8084f76-i586-1_SBo.tgz # install containerd cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/system/containerd.tar.gz tar xvzf containerd.tar.gz cd containerd wget https://github.com/containerd/containerd/archive/v1.2.4/containerd-1.2.4.tar.gz ./containerd.SlackBuild installpkg/tmp/containerd-1.2.4-i586-1_SBo.tgz # install docker cd /tmp wget https://slackbuilds.org/slackbuilds/14.2/system/docker.tar.gz tar xvzf docker.tar.gz cd docker wget https://github.com/docker/docker-ce/archive/v18.09.2/docker-ce-18.09.2.tar.gz vi docker.SlackBuild # change to docker-linux-386 ./docker.SlackBuild installpkg /tmp/docker-18.09.2-i586-1_SBo.tgz cd /etc/rc.d sh rc.docker status sh rc.docker start groupadd -r -g 281 docker usermod -a -G docker vitor }}} == Docker + cherrypy == === Setup environment === {{{#!highlight python cd ~ mkdir env-docker-cherry cd env-docker-cherry touch Dockerfile mkdir target touch target/cherry.py }}} === Ubuntu Dockerfile === {{{#!highlight sh FROM ubuntu:20.04 RUN apt update RUN apt-get install -y curl sudo wget python net-tools vim RUN mkdir /app RUN cd /app && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py RUN cd app/ && python get-pip.py && pip install cherrypy RUN echo "#!/bin/sh\n python /app/cherry.py" > /start.sh EXPOSE 80 22 8080 8081 CMD ["sh","/start.sh"] }}} === Alpine Dockerfile === {{{#!highlight sh touch Dockerfile mkdir target touch target/cherry.py }}} {{{#!highlight sh FROM alpine:3.16 RUN apk add --update --no-cache python3 curl wget RUN mkdir /app RUN cd /app && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py RUN cd app/ && python3 get-pip.py && pip install cherrypy EXPOSE 80 22 8080 8081 CMD ["python3","/app/cherry.py"] }}} === target/cherry.py === {{{#!highlight python import cherrypy import json cherrypy.config.update({'server.socket_port': 8081}) cherrypy.config.update({'server.socket_host': '0.0.0.0'}) class Root(object): @cherrypy.expose def index(self): return "Hello World!".encode('utf8') root = Root() cherrypy.quickstart(root) }}} === Commands to run container === {{{#!highlight sh docker build -t env-docker-cherry-image . # run container and map docker internal port 8081 to external port 8081 docker run -p 8081:8081 -d -it --rm --name env-docker-cherry-container --mount type=bind,source="$(pwd)"/target,target=/app env-docker-cherry-image docker ps # invoke external port 8081 curl http://localhost:8081/ # change code in target ... vi target/cherry.py # inside Root class # @cherrypy.expose # def test(self): # return "test hey!".encode('utf8') # invoke external port 8081 to check the modification made curl http://localhost:8081/test #### create net between two containers docker network create testnet docker network ls docker network connect testnet env-docker-cherry-container docker run -p 8082:8081 -d -it --rm --name env-docker-cherry-container-2 --network testnet --mount type=bind,source="$(pwd)"/target,target=/app env-docker-cherry-image docker ps docker exec -it env-docker-cherry-container-2 ash # ping env-docker-cherry-container-2 # ping env-docker-cherry-container docker exec -it env-docker-cherry-container ash # ping env-docker-cherry-container-2 # ping env-docker-cherry-container }}} == Setup Proxy for docker daemon == {{{#!highlight sh sudo bash mkdir /etc/systemd/system/docker.service.d cd /etc/systemd/system/docker.service.d nano http-proxy.conf [Service] Environment="HTTP_PROXY=http://192.168.22.214:3128" Environment="HTTPS_PROXY=http://192.168.22.214:3128" systemctl daemon-reload systemctl restart docker # settings also in ~/.docker/config.json { "proxies": { "default": { "httpProxy": "http://192.168.42.108:3128", "httpsProxy": "http://192.168.42.108:3128", "noProxy": "127.0.0.0/8" } } } }}} == Install from binaries in Slackware 15.0 == {{{#!highlight sh # as root wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.17.tgz tar xvzf docker-20.10.17.tgz cp docker/* /usr/bin/ groupadd -r -g 281 docker usermod -a -G docker vitor # signout and signin user vitor sudo nohup dockerd & docker run hello-world }}} == Build image from scratch - Slackware64 15.0 - rootfs == === Dockerfile === {{{#!highlight sh FROM scratch ADD . / RUN /usr/bin/echo "test" > /test.txt #CMD ["/usr/bin/cat","/test.txt"] CMD ["/usr/bin/tail","-f","/test.txt"] }}} === Steps === {{{#!highlight sh mkdir scratch-test cd scratch-test/ touch Dockerfile mkdir -p usr/bin/ mkdir lib64 mkdir bin cp /usr/bin/ls usr/bin/ cp /usr/bin/cat usr/bin/ cp /usr/bin/echo usr/bin/ cp /usr/bin/tail usr/bin/ cp /usr/bin/uname usr/bin/ cp /bin/sh bin/ # to check dependencies use ldd cp /lib64/libcap.so.2 lib64/ cp /lib64/libc.so.6 lib64/ cp /lib64/libtinfo.so.6 lib64/ cp /lib64/libdl.so.2 lib64/ cp /lib64/ld-linux-x86-64.so.2 lib64/ # build image and run container docker build -t scratch-test-image . docker run --rm --name scratch-test-container scratch-test-image ##### docker build -t scratch-test-image . docker run -d --rm --name scratch-test-container scratch-test-image docker ps docker exec -it scratch-test-container sh # export container filesystem docker container export scratch-test-container -o scratch-test.tar tar tvf scratch-test.tar.gz }}} == Static binaries in Slackware64 == * https://docs.docker.com/engine/install/binaries/ * https://download.docker.com/linux/static/stable/x86_64/docker-20.10.17.tgz === /etc/rc.d/rc.docker === {{{#!highlight sh #!/bin/sh PATH=$PATH:/usr/sbin docker_start() { /usr/bin/dockerd --raw-logs > /var/log/dockerd.log 2>&1 & } docker_stop() { killall dockerd } docker_restart() { docker_stop docker_start } case "$1" in 'start') docker_start ;; 'stop') docker_stop ;; 'restart') docker_restart ;; *) echo "usage $0 start|stop|restart" esac }}} {{{#!highlight sh # In Slack64 sudo sh /etc/rc.d/rc.docker start #sudo sh /etc/rc.d/rc.docker stop #sudo sh /etc/rc.d/rc.docker restart docker ps docker version docker run hello-world }}}