Spring boot, mongoDB and Spring consul

I am developing a containerized micro service using Spring Boot and using MongoDB as a database and Consul for service discovery and KV storage. I have written cucumber tests as well and want to bring all of this using docker compose and then run the tests against the whole thing. When I was just using Spring Boot MS and Mongo then I was able to bring up the service using docker-compose and run the tests. Since I have added Spring-Consul it doesn’t work. Here are some details

build.gradle

<code> buildscript {
    ext {
        springBootVersion = '2.0.0.RC1'
        dockerComposePluginVersion = '0.6.15'
    }
    repositories {
        mavenCentral()
        jcenter()
        maven { url "https://repo.spring.io/snapshot" }
        maven { url "https://repo.spring.io/milestone" }
        maven { url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath("io.spring.gradle:dependency-management-plugin:1.0.2.RELEASE")
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.17.2")
        classpath "com.avast.gradle:gradle-docker-compose-plugin:${dockerComposePluginVersion}"
        classpath('com.adarshr:gradle-test-logger-plugin:1.1.2')
    }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

apply plugin: 'com.palantir.docker'
apply plugin: 'com.palantir.docker-run'
apply plugin: 'docker-compose'
apply plugin: 'com.adarshr.test-logger'

apply from: "$rootDir/integTest.gradle"


dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-consul-dependencies:2.0.0.M5"
    }
}

group = 'com.inmarsat.be'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

dockerCompose.isRequiredBy(integTest)

testlogger {
    theme 'mocha'
}

configurations {
    compile.exclude module: 'spring-boot-starter-tomcat'

    cucumberRuntime {
        extendsFrom testRuntime
    }
}

jar {
    baseName = 'examplems'
    version =  project.version
}

springBoot {
    mainClassName = "com.inmarsat.be.examplems.ExamplemsApplication"
}

bootJar {
    baseName = 'examplems'
    version =  project.version
}


docker {
    name "${project.group}/${jar.baseName}"
    tags 'latest'
    files bootJar
    dockerfile file('Dockerfile')
    buildArgs([BUILD_VERSION: "${project.version}"])
    noCache true
}


//task cucumber() {
//    dependsOn assemble, compileTestJava
//    doLast {
//        javaexec {
//            main = "cucumber.api.cli.Main"
//            classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
//            args = ['--plugin', 'pretty', '--glue', 'com.inmarsat.be.bdd', 'src/bdd/resources']
//        }
//    }
//}

repositories {
    mavenCentral()
    maven { url "https://repo.spring.io/snapshot" }
    maven { url "https://repo.spring.io/milestone" }
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-webflux')
    compile('org.springframework.boot:spring-boot-starter-data-mongodb-reactive')
    compile('org.springframework.boot:spring-boot-starter-hateoas')
    compile('org.springframework.boot:spring-boot-starter-reactor-netty')
    compile('org.springframework.cloud:spring-cloud-starter-consul-all')

    compileOnly('org.projectlombok:lombok')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('de.flapdoodle.embed:de.flapdoodle.embed.mongo')
    testCompile('io.projectreactor:reactor-test')
    testCompile('org.springframework.restdocs:spring-restdocs-mockmvc')
    testCompile('junit:junit')
    testCompile('org.assertj:assertj-core')
    testCompile('io.cucumber:cucumber-java:2.3.1')
    testCompile('io.cucumber:cucumber-junit:2.3.1')
    testCompile(group: 'info.cukes', name: 'cucumber-spring', version: '1.2.5')
}
</code>

integTest.gradle
<code>
sourceSets {
    integTest {
        java.srcDir 'src/integTest/java'
        resources.srcDir 'src/integTest/resources'
    }
}

dependencies {
    integTestCompile sourceSets.main.output
    integTestCompile sourceSets.test.output

    integTestCompile configurations.compile
    integTestCompile configurations.testCompile

    integTestRuntime configurations.runtime
    integTestRuntime configurations.testRuntime
}

//noinspection GroovyAssignabilityCheck
task integTest(type: Test) {
    group = LifecycleBasePlugin.VERIFICATION_GROUP
    description = 'Runs the bdd tests.'

    maxHeapSize = '1024m'

    setTestClassesDirs sourceSets.integTest.output.classesDirs
    classpath = sourceSets.integTest.runtimeClasspath

    binResultsDir = file("$buildDir/integration-test-results/binary/integTest")


    reports {
        html.destination  file("$buildDir/reports/integration-test")
        junitXml.destination  file("$buildDir/integration-test-results")
    }

    mustRunAfter tasks.test
}

check.dependsOn integTest


gradle.projectsEvaluated {
    def quickTasks = []

    gradle.rootProject.allprojects.each { project ->
        quickTasks.addAll(project.tasks.findAll { it.name == 'test' })
        quickTasks.addAll(project.tasks.withType(FindBugs))
        quickTasks.addAll(project.tasks.withType(Pmd))
    }

    quickTasks.each { task ->
        project.tasks.integTest.mustRunAfter task
    }
}
</code>

docker-compose.yaml
<code>
version: '3.1'

