Eric Helgeson

Eric Helgeson

About Blog Email GitHub RSS

17 Oct 2014
Docker, SpringBoot, MicroServices. Friday hacking

Fig 1.0 and Docker 1.3 were released this week and brought along some new features that, for me, made Docker a viable alternative to our normal Vagrant or Kitchen environments. Shared folders now work from MacOS, through Boot2Docker to the container. That means developers can write code on their Laptop and be visible directly to the container. Also the docker run or fig run is a helpful to inspect the container when your unsure what is going on.

Here’s how we approached it.

Project Layout

├── README.md
├── myapp-api # All the springboot microservices
│   ├── Dockerfile # Just: 'FROM java:8' for now.
│   ├── myapp-common # Shared Java code
│   ├── myapp-oauth # OAuth Server
│   ├── myapp-resource # Has API Resources protected by myapp-oauth
│   ├── ... more apis ...
│   ├── build.gradle # Gradle file, builds other projects
├── myapp-web
│   └── package.json
├── data # Persist postgres
└── fig.yml

fig.yml

# OAuth Server (springboot app)
oauth:
  build: myapp-api/. # Use the Dockerfile under my myapp-api
  working_dir: /code/myapp-api
  # Build and run the app via Gradle
  # Cache dependancies and Gradle on the shared folder so we dont have to download each time.
  command: ./gradlew myapp-oauth:bootRun --project-cache-dir /code/myapp-api/myapp-oauth
  environment:
    GRADLE_OPTS: "-Dgradle.user.home=/code/.gradle_home_oauth"
  # Let this container talk to postgres
  links:
    - db
  ports:
    - "8081:8081"
  # Share the cwd on my mac with the container
  volumes:
    - .:/code

# Resources api (springboot app)
resource:
  build: myapp-api/.
  working_dir: /code/myapp-api
  command: ./gradlew myapp-resource:bootRun --project-cache-dir /code/myapp-api/myapp-resource
  environment:
    GRADLE_OPTS: "-Dgradle.user.home=/code/.gradle_home_resource"
  links:
    - db
    - oauth
  ports:
    - "8080:8080"
  volumes:
    - .:/code

# No Docker file here yet, just using the Prebuilt image and npm start to download and start the app.
web:
  image: node:0.10-onbuild
  working_dir: /code/myapp-web
  command: npm start
  links:
    - db
    - resource
    - oauth
  ports:
    - "8000:8000"
  volumes:
    - .:/code

# The default Postgres is good enough here. RDS in production
db:
  image: postgres
  # Expose the port so we can access the DB via psql -U postgres -h BOOT2DOCKERIP
  ports:
    - "5432:5432"
  # Persist the data between containers.
  volumes:
    - ./data:/var/lib/postgresql

This is less than 50 lines (without comments) of code to describe our whole stack and some of it could be moved into the Dockerfile. And after the initial Gradle/NPM builds starts up fast!

fig up

Deploying

Since we’re using SpringBoot we’ll be deploying fatjar, Our Docker files will be simple:

FROM java:8
COPY target/myapp-oauth.jar /opt/myapp-oauth.jar
CMD java -jar /opt/myapp-oauth.jar

I have run fatjars in production with other frameworks, it is most defiantly my favorite way to run Java+Tomcat!

Configuration

Docker will create a /etc/hosts with the other linked container info (eg, so the database can be referenced just by postgresql://db:5432/myapp) or you can use the environment variables injected like so:

myapp-oauth/src/main/resources/application.properties -
spring.datasource_oauth.url=jdbc:postgresql://${DB_PORT_5432_TCP_ADDR}:5432/myapp_oauth

We haven’t finalized on the approach yet, will update this post with what works for us!

The new docker run seems really interesting for production debugging, docker run <container> sysdig :)

Next steps

I’ve been playing with Docker on and off since its release and today was the first time it really clicked and worked for our whole stack and developer workflow. This was about a 1/2 of a day or so to get this up and hopefully it’ll save you some time and give you a few ideas when building your Docker setup.

I’ll be folding this into our CI/CD pipeline and looking at how to integrate a service discovery layer on top. More on that in a later blog post.

Let me know on twitter or in the comments if you have any questions or approached this differently, would love to hear your experiences.


Want to contribute to this article? Edit this post on Github!

About Blog Email GitHub RSS