Git Product home page Git Product logo

docker-spk's Introduction

docker-spk is a tool to develop sandstorm packages using Docker to build the root filesystems.

It is a work in progress, but already supports converting docker images to sandstorm packages (.spk files), and signing and populating them with metadata based on sandstorm-pkgdef.capnp.

Note that:

  • It is not possible to automatically convert an arbitrary Docker image and have it work; the filesystem must be constructed to behave correctly inside Sandstorm's sandbox environment.
  • Docker is only used to build the root filesystem of the app. Accordingly, Dockerfile instructions like CMD, EXPOSE, STOPSIGNAL, etc, which do not modify the image's filesystem, have no effect on the app. For other forms of customization, edit sandstorm-pkgdef.capnp.

Installing

In addition to docker-spk itself, you will also need the capnp command line tool somewhere in your $PATH; see the Cap'n Proto documentation for setup.

From Pre-Built Binaries

The releases page distributes tar archives containing x86_64 binaries of docker-spk for Linux and MacOS; extract the archive, and place the appropriate

From Source

  1. Install Go 1.11 or later.
  2. From the root of the source tree, run:
go build

This will create an executable ./docker-spk; place it somewhere in your $PATH.

Quick Start

First, generate a sandstorm-pkgdef.capnp in the current directory:

docker-spk init

The tool will automatically generate a keypair for your app, and save it in your keyring (by default ~/.sandstorm-keyring, but this can be overridden with the -keyring flag).

Edit the file to match your app. In particular, you will want to change the command used to launch the app, near the bottom of the file.

Then, create a Dockerfile in the current directory, which will be responsible for building the filesystem for your app. Finally, from the directory containing Dockerfile and sandstorm-pkgdef.capnp, run:

docker-spk build

This will build the docker image and then package it into a .spk file. with the name derived from the app name and version defined in sandstorm-manifest.capnp.

Alternatively, you can package an already-built docker image:

docker-spk pack -image <image-name>

...to use the image <image-name>, fetched from a running Docker daemon.

This will skip the build step and just create the .spk.

You can also use docker save to fetch the image manually and specify the file name via -imagefile:

docker save my-image > my-image.tar
docker-spk pack -imagefile my-image.tar

Examples

The examples/ directory contains some examples that may be useful in seeing how to package apps with docker-spk.

Reference

See docker-spk -h.

License

Apache 2.0, see COPYING.

docker-spk's People

Contributors

rs22 avatar zenhack avatar zombiezen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

docker-spk's Issues

"undefined" errors

Hi Ian,

If I clone this repository and then run go build, I get a few undefined errors regarding zenhack.net/go/sandstorm/exp/spk. To make sure it's not just something about my system, I was able to reproduce this error in the golang:latest Docker container:

root@4bcb8d9b7641:/go/docker-spk# go build
go: downloading zenhack.net/go/sandstorm v0.0.0-20200724231323-be1af19658ec
go: downloading zombiezen.com/go/capnproto2 v2.17.1-0.20180404044107-e89f9b7f0213+incompatible
go: downloading github.com/ulikunitz/xz v0.5.7
go: downloading golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899
# zenhack.net/go/docker-spk
./init.go:12:17: undefined: "zenhack.net/go/sandstorm/exp/spk".NewApp
./metadata.go:21:17: undefined: "zenhack.net/go/sandstorm/exp/spk".ReadPackageDefinition

and no docker-spk output file results.

Can't use distroless as base

I'm hitting a rather strange issue when trying to package a Sandstorm application with docker-spk and the distroless Docker base image. It seems as though docker-spk is archiving files as directories, which is causing strange problems for Sandstorm.

Reproduction Steps

  1. git clone https://github.com/zombiezen/sandpass.git && cd sandpass
  2. git checkout 269c5d57b2e2ac982d5317b86fa8de2870b51ead (current master)
  3. spk keygen to get a temporary dev key
  4. Paste in the key into sandstorm-pkgdef.capnp and remove the PGP signature bits.
  5. docker-spk build -appkey $KEY
  6. Upload the SPK to a Sandstorm server and create a new grain.

Expected Result

A running instance of Sandpass.

Actual Result

Grain doesn't start up successfully, instead producing the following debug log:

