Size: 119
Comment:
|
Size: 26684
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 3: | Line 3: |
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). docker run hello-world == Docker SSH container Ubuntu == https://docs.docker.com/examples/running_ssh_service/ In bootDocker create ~/ssh/Dockerfile : {{{ # 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"] }}} * 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 == * apt-get install software-properties-common * add-apt-repository ppa:openjdk-r/ppa -y * apt-get update * apt-get install openjdk-8-jdk Dockerfile {{{ 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 == {{{ 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 == {{{ 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 == {{{ 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 == {{{ 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 == {{{ 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 == {{{ 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 == {{{ 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: {{{ # 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: {{{ 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 bash 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 bash docker ps -a # showall containers docker system prune -a # clean system 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 bash 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 bash # 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" 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): 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" 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) }}} == 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 bash 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 bash # 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 bash 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 bash docker build -t hello-maven-docker-image . docker run -it --rm --name hello-maven-docker hello-maven-docker-image }}} == docker - maven - springboot-test == * 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 === {{{ 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 bash 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 |
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://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).
docker run hello-world
Docker SSH container Ubuntu
https://docs.docker.com/examples/running_ssh_service/
In bootDocker create ~/ssh/Dockerfile :
# 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"]
- 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
- apt-get install software-properties-common
- add-apt-repository ppa:openjdk-r/ppa -y
- apt-get update
- apt-get install openjdk-8-jdk
Dockerfile
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
Install go lang
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
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
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
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
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
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
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:
# 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:
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
1 mkdir tmp
2 cd tmp
3 vagrant init ubuntu/xenial64
4 vagrant up
5 vagrant ssh
6 # inside the box with user vagrant
7 sudo bash
8 apt-get update
9 apt-get install apt-transport-https ca-certificates curl software-properties-common
10 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
11 apt-key fingerprint 0EBFCD88
12 add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
13 apt-get update
14 apt-get install docker-ce
15 docker run hello-world
16 usermod -aG docker
17 exit
18 exit
19 #login again with vagrant ssh
20 # as user vagrant
21 docker run hello-world
22 # install java and maven
23 apt-get install openjdk-8-jdk
24 apt-get install maven
Commands
1 docker ps -a # showall containers
2 docker system prune -a # clean system
3 docker ps -a | awk '//{print $1}' | grep -v "CONTAINER" | xargs -i sh -c 'docker stop {};docker rm {}' # clear all containers
4 docker build -t acme_app . # build image from docker file
5 docker run -P -p 8080:80 -d acme_app # run dettached container from image acme_app mapping port 8080 to port exposed 80
6
Docker DNS server
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
Docker playground - cherrypy
Dockerfile
1 # docker build -t image_cherrypy . # build image from Dockerfile
2 # docker run -P -p 8080:80 -d image_cherrypy
3 # touch cherrypytest.wsgi
4 # links http://localhost/add/3/4
5 # curl -X POST -d "{\"name\":\"jkl\"}" http://localhost/hellojson --header "Content-Type:application/json"
6 FROM ubuntu:16.04
7 RUN apt-get update && apt-get install -y python libapache2-mod-wsgi apache2 vim links net-tools nano curl wget
8 RUN wget https://pypi.python.org/packages/source/C/CherryPy/CherryPy-3.2.4.tar.gz
9 RUN cp CherryPy-3.2.4.tar.gz /tmp
10 RUN cd /tmp && tar xvzf CherryPy-3.2.4.tar.gz
11 RUN cd /tmp/CherryPy-3.2.4 && python setup.py build && python setup.py install
12 RUN mkdir -p /var/www/htdocs/cherrypytest/static
13 # copy cherrypytest.wsgi from where the Dockerfile is
14 COPY cherrypytest.wsgi /var/www/htdocs/cherrypytest/cherrypytest.wsgi
15 RUN echo "Static Test" > /var/www/htdocs/cherrypytest/static/a.txt
16 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
17 RUN echo "#!/bin/sh\n service apache2 start \n tail -f /var/log/apache2/error.log" > /start.sh
18 EXPOSE 80
19 CMD ["sh","/start.sh"]
cherrypytest.wsgi
1 import sys
2 sys.stdout = sys.stderr
3 import cherrypy
4
5 cherrypy.config.update({'environment': 'embedded'})
6
7 class HelloWorld(object):
8 @cherrypy.expose
9 def index(self):
10 return "Hello World CherryPy!!!!"
11
12 @cherrypy.expose
13 def add(self,param1,param2):
14 return str( int(param1)+int(param2) )
15
16 @cherrypy.expose
17 @cherrypy.tools.json_in()
18 @cherrypy.tools.json_out()
19 def hellojson(self):
20 # curl -X POST -d "{\"name\":\"jkl\"}" http://localhostcherrypytest/hellojson --header "Content-Type:application/json"
21 inj = cherrypy.request.json
22 return {"message": "hello world " + inj['name'] }
23
24 hello = HelloWorld()
25 #static dir
26 confx={'/static': {'tools.staticdir.on':True ,
27 'tools.staticdir.dir':'/var/www/htdocs/cherrypytest/static'
28 }}
29 application = cherrypy.Application(hello, script_name=None, config=confx)
Docker - openjdk8 - hello
Main.java
Dockerfile
Execute
Docker - openjdk 8 - hello - maven
- mkdir -p src/main/java/com/example/artifactX
pom.xml
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
3 http://maven.apache.org/maven-v4_0_0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <groupId>com.example</groupId>
6 <artifactId>artifactX</artifactId>
7 <packaging>jar</packaging>
8 <version>0.0.1</version>
9 <name>artifactX</name>
10 <url>http://maven.apache.org</url>
11 <build>
12 <plugins>
13 <plugin>
14 <artifactId>maven-assembly-plugin</artifactId>
15 <version>2.4</version>
16 <configuration>
17 <descriptorRefs>
18 <descriptorRef>jar-with-dependencies</descriptorRef>
19 </descriptorRefs>
20 <archive>
21 <manifest>
22 <mainClass>com.example.artifactX.Main</mainClass>
23 </manifest>
24 </archive>
25 </configuration>
26 <executions>
27 <execution>
28 <id>make-assembly</id>
29 <phase>package</phase>
30 <goals>
31 <goal>single</goal>
32 </goals>
33 </execution>
34 </executions>
35 </plugin>
36 </plugins>
37 </build>
38 <dependencies>
39 </dependencies>
40 </project>
src/main/java/com/example/artifactX/Main.java
Dockerfile
Execute
docker - maven - springboot-test
- 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
Dockerfile
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
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <groupId>hello</groupId>
6 <artifactId>test-spring-boot</artifactId>
7 <version>0.1.0</version>
8 <parent>
9 <groupId>org.springframework.boot</groupId>
10 <artifactId>spring-boot-starter-parent</artifactId>
11 <version>1.4.0.RELEASE</version>
12 </parent>
13 <dependencies>
14 <dependency>
15 <groupId>org.springframework.boot</groupId>
16 <artifactId>spring-boot-starter-thymeleaf</artifactId>
17 </dependency>
18 </dependencies>
19 <properties>
20 <start-class>hello.Application</start-class>
21 </properties>
22 <build>
23 <plugins>
24 <plugin>
25 <groupId>org.springframework.boot</groupId>
26 <artifactId>spring-boot-maven-plugin</artifactId>
27 </plugin>
28 </plugins>
29 </build>
30 <repositories>
31 <repository>
32 <id>spring-milestone</id>
33 <url>http://repo.spring.io/libs-release</url>
34 </repository>
35 </repositories>
36 <pluginRepositories>
37 <pluginRepository>
38 <id>spring-milestone</id>
39 <url>http://repo.spring.io/libs-release</url>
40 </pluginRepository>
41 </pluginRepositories>
42 </project>
src/main/java/hello/GreetingController.java
1 package hello;
2
3 import org.springframework.stereotype.Controller;
4 import org.springframework.ui.Model;
5 import org.springframework.web.bind.annotation.RequestMapping;
6 import org.springframework.web.bind.annotation.RequestParam;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9 import org.springframework.web.bind.annotation.ResponseBody;
10 import org.springframework.beans.factory.annotation.Autowired;
11 import java.util.List;
12 import java.util.ArrayList;
13
14 @Controller
15 public class GreetingController {
16 private final Logger logger = LoggerFactory.getLogger(GreetingController.class);
17
18 public GreetingController(){
19 logger.debug("Greeting controller created.");
20 }
21
22 @RequestMapping("/greeting")
23 // http://localhost:8080/greeting?name=nnnn
24 public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
25 logger.info("Greeting endpoint called.");
26 model.addAttribute("name", name);
27 return "greeting";
28 }
29
30 @RequestMapping(value="/dummy",produces="application/json")
31 @ResponseBody
32 // http://localhost:8080/dummy
33 public List<Dummy> dummy(){
34 List<Dummy> list= new java.util.ArrayList<Dummy>();
35 Dummy dummy = new Dummy();
36 dummy.setFieldA("AAA");
37 dummy.setFieldB("CCC");
38 list.add(dummy);
39
40 Dummy dummy2 = new Dummy();
41 dummy2.setFieldA("AAA2");
42 dummy2.setFieldB("CCC2");
43 list.add(dummy2);
44
45 return list;
46 }
47
48 }
src/main/java/hello/Application.java
1 package hello;
2
3 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
4 import org.springframework.boot.SpringApplication;
5 import org.springframework.context.annotation.ComponentScan;
6 import org.springframework.context.annotation.Bean;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.beans.factory.annotation.Qualifier;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11
12 @ComponentScan
13 @EnableAutoConfiguration
14 public class Application {
15 private static Logger logger;
16
17 public static void main(String[] args) {
18 logger = LoggerFactory.getLogger(Application.class);
19 logger.info("Starting application");
20 SpringApplication.run(Application.class, args);
21 }
22
23 }
src/main/java/hello/ThreadTimer.java
1 package hello;
2
3 import org.springframework.stereotype.Component;
4 import javax.annotation.PostConstruct;
5 import org.springframework.beans.factory.annotation.Autowired;
6 import java.text.MessageFormat;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9 import java.util.ArrayList;
10
11 @Component
12 public class ThreadTimer extends Thread {
13 private int delaySeconds;
14 private Logger logger;
15 private boolean running;
16 private Object monitor=new Object();
17 private ArrayList<Object> subscribers;
18
19 //@Autowired
20 //WaitThread waitThread;
21
22 public ThreadTimer() {
23 this.logger = LoggerFactory.getLogger(ThreadTimer.class);
24 logger.info("Created instance of " + this.getClass().getSimpleName());
25 this.running = true;
26 this.delaySeconds = 5 * 1000;
27 this.setName(this.getClass().getSimpleName() + "_" + this.getName());
28 this.subscribers = new ArrayList<Object>();
29 }
30
31 public void addSubscriber(Object subscriber){
32 this.subscribers.add(subscriber);
33 }
34
35 @PostConstruct
36 public void init() {
37 logger.info("Starting the thread");
38 this.start();
39 }
40
41 @Override
42 public void run() {
43 while (running) {
44 try {
45 Thread.sleep(this.delaySeconds);
46 logger.info("Delay " + this.getClass().getSimpleName());
47
48 for(Object o: this.subscribers){
49 synchronized(o){
50 o.notify();
51 }
52 }
53 }
54 catch (InterruptedException e) {
55 logger.info("ThreadTimer interrupted exception:" + e.getMessage() );
56 }
57 catch (Exception e) {
58 e.printStackTrace();
59 logger.info("ThreadTimer exception:" + e.getMessage() );
60 stopRunning();
61 }
62 }
63 logger.info("Exited " + this.getClass().getSimpleName());
64 }
65
66 public void startRunning() {
67 this.running = true;
68 }
69
70 public void stopRunning() {
71 this.running = false;
72 }
73
74 public void destroy(){
75 logger.info("Called destroy");
76 this.stopRunning();
77 this.interrupt();
78 }
79 }
src/main/java/hello/WaitThread.java
1 package hello;
2
3 import org.springframework.stereotype.Component;
4 import javax.annotation.PostConstruct;
5 import java.text.MessageFormat;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.beans.factory.annotation.Autowired;
9
10 @Component
11 public class WaitThread extends Thread {
12 private Logger logger;
13 private boolean running;
14 private Object monitor;
15
16 @Autowired
17 ThreadTimer timerThread;
18
19 public WaitThread() {
20 this.logger = LoggerFactory.getLogger(WaitThread.class);
21 logger.info("Created instance of " + this.getClass().getSimpleName());
22 this.running = true;
23 this.setName(this.getClass().getSimpleName() + "_" + this.getName());
24 this.monitor=new Object();
25 }
26
27 @PostConstruct
28 public void init() {
29 this.timerThread.addSubscriber(this);
30 logger.info("Starting the thread");
31 this.start();
32 }
33
34 public void run() {
35 while (running) {
36 try {
37 synchronized(this){
38 this.wait();
39 logger.info("Notification received.");
40 }
41 }
42 catch (InterruptedException e) {
43 logger.info("ThreadTimer interrupted exception:" + e.getMessage() );
44 }
45 catch (Exception e) {
46 logger.info("WaitThread exception:" + e.getMessage() );
47 stopRunning();
48 }
49 }
50 logger.info("Exited " + this.getClass().getSimpleName());
51 }
52
53 public void startRunning() {
54 this.running = true;
55 }
56
57 public void stopRunning() {
58 this.running = false;
59 }
60
61 public void destroy(){
62 logger.info("Called destroy");
63 this.stopRunning();
64 this.interrupt();
65 }
66 }
src/main/java/hello/Dummy.java
1 package hello;
2
3 public class Dummy{
4 private String fieldA;
5 private String fieldB;
6
7 public Dummy(){
8 }
9
10 public String getFieldA(){
11 return fieldA;
12 }
13
14 public String getFieldB(){
15 return fieldB;
16 }
17
18 public void setFieldA(String arg){
19 fieldA = arg;
20 }
21
22 public void setFieldB(String arg){
23 fieldB = arg;
24 }
25 }
src/main/resources/templates/greeting.html
src/main/resources/application.properties
1 logging.file=/tmp/testout.log
src/main/resources/logback-spring.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <configuration>
3 <!--
4 <include resource="org/springframework/boot/logging/logback/defaults.xml" />
5 <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
6 <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
7 -->
8 <!-- override spring logback default behaviour -->
9 <appender name="FILE" class="ch.qos.logback.core.FileAppender">
10 <file>${filelog}</file>
11 <encoder>
12 <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern>
13 </encoder>
14 </appender>
15 <appender name="GREETFILE" class="ch.qos.logback.core.FileAppender">
16 <file>/tmp/greet.log</file>
17 <encoder>
18 <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern>
19 </encoder>
20 </appender>
21 <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
22 <layout class="ch.qos.logback.classic.PatternLayout">
23 <Pattern>%yellow(%date{ISO8601}) %green([%thread]) %highlight(%-5level) %cyan(%logger{35}) - %white(%msg%n) </Pattern>
24 </layout>
25 </appender>
26 <root level="INFO">
27 <appender-ref ref="FILE" />
28 <appender-ref ref="CONSOLE"/>
29 </root>
30 <logger name="hello.GreetingController" level="debug" additivity="false">
31 <appender-ref ref="GREETFILE"/>
32 <appender-ref ref="CONSOLE" />
33 </logger>
34 </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
Docker registry
- Check images catalog in registry