services:
  springboot:
    image: com.inmarsat.be/examplems:latest
    restart: always
    container_name: springboot
    ports:
      - 8180:8080
    working_dir: /opt/app
    depends_on:
      - consul
      - mongo
   mongo:
    image: mongo
    container_name: springboot-mongo
    ports:  # for demo/debug purpose only
      - 27018:27017
    volumes:
      - $HOME/data/springboot-mongo-data:/data/db
      - $HOME/data/springboot-mongo-bkp:/data/bkp
    restart: always
  consul:
    image: consul
    container_name: consul
    hostname: consul
    command: agent -dev
    ports:
        - 8500:8500
        - 8600:8600
        - 8400:8400
</code>

application.yaml
<code>
server:
  port: 8080

spring:
  data:
    mongodb:
      uri:  mongodb://localhost:27017/webflux_demo
  output:
    ansi:
      enabled: always
  main:
    banner-mode: console
</code>

bootstrap.yaml

<code>
spring:
  application:
    name: ExampleMicroserviceApp
  cloud:
    consul:
      host: localhost
      port: 8500
      config:
        format: yaml
        enabled: false
        prefix: config
        data-key: data
        profile-separator: '::'
        default-context: application
        fail-fast: false

      discovery:
        health-check-path: /health
        health-check-interval: 15s
        instance-id: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
</code>

Thanks & Regards,
Irfan

How do I set up PhpStorm so that the Docker Compose Interpreter can use the PHP executable?

I’m trying to integrate Docker with PhpStorm by following this JetBrainsTV video. (The container is working fine – it’s up and running).

At the CLI Interpreter edit screen, it says PHP is not installed.

enter image description here

When I click the synchronise button, I get an ‘Address in use’ error.

enter image description here

Kubernetes – Jenkins integration

I’ve bootstrapped with kubeadm Kubernetes 1.9 RBAC cluster and I’ve started inside a POD Jenkins based on jenkins/jenkins:lts. I would like to try out https://github.com/jenkinsci/kubernetes-plugin .
I have already created a serviceaccount based on the proposal in https://gist.github.com/lachie83/17c1fff4eb58cf75c5fb11a4957a64d2

> kubectl -n dev-infra create sa jenkins
> kubectl create clusterrolebinding jenkins --clusterrole cluster-admin --serviceaccount=dev-infra:jenkins
> kubectl -n dev-infra get sa jenkins -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: 2018-02-16T12:06:26Z
  name: jenkins
  namespace: dev-infra
  resourceVersion: "1295580"
  selfLink: /api/v1/namespaces/dev-infra/serviceaccounts/jenkins
  uid: d040041c-1311-11e8-a4f8-005056039a14
secrets:
- name: jenkins-token-vmt79

> kubectl -n dev-infra get secret jenkins-token-vmt79 -o yaml
apiVersion: v1
data:
  ca.crt: LS0tL...0tLQo=
  namespace: ZGV2LWluZnJh
  token: ZXlK...tdVE=
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: jenkins
    kubernetes.io/service-account.uid: d040041c-1311-11e8-a4f8-005056039a14
  creationTimestamp: 2018-02-16T12:06:26Z
  name: jenkins-token-vmt79
  namespace: dev-infra
  resourceVersion: "1295579"
  selfLink: /api/v1/namespaces/dev-infra/secrets/jenkins-token-vmt79
  uid: d041fa6c-1311-11e8-a4f8-005056039a14
type: kubernetes.io/service-account-token

After that I go to Manage Jenkins -> Configure System -> Cloud -> Kubernetes and set the Kubernetes URL to the Cluster API that I use also in my kubectl KUBECONFIG server: url:port.

When I hit test connection I get “Error testing connection https://url:port: Failure executing: GET at: https://url:port/api/v1/namespaces/dev-infra/pods. Message: Forbidden!Configured service account doesn’t have access. Service account may have been revoked. pods is forbidden: User “system:serviceaccount:dev-infra:default” cannot list pods in the namespace “dev-infra”.

I don’t want to give to the dev-infra:default user a cluster-admin role and I want to use the jenkins sa I created. I can’t understand how to configure the credentials in Jenkins. When I hit add credentials on the https://github.com/jenkinsci/kubernetes-plugin/blob/master/configuration.png I get

<select class="setting-input dropdownList">
<option value="0">Username with password</option>
<option value="1">Docker Host Certificate Authentication</option>
<option value="2">Kubernetes Service Account</option>
<option value="3">OpenShift OAuth token</option>
<option value="4">OpenShift Username and Password</option>
<option value="5">SSH Username with private key</option>
<option value="6">Secret file</option>
<option value="7">Secret text</option>
<option value="8">Certificate</option></select>

I could not find a clear example how to configure Jenkins Kubernetes Cloud connector to use my Jenkins to authenticate with service account jenkins.
Could you please help me to find step-by-step guide – what kind of of credentials I need?

Regards,
Pavel

Docker: I can’t map ports other than 80 to my WordPress container

I want to map some random port on my computer e.g. localhost:7006 to my WordPress docker container’s port 80. Currently when I change the port of WordPress from 80:80 to 7006:80 it not only stops working on localhost(port 80) but also don’t respond on localhost:7006.

My docker-compose.yml file looks like this:

    version: '3'
services:
  wordpress:
    depends_on:
      - db
    image: wordpress:4.7.1
    restart: always
    volumes:
      - ./wp-content:/var/www/html/wp-content 
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_PASSWORD: p4ssw0rd!
    ports:
      - 80:80 # Expose http and https
      - 8443:443
    networks:
      - wp_nwk
  db:
    image: mysql:5.7
    restart: always
    volumes:
       - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: p4ssw0rd!
    networks:
      - wp_nwk
  phpmyadmin:
    depends_on:
      - db
    image: phpmyadmin/phpmyadmin
    restart: always
    ports:
      - 7005:80
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: p4ssw0rd!
    networks:
      - wp_nwk
networks:
  wp_nwk:
volumes:
  db_data:

Access denied when pulling Docker image from a repository I own

I built a Docker image that I pushed to Docker Hub under my account and removed locally after. But when I try to pull it, it throws the following error:

Error response from daemon: pull access denied for mightyspaj/dockerfile-assignment-1, repository does not exist or may require 'docker login'

I’m logged into the same account that owns the repository for this image and can perform other tasks (such as pushing) perfectly fine. The repository also definitely exists on Docker Hub, yet it fails when I try to pull it.

I’ve tried the following things:

  1. Logging out of my account and back in again
  2. Renaming config.json and regenerating it
  3. Running an isolated Docker container with docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock:ro docker sh, then logging into my account and attempting to pull the image
  4. Deleting and recreating the repository

All of these things still produce the same error. I’m baffled.

To note, both my client and engine versions are 17.12.0-ce. My OS is Ubuntu 17.10 (64-bit).

Console output

docker login

-> % docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: mightyspaj
Password: 
Login Succeeded

docker tag

-> % docker tag dockerfile-assignment-1:latest mightyspaj/dockerfile-assignment-1

docker push

-> % docker push mightyspaj/dockerfile-assignment-1                              
The push refers to repository [docker.io/mightyspaj/dockerfile-assignment-1]
8427a8e6a29f: Pushed 
655a921743e8: Pushed 
8aa44edb7524: Pushed 
60f1a2dc4cd8: Mounted from library/node 
9185fe936b87: Mounted from library/node 
e53f74215d12: Mounted from library/node 
latest: digest: sha256:6c68220ba84f13d0229ef4458f22369410bb98764b908a75be0849c3003de160 size: 1582

docker image rm

-> % docker image rm mightyspaj/dockerfile-assignment-1
Untagged: mightyspaj/dockerfile-assignment-1:latest
Untagged: mightyspaj/dockerfile-assignment-1@sha256:6c68220ba84f13d0229ef4458f22369410bb98764b908a75be0849c3003de160

docker image pull

-> % docker image pull mightyspaj/dockerfile-assignment-1
Using default tag: latest
Error response from daemon: pull access denied for mightyspaj/dockerfile-assignment-1, repository does not exist or may require 'docker login'

Unable to setup networking to access docker container IPs from outside?

Context:
I have a web server hosting a UI from which users can request for emulator instances for my product. Each emulator instance is a webapp running on nodejs. When a user requests an emulator instance from the UI, I spawn a docker container. I would like to return to the user an IP address(+port) from which this emulator container can be accessed.
Note: Presently, docker and the webserver facing the user are running on the same system.

Problems:
1) The default container on the docker0 network is accessible only with it’s local IP address on the host. e.g. http://172.17.0.5. I can’t access the container with http://localhost:32768 (container was started with -P and was assigned the port 32768). I get a message that the site can’t be reached.

2) I can’t use the docker host network driver because the emulator uses ports internally which I don’t want to expose in the host network

3) I don’t want to use the macvlan driver because I will be using up too many IPs.

Is it possibly to map various ports on the host to IPs on the docker0 subnet? If yes, how do I go about this? If this is possible I could expose the host IP and the container specific port to the user.

What is best way to give users access to the containers?

docker sharing host directory

I used to share my host diretory with a docker container with the command (osx):

docker run --name tensorflower -it -p 8888:8888 -v /c/foo/labs:/home tensorflow/tensorflow

on windows it used to work with:

docker run --name tensorflower -it -p 8888:8888 -v //c/foo/labs:/home tensorflow/tensorflow

But now it does not work on windows. I tried both -v variants. As I do not get any error messages, I have no glue where to dig in to solve the problem.

How can I share the host directory c:\foo\labs with my docker container?
Or at least get some more informaton regarding the error?

Docker version 17.09.1-ce, build 19e2cf6 on windows 10

Docker terminal size

I’m running docker 17.12.0-ce under ubuntu 16.04 Server

After doing docker exec -it ... bash the terminal (putty) size change.

Before stty size gives 60 180 after 0 0

So after entering the 80st character the next ones are placed at the begining of the line (not on the next line).

enter image description here

There is a solution ? Something to configure in docker daemon ?