** SANDSTORM SUPERVISOR: Starting up grain. Sandbox type: privileged
*** Uncaught exception ***
sandstorm/sandstorm-http-bridge.c++:2534: failed: execvp(argvp[0], argvp): Permission denied; argvp[0] = /opt/app/sandpass
stack: 516d6c 5b1293
** HTTP-BRIDGE: App server exited with status code: 1
** SANDSTORM SUPERVISOR: App exited with status code: 1

Observations so far

  • Running this Docker image outside of Sandstorm will start up perfectly fine: docker build -t sandpass . && docker run --rm -p 8080:8080 sandpass
  • This has passing similarity to sandstorm-io/sandstorm#1577, but it's different. sandstorm-http-bridge will throw the error shown above if execve(2) returns EACCES. To the best of my knowledge, I do not believe this to be a permissions problem: running spk unpack on the resulting SPK will show that the parent directories and the binary all have the execute bit set.
  • Now here's the interesting part: if you switch the FROM line to be FROM debian:stretch-slim, the server starts up just fine. This seems odd, since if you look at my old sandstorm-files.list, there aren't that many files that were being brought in to begin with.
  • So this got me into thinking, what's different about the libraries in the distroless image? I looked back at the spk unpack directory and discovered that most all of the "files" in the SPK are actually directories:
$ spk unpack Sandpass-1.0.0.spk foo
$ cd foo
$ find . -type f | grep -v 'opt/app'
./sandstorm-http-bridge
./sandstorm-http-bridge-config
./sandstorm-manifest
./usr/share/dict/words
$ ls -l lib64
total 0
drwxr-xr-x 1 rlight2 rlight2 0 Dec 31  1969 ld-linux-x86-64.so.2
# ruh roh

My suspicion here is that there's something that is unique about the distroless image that is tripping up docker-spk.

docker-spk version

1.1

Canonicalize messages in .spk file (for better reproducability of package files).

It would be nice to convert the two messages in the output .spk into capnproto canonical form. This would reduce the number of things that might cause a package to not be reproducible, since it means that e.g. if we upgrade to a newer version of the capnproto library, changes in how it allocates values inside of a message will affect the final output. We already sort the names of files in a directory, so value-significant details of a package archive should already only depend on the actual filesystem in the docker image. Besides this, the only other variable is the details of what our xz compression library does.

The canonicalization function strips off the message header, returning just a segment, so we will have to add that back to conform to the spk format, but this is easy enough to do by hand.

Copy bridgeConfig (if present) into the package.

sandstorm-http-bridge requires its own configuration, separate from the rest of the sandstorm manifest:

https://github.com/zenhack/docker-spk/blob/master/sandstorm-pkgdef.capnp.template#L137

It expects this to be present in the filesystem at /sandstorm-http-bridge-config:

https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/sandstorm-http-bridge.c%2B%2B#L2559

If it is defined inside sandstorm-pkgdef.capnp, we should copy it into the archive, just like we're doing with sandstorm-manifest.

Build suitable base images.

We will want some base docker images that folks can work from when developing apps; probably something that comes with sandstorm-http-bridge, and we may want to try to replicate vagrant-spk's stacks.

Path to sandstorm keyring

The path to the sandstorm keyring is set to /Users/{$user}/.sandstorm-keyring by default (example from macOS). But according to my experience it should be /Users/{$user}/.sandstorm/sandstorm-keyring. The spk command and also vagrant-spk are using this path too.

Exctract Docker images directly from Docker.

Right now the user has to call docker save themselves; we should make it possible to just specify an image name and then extract the image from a running docker daemon ourselves (by calling out to docker save).

Docker-SPK in Build pipeline

Hey @zenhack, do you think it would be possible to use docker-spk in a build pipeline? Right now it’s build to run with a local installation of docker and the tool itself. Would be interesting to have that in an automated pipeline too. I’m not yet sure how that could look like. That’s why I’m asking for your opinion.

Option to output contents to directory, skipping compression

It would be nice if one could choose a lower compression ratio for the xz compression to speed it up. In my case, I immediately spk unpack the resulting spk (in order to spk dev, but also for the fake-proc trick), so there is no sense in waiting for it to achieve maximum compression -- it only serves to slow down the development/test cycle.

Reproducible builds

Per discussion in #3, I'd like to get a reproducible build process working and documented, so I can comfortably release binaries for users who don't want to build from source.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.