-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
217d133
commit 90f496a
Showing
19 changed files
with
730 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
version: 2.1 | ||
executors: | ||
docker-executor: | ||
docker: | ||
- image: circleci/openjdk:8-stretch | ||
jobs: | ||
build: | ||
executor: docker-executor | ||
steps: | ||
- checkout | ||
- restore_cache: | ||
key: gradle-{{ checksum "build.gradle.kts" }} | ||
- run: | ||
name: Build and test | ||
command: ./gradlew -q build | ||
- save_cache: | ||
paths: | ||
- ~/.gradle | ||
key: gradle-{{ checksum "build.gradle.kts" }} | ||
- store_test_results: | ||
path: build/test-results/ | ||
publish-tag: | ||
executor: docker-executor | ||
steps: | ||
- checkout | ||
- restore_cache: | ||
key: gradle-{{ checksum "build.gradle.kts" }} | ||
- run: | ||
name: Build image and push to repository | ||
command: ./gradlew -q jib | ||
- save_cache: | ||
paths: | ||
- ~/.gradle | ||
key: gradle-{{ checksum "build.gradle.kts" }} | ||
workflows: | ||
version: 2 | ||
build: | ||
jobs: | ||
- build | ||
build-and-publish-tags: | ||
jobs: | ||
- build: | ||
filters: | ||
tags: | ||
only: /^v.*/ | ||
branches: | ||
ignore: /.*/ | ||
- publish-tag: | ||
context: org-global | ||
requires: | ||
- build | ||
filters: | ||
tags: | ||
only: /^v.*/ | ||
branches: | ||
ignore: /.*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# Compiled class file | ||
*.class | ||
|
||
# Log file | ||
*.log | ||
|
||
# BlueJ files | ||
*.ctxt | ||
|
||
# Mobile Tools for Java (J2ME) | ||
.mtj.tmp/ | ||
|
||
# Package Files # | ||
*.jar | ||
*.war | ||
*.nar | ||
*.ear | ||
*.zip | ||
*.tar.gz | ||
*.rar | ||
|
||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml | ||
hs_err_pid* | ||
|
||
.gradle | ||
/build/ | ||
*/build/ | ||
|
||
# Ignore Gradle GUI config | ||
gradle-app.setting | ||
|
||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) | ||
!gradle-wrapper.jar | ||
|
||
# Cache of project | ||
.gradletasknamecache | ||
|
||
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 | ||
# gradle/wrapper/gradle-wrapper.properties | ||
|
||
# User-specific stuff | ||
.idea/**/workspace.xml | ||
.idea/**/tasks.xml | ||
.idea/**/usage.statistics.xml | ||
.idea/**/dictionaries | ||
.idea/**/shelf | ||
|
||
# Generated files | ||
.idea/**/contentModel.xml | ||
|
||
# Sensitive or high-churn files | ||
.idea/**/dataSources/ | ||
.idea/**/dataSources.ids | ||
.idea/**/dataSources.local.xml | ||
.idea/**/sqlDataSources.xml | ||
.idea/**/dynamic.xml | ||
.idea/**/uiDesigner.xml | ||
.idea/**/dbnavigator.xml | ||
|
||
# Gradle | ||
.idea/**/gradle.xml | ||
.idea/**/libraries | ||
|
||
# Gradle and Maven with auto-import | ||
# When using Gradle or Maven with auto-import, you should exclude module files, | ||
# since they will be recreated, and may cause churn. Uncomment if using | ||
# auto-import. | ||
# .idea/modules.xml | ||
# .idea/*.iml | ||
# .idea/modules | ||
|
||
# CMake | ||
cmake-build-*/ | ||
|
||
# Mongo Explorer plugin | ||
.idea/**/mongoSettings.xml | ||
|
||
# File-based project format | ||
*.iws | ||
|
||
# IntelliJ | ||
out/ | ||
|
||
# mpeltonen/sbt-idea plugin | ||
.idea_modules/ | ||
|
||
# JIRA plugin | ||
atlassian-ide-plugin.xml | ||
|
||
# Cursive Clojure plugin | ||
.idea/replstate.xml | ||
|
||
# Crashlytics plugin (for Android Studio and IntelliJ) | ||
com_crashlytics_export_strings.xml | ||
crashlytics.properties | ||
crashlytics-build.properties | ||
fabric.properties | ||
|
||
# Editor-based Rest Client | ||
.idea/httpRequests | ||
|
||
# Android studio 3.1+ serialized cache file | ||
.idea/caches/build_file_checksums.ser |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,126 @@ | ||
# kotlin-jib | ||
Containerising Kotlin with Jib | ||
# Containerising Kotlin with Jib | ||
|
||
Writing a `Dockerfile` to containerise an application can often be a non-trivial task. Many times I've spent hours fiddling with different base images and configurations and never being quite satisfied with the result. Well I recently tried [Jib](https://github.com/GoogleContainerTools/jib), one of Google's container tools, and I love it! It builds optimised Docker and [Open Container Initiative (OCI)](https://github.com/opencontainers/image-spec) spec images for JVM applications. For containerising JVM apps I will definitely try and use Jib where possible in future. | ||
|
||
## Jib images are distroless! | ||
|
||
I had been interested in trying [Google's "Distroless" Docker images](https://github.com/GoogleContainerTools/distroless) for a while, and so it was great to read that Jib uses these as base images by default. "Distroless" images are stripped down to the bare essentials. They contain only the application and its runtime dependencies. There is no bloat from unnecessary programs, shells, package managers, etc. | ||
|
||
## Jib images are reproducible | ||
|
||
The layers, metadata, files and directories are all added to the image by Jib in a consistent order. Additionally, timestamps of all files and directories are set to one second after the Epoch, and the image creation time is set exactly to the Epoch. This makes the image build process deterministic and able to rebuild layers so that they have the exact same digest each time. | ||
|
||
Don't be surprised that it reports the image was created 49+ years ago—it's for reproducibility! | ||
```bash | ||
REPOSITORY TAG IMAGE ID CREATED SIZE | ||
peterevans/webservice 0.1 493233af1b87 49 years ago 137MB | ||
peterevans/webservice 0.1.0 493233af1b87 49 years ago 137MB | ||
peterevans/webservice latest 493233af1b87 49 years ago 137MB | ||
``` | ||
|
||
The result is that Jib produces lean, efficient and reproducible images that have a number of benefits. | ||
- An accurate diff of changes and provenance between image releases becomes much less of a burden | ||
- Reduced attack surface | ||
- Improves the signal to noise ratio of vulnerability scanners | ||
|
||
## Using Jib with Gradle's Kotlin DSL | ||
|
||
Here is a quick introduction of how to use Jib with Gradle's Kotlin DSL. A complete example project is contained in this repository. | ||
|
||
First add the plugin to `build.gradle.kts` | ||
```kotlin | ||
plugins { | ||
id("com.google.cloud.tools.jib") version "1.3.0" | ||
} | ||
``` | ||
|
||
Add a configuration section for Jib to `build.gradle.kts` specifying the image name. Don't forget to prefix with the registry host for pushing to registries other than `io.dockerhub`. | ||
```kotlin | ||
jib { | ||
to { | ||
image = "peterevans/webservice" | ||
} | ||
} | ||
``` | ||
|
||
The `jib` gradle task will build and push to the registry. You might also need to specify an [authentication method](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#authentication-methods). This is the preferred way to build jib images as it is daemonless. There is no requirement for your CI environment to be running the Docker daemon. | ||
|
||
```bash | ||
gradle jib | ||
``` | ||
|
||
The `jibDockerBuild` gradle task will build the image and load it into the Docker daemon. This can be useful if during your CI release process you want to [smoke test](https://peterevans.dev/posts/smoke-testing-containers/) the image after being built but before being pushed to the registry. | ||
```bash | ||
gradle jibDockerBuild | ||
``` | ||
|
||
## Image Configuration | ||
|
||
### Tags | ||
|
||
By default, Jib builds every image with no tag, meaning it will always produce an image with the default tag `latest`. A set of additional tags can be added under `jib.to.tags`. The following example tags the image with a `major.minor` version and a `major.minor.build` version. | ||
|
||
```kotlin | ||
version = "0.1" | ||
val buildNumber by extra("0") | ||
|
||
jib { | ||
to { | ||
image = "peterevans/webservice" | ||
tags = setOf("$version", "$version.${extra["buildNumber"]}") | ||
} | ||
} | ||
``` | ||
|
||
### Labels | ||
Labels can be specified as a map under `jib.container.labels` as follows. | ||
```kotlin | ||
jib { | ||
container { | ||
labels = mapOf( | ||
"maintainer" to "Peter Evans <mail@peterevans.dev>", | ||
"org.opencontainers.image.title" to "webservice", | ||
"org.opencontainers.image.description" to "An example webservice", | ||
"org.opencontainers.image.version" to "$version", | ||
"org.opencontainers.image.authors" to "Peter Evans <mail@peterevans.dev>", | ||
"org.opencontainers.image.url" to "https://github.com/peter-evans/kotlin-jib", | ||
"org.opencontainers.image.vendor" to "https://peterevans.dev", | ||
"org.opencontainers.image.licenses" to "MIT" | ||
) | ||
} | ||
} | ||
``` | ||
|
||
### Further Container Configuration | ||
|
||
You can customise almost everything about the image including JVM flags, environment variables, volumes, ports, etc. Further configuration options can be found in the documentation [here](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin). | ||
|
||
```kotlin | ||
jib { | ||
container { | ||
jvmFlags = listOf( | ||
"-server", | ||
"-Djava.awt.headless=true", | ||
"-XX:InitialRAMFraction=2", | ||
"-XX:MinRAMFraction=2", | ||
"-XX:MaxRAMFraction=2", | ||
"-XX:+UseG1GC", | ||
"-XX:MaxGCPauseMillis=100", | ||
"-XX:+UseStringDeduplication" | ||
) | ||
environment = mapOf( | ||
"USERNAME" to "user1", | ||
"PASSWORD" to "1234") | ||
workingDirectory = "/webservice" | ||
volumes = listOf("/data") | ||
ports = listOf("8080") | ||
args = listOf("--help") | ||
} | ||
} | ||
``` | ||
|
||
See the code in this repository for a more complete example of using Jib to containerise Kotlin. | ||
|
||
## License | ||
|
||
MIT License - see the [LICENSE](LICENSE) file for details |
Oops, something went wrong.