Skip to content

Commit 870786d

Browse files
committed
global state location option and various minor fixes
1 parent bfe1202 commit 870786d

File tree

15 files changed

+127
-78
lines changed

15 files changed

+127
-78
lines changed

README.md

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[![Go Report Card](https://goreportcard.com/badge/github.com/cloudimmunity/docker-slim)](https://goreportcard.com/report/github.com/cloudimmunity/docker-slim)
2+
13
# docker-slim: Lean and Mean Docker containers
24

35
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
@@ -6,7 +8,7 @@
68

79
- [docker-slim: Lean and Mean Docker containers](#docker-slim-lean-and-mean-docker-containers)
810
- [DESCRIPTION](#description)
9-
- [NEW](#new)
11+
- [RECENT UPDATES](#new)
1012
- [INSTALLATION](#installation)
1113
- [BASIC USAGE INFO](#basic-usage-info)
1214
- [QUICK SECCOMP EXAMPLE](#quick-seccomp-example)
@@ -50,10 +52,11 @@ Creating small containers requires a lot of voodoo magic and it can be pretty pa
5052

5153
`docker-slim` is a magic diet pill for your containers :) It will use static and dynamic analysis to create a skinny container for your app.
5254

53-
## NEW
55+
## RECENT UPDATES
5456

55-
Latest version: 1.14 (3/13/2016)
57+
Latest version: 1.15 (6/19/2016)
5658

59+
* User selected location to store DockerSlim state (global `--state-path` parameter).
5760
* Auto-generated seccomp profiles for Docker 1.10.
5861
* Python 3 support
5962
* Docker connect options
@@ -63,8 +66,8 @@ Latest version: 1.14 (3/13/2016)
6366
## INSTALLATION
6467

6568
1. Download the zip package for your platform.
66-
- [Latest Mac binaries](https://github.com/cloudimmunity/docker-slim/releases/download/1.14/dist_mac.zip)
67-
- [Latest Linux binaries](https://github.com/cloudimmunity/docker-slim/releases/download/1.14/dist_linux.zip)
69+
- [Latest Mac binaries](https://github.com/cloudimmunity/docker-slim/releases/download/1.15/dist_mac.zip)
70+
- [Latest Linux binaries](https://github.com/cloudimmunity/docker-slim/releases/download/1.15/dist_linux.zip)
6871
2. Unzip the package.
6972
3. Add the location where you unzipped the package to your PATH environment variable (optional).
7073

@@ -100,7 +103,7 @@ You can use the generated Seccomp profile with your original image or with the m
100103

101104
You can use the generated profile with your original image or with the minified image DockerSlim created:
102105

103-
`docker run --security-opt seccomp:path_to/my-sample-node-app-seccomp.json -p 8000:8000 my/sample-node-app.slim`
106+
`docker run -it --rm --security-opt seccomp:path_to/my-sample-node-app-seccomp.json -p 8000:8000 my/sample-node-app.slim`
104107

105108
## ORIGINAL DEMO VIDEO
106109

@@ -112,52 +115,52 @@ You can use the generated profile with your original image or with the minified
112115

113116
The demo run on Mac OS X, but you can build a linux version. Note that these steps are different from the steps in the demo video.
114117

115-
0. Get the docker-slim [Mac](https://github.com/cloudimmunity/docker-slim/releases/download/1.14/dist_mac.zip) or [Linux](https://github.com/cloudimmunity/docker-slim/releases/download/1.14/dist_linux.zip) binaries. Unzip them and optionally add their directory to your PATH environment variable if you want to use the app from other locations.
118+
1. Get the docker-slim [Mac](https://github.com/cloudimmunity/docker-slim/releases/download/1.15/dist_mac.zip) or [Linux](https://github.com/cloudimmunity/docker-slim/releases/download/1.15/dist_linux.zip) binaries. Unzip them and optionally add their directory to your PATH environment variable if you want to use the app from other locations.
116119

117-
The extracted directory contains two binaries:
120+
The extracted directory contains two binaries:
118121

119-
* `docker-slim` <- the main application
120-
* `docker-slim-sensor` <- the sensor application used to collect information from running containers
122+
* `docker-slim` <- the main application
123+
* `docker-slim-sensor` <- the sensor application used to collect information from running containers
121124

122-
1. Clone this repo to use the sample apps. You can skip this step if you have your own app.
125+
2. Clone this repo to use the sample apps. You can skip this step if you have your own app.
123126

124-
`git clone https://github.com/cloudimmunity/docker-slim.git`
127+
`git clone https://github.com/cloudimmunity/docker-slim.git`
125128

126-
2. Create a Docker image for the sample node.js app in `sample/apps/node`. You can skip this step if you have your own app.
129+
3. Create a Docker image for the sample node.js app in `sample/apps/node`. You can skip this step if you have your own app.
127130

128-
`cd docker-slim/sample/apps/node`
131+
`cd docker-slim/sample/apps/node`
129132

130-
`eval "$(docker-machine env default)"` <- optional (depends on how Docker is installed on your machine); if the Docker host is not running you'll need to start it first: `docker-machine start default`; see the `Docker connect options` section for more details.
133+
`eval "$(docker-machine env default)"` <- optional (depends on how Docker is installed on your machine); if the Docker host is not running you'll need to start it first: `docker-machine start default`; see the `Docker connect options` section for more details.
131134

132-
`docker build -t my/sample-node-app .`
135+
`docker build -t my/sample-node-app .`
133136

134-
3. Run `docker-slim`:
137+
4. Run `docker-slim`:
135138

136-
`./docker-slim build --http-probe my/sample-node-app` <- run it from the location where you extraced the docker-slim binaries (or update your PATH env var to include the `docker-slim` bin directory)
139+
`./docker-slim build --http-probe my/sample-node-app` <- run it from the location where you extraced the docker-slim binaries (or update your PATH env var to include the `docker-slim` bin directory)
137140

138-
DockerSlim creates a special container based on the target image you provided. It also creates a resource directory where it stores the information it discovers about your image: `<docker-slim directory>/.images/<TARGET_IMAGE_ID>`.
141+
DockerSlim creates a special container based on the target image you provided. It also creates a resource directory where it stores the information it discovers about your image: `<docker-slim directory>/.images/<TARGET_IMAGE_ID>`.
139142

140-
4. Use curl (or other tools) to call the sample app (optional)
143+
5. Use curl (or other tools) to call the sample app (optional)
141144

142-
`curl http://<YOUR_DOCKER_HOST_IP>:<PORT>`
145+
`curl http://<YOUR_DOCKER_HOST_IP>:<PORT>`
143146

144-
This is an optional step to make sure the target app container is doing something. Depending on the application it's an optional step. For some applications it's required if it loads new application resources dynamically based on the requests it's processing.
147+
This is an optional step to make sure the target app container is doing something. Depending on the application it's an optional step. For some applications it's required if it loads new application resources dynamically based on the requests it's processing.
145148

146-
You can get the port number either from the `docker ps` or `docker port <CONTAINER_ID>` commands. The current version of DockerSlim doesn't allow you to map exposed network ports (it works like `docker run … -P`).
149+
You can get the port number either from the `docker ps` or `docker port <CONTAINER_ID>` commands. The current version of DockerSlim doesn't allow you to map exposed network ports (it works like `docker run … -P`).
147150

148-
If you set the `http-probe` flag then `docker-slim` will try to call your application using HTTP/HTTPS: `./docker-slim build --http-probe my/sample-node-app`
151+
If you set the `http-probe` flag then `docker-slim` will try to call your application using HTTP/HTTPS: `./docker-slim build --http-probe my/sample-node-app`
149152

150-
5. Press <enter> and wait until `docker-slim` says it's done
153+
6. Press <enter> and wait until `docker-slim` says it's done
151154

152-
6. Once DockerSlim is done check that the new minified image is there
155+
7. Once DockerSlim is done check that the new minified image is there
153156

154-
`docker images`
157+
`docker images`
155158

156-
You should see `my/sample-node-app.slim` in the list of images. Right now all generated images have `.slim` at the end of its name.
159+
You should see `my/sample-node-app.slim` in the list of images. Right now all generated images have `.slim` at the end of its name.
157160

158-
7. Use the minified image
161+
8. Use the minified image
159162

160-
`docker run --name="slim_node_app" -p 8000:8000 my/sample-node-app.slim`
163+
`docker run -it --rm --name="slim_node_app" -p 8000:8000 my/sample-node-app.slim`
161164

162165
## USAGE DETAILS
163166

@@ -171,11 +174,13 @@ Commands:
171174

172175
Global options:
173176

177+
* ` --version` - print the version
174178
* ` --debug` - enable debug logs
175179
* `--host` - Docker host address
176180
* `--tls` - use TLS connecting to Docker
177181
* `--tls-verify` - do TLS verification
178182
* `--tls-cert-path` - path to TLS cert files
183+
* `--state-path value` - DockerSlim state base path (must set it if the DockerSlim binaries are not in a writable directory!)
179184

180185
### `BUILD` COMMAND OPTIONS
181186

@@ -257,7 +262,8 @@ Commands in `probeCmds.json`:
257262
{
258263
"protocol": "http",
259264
"method": "POST",
260-
"resource": "/submit2"
265+
"resource": "/submit2",
266+
"body": "key=value"
261267
}
262268
]
263269
}
@@ -299,11 +305,11 @@ You can also run `docker-slim` in the `info` mode and it'll generate useful imag
299305

300306
DockerSlim now also generates Seccomp (usable) and AppArmor (WIP) profiles for your container.
301307

302-
Works with Docker 1.8, 1.9 and 1.10.
308+
Works with Docker 1.8, 1.9, 1.10 and 1.11.
303309

304310
Note:
305311

306-
You don't need Docker 1.10 to generate Seccomp profiles, but you do need it if you want to use the generated profiles.
312+
You don't need Docker 1.10 or above to generate Seccomp profiles, but you do need it if you want to use the generated profiles.
307313

308314
## FAQ
309315

@@ -329,9 +335,9 @@ You can explore the artifacts DockerSlim generates when it's creating a slim ima
329335

330336
If you'd like to see the artifacts without running `docker-slim` you can take a look at the `sample/artifacts` directory in this repo. It doesn't include any image files, but you'll find:
331337

332-
* a reverse engineered Dockerfile (`Dockerfile.fat`)
333-
* a container report file (`creport.json`)
334-
* a sample AppArmor profile (which will be named based on your original image name)
338+
* a reverse engineered Dockerfile (`Dockerfile.fat`)
339+
* a container report file (`creport.json`)
340+
* a sample AppArmor profile (which will be named based on your original image name)
335341
* and a sample Seccomp profile
336342

337343
If you don't want to create a minified image and only want to "reverse engineer" the Dockerfile you can use the `info` command.
@@ -452,4 +458,4 @@ Docker Hub: [dslim](https://hub.docker.com/r/dslim/) (dockerslim is already take
452458

453459
## NOTES
454460

455-
* The code is still not very pretty at this point in time :)
461+
* The code is still not very pretty, so feel free to make improvements and submit your PRs :)

apps/docker-slim-sensor/artifacts.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ func cpFile(src, dst string) error {
362362
func py3FileNameFromCache(p string) string {
363363
ext := path.Ext(p)
364364

365-
if !(((ext == pycExt) || (ext == pycExt)) && strings.Contains(p, pycacheDir)) {
365+
if !(((ext == pycExt) || (ext == pyoExt)) && strings.Contains(p, pycacheDir)) {
366366
return ""
367367
}
368368

apps/docker-slim/cli.go

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"fmt"
55
"os"
6+
"runtime"
67
"strconv"
78
"time"
89

@@ -23,7 +24,7 @@ var app *cli.App
2324

2425
func init() {
2526
app = cli.NewApp()
26-
app.Version = fmt.Sprintf("%v|%v|%v|%v", consts.APP_VERSION_NAME, appVersionTag, appVersionRev, appVersionTime)
27+
app.Version = fmt.Sprintf("%v|%v|%v|%v|%v", runtime.GOOS, consts.APP_VERSION_NAME, appVersionTag, appVersionRev, appVersionTime)
2728
app.Name = APP_NAME
2829
app.Usage = APP_USAGE
2930
app.CommandNotFound = func(ctx *cli.Context, command string) {
@@ -63,6 +64,11 @@ func init() {
6364
Value: "",
6465
Usage: "Docker host address",
6566
},
67+
cli.StringFlag{
68+
Name: "state-path",
69+
Value: "",
70+
Usage: "DockerSlim state base path",
71+
},
6672
}
6773

6874
app.Before = func(ctx *cli.Context) error {
@@ -186,17 +192,20 @@ func init() {
186192
Name: "info",
187193
Aliases: []string{"i"},
188194
Usage: "Collects fat image information and reverse engineers its Dockerfile",
189-
Action: func(ctx *cli.Context) {
195+
Action: func(ctx *cli.Context) error {
190196
if len(ctx.Args()) < 1 {
191197
fmt.Printf("[info] missing image ID/name...\n\n")
192198
cli.ShowCommandHelp(ctx, "info")
193-
return
199+
return nil
194200
}
195201

202+
statePath := ctx.GlobalString("state-path")
203+
196204
imageRef := ctx.Args().First()
197205
clientConfig := getDockerClientConfig(ctx)
198206

199-
commands.OnInfo(clientConfig, imageRef)
207+
commands.OnInfo(statePath, clientConfig, imageRef)
208+
return nil
200209
},
201210
},
202211
{
@@ -236,13 +245,15 @@ func init() {
236245
doUseMountFlag,
237246
doConfinueAfterFlag,
238247
},
239-
Action: func(ctx *cli.Context) {
248+
Action: func(ctx *cli.Context) error {
240249
if len(ctx.Args()) < 1 {
241250
fmt.Printf("[build] missing image ID/name...\n\n")
242251
cli.ShowCommandHelp(ctx, "build")
243-
return
252+
return nil
244253
}
245254

255+
statePath := ctx.GlobalString("state-path")
256+
246257
imageRef := ctx.Args().First()
247258
clientConfig := getDockerClientConfig(ctx)
248259
doRmFileArtifacts := ctx.Bool("remove-file-artifacts")
@@ -252,7 +263,7 @@ func init() {
252263
httpProbeCmds, err := getHttpProbes(ctx)
253264
if err != nil {
254265
fmt.Printf("[build] invalid HTTP probes: %v\n", err)
255-
return
266+
return err
256267
}
257268

258269
if len(httpProbeCmds) > 0 {
@@ -266,13 +277,13 @@ func init() {
266277
overrides, err := getContainerOverrides(ctx)
267278
if err != nil {
268279
fmt.Printf("[build] invalid container overrides: %v\n", err)
269-
return
280+
return err
270281
}
271282

272283
volumeMounts, err := parseVolumeMounts(ctx.StringSlice("mount"))
273284
if err != nil {
274285
fmt.Printf("[build] invalid volume mounts: %v\n", err)
275-
return
286+
return err
276287
}
277288

278289
excludePaths := parsePaths(ctx.StringSlice("exclude-path"))
@@ -288,17 +299,18 @@ func init() {
288299
confinueAfter, err := getContinueAfter(ctx)
289300
if err != nil {
290301
fmt.Printf("[build] invalid continue-after mode: %v\n", err)
291-
return
302+
return err
292303
}
293304

294305
for ipath, _ := range includePaths {
295306
if excludePaths[ipath] {
296307
fmt.Printf("[build] include and exclude path conflict: %v\n", err)
297-
return
308+
return nil
298309
}
299310
}
300311

301312
commands.OnBuild(ctx.GlobalBool("debug"),
313+
statePath,
302314
clientConfig,
303315
imageRef, doTag,
304316
doHttpProbe, httpProbeCmds,
@@ -307,6 +319,8 @@ func init() {
307319
overrides,
308320
volumeMounts, excludePaths, includePaths,
309321
confinueAfter)
322+
323+
return nil
310324
},
311325
},
312326
{
@@ -329,21 +343,23 @@ func init() {
329343
doUseMountFlag,
330344
doConfinueAfterFlag,
331345
},
332-
Action: func(ctx *cli.Context) {
346+
Action: func(ctx *cli.Context) error {
333347
if len(ctx.Args()) < 1 {
334348
fmt.Printf("[profile] missing image ID/name...\n\n")
335349
cli.ShowCommandHelp(ctx, "profile")
336-
return
350+
return nil
337351
}
338352

353+
statePath := ctx.GlobalString("state-path")
354+
339355
imageRef := ctx.Args().First()
340356
clientConfig := getDockerClientConfig(ctx)
341357
doHttpProbe := ctx.Bool("http-probe")
342358

343359
httpProbeCmds, err := getHttpProbes(ctx)
344360
if err != nil {
345361
fmt.Printf("[profile] invalid HTTP probes: %v\n", err)
346-
return
362+
return err
347363
}
348364

349365
if len(httpProbeCmds) > 0 {
@@ -354,13 +370,13 @@ func init() {
354370
overrides, err := getContainerOverrides(ctx)
355371
if err != nil {
356372
fmt.Printf("[profile] invalid container overrides: %v", err)
357-
return
373+
return err
358374
}
359375

360376
volumeMounts, err := parseVolumeMounts(ctx.StringSlice("mount"))
361377
if err != nil {
362378
fmt.Printf("[profile] invalid volume mounts: %v\n", err)
363-
return
379+
return err
364380
}
365381

366382
excludePaths := parsePaths(ctx.StringSlice("exclude-path"))
@@ -376,23 +392,26 @@ func init() {
376392
confinueAfter, err := getContinueAfter(ctx)
377393
if err != nil {
378394
fmt.Printf("[profile] invalid continue-after mode: %v\n", err)
379-
return
395+
return err
380396
}
381397

382398
for ipath, _ := range includePaths {
383399
if excludePaths[ipath] {
384400
fmt.Printf("[profile] include and exclude path conflict: %v\n", err)
385-
return
401+
return nil
386402
}
387403
}
388404

389405
commands.OnProfile(ctx.GlobalBool("debug"),
406+
statePath,
390407
clientConfig,
391408
imageRef,
392409
doHttpProbe, httpProbeCmds,
393410
doShowContainerLogs, overrides,
394411
volumeMounts, excludePaths, includePaths,
395412
confinueAfter)
413+
414+
return nil
396415
},
397416
},
398417
}

0 commit comments

Comments
 (0)