Skip to content

Commit c7a8306

Browse files
committed
Update README
1 parent 96810b8 commit c7a8306

File tree

4 files changed

+43
-36
lines changed

4 files changed

+43
-36
lines changed

Makefile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ build-image:
3737
shell:
3838
docker run --rm -ti -u root -v `pwd`:/workspace --entrypoint=/bin/sh $(IMAGE)
3939

40-
push-image: build
41-
docker tag $(IMAGE):$(TAG) $(REMOTE)/$(IMAGE):$(TAG)
42-
docker push $(REMOTE)/$(IMAGE):$(TAG)
40+
push-image: build-image
41+
docker push $(IMAGE):$(TAG)
4342

4443
attach:
4544
@docker exec -ti $(CONT) /bin/bash

README.md

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
11
# Introduction
2-
This project teaches Docker some IPFS. IPFS is a global, versioned, peer-to-peer filesystem. It combines good ideas from Git, BitTorrent, Kademlia, SFS, and the Web. It is like a single bittorrent swarm, exchanging git objects.
2+
This project teaches Docker some IPFS. IPFS is a global, versioned, peer-to-peer filesystem. IPFS combines good ideas from Git, BitTorrent, Kademlia, SFS, and the Web. It is like a single bittorrent swarm, exchanging git objects.
33
[https://github.com/ipfs/go-ipfs]
44

55
image2ipfs works only with images prduced docker >= 1.10. On the bright side, all post-1.6 dockers can pull from an ipfs-registry.
66

77
# How does it work?
8+
89
image2ipfs takes an image archive produced using `docker save`.
910
The archive is extracted to a temp location then processed a bit. Finally, it is added to IPFS using `ipfs add -r`
1011
(you need to have the ipfs binary in your `PATH`). For a simple busybox image
11-
image2ipfs will produce something like this:
12+
image2ipfs will produce a work dir like this:
1213
```
1314
busybox
1415
├── blobs
1516
│   ├── sha256:193bda8d9ac77416619eb556391a9c5447adb2abf12aab515d1b0c754637eb80
1617
│   ├── sha256:47bcc53f74dc94b1920f0b34f6036096526296767650f223433fe65c35f149eb
1718
│   └── sha256:a1b1b81d3d1afdb8fe119b002318c12c20934713b9754a40f702adb18a2540b9
1819
└── manifests
19-
├── latest-v1
2020
└── latest-v2
2121
```
2222

23+
_v1 Manifests are not supported starting with version 0.0.6_
2324
But how do you get from something like QmQSF1oN4TXeU2kRvmjerEs62ZYfKPyRCqPvW1XTTc4fLS to a working `docker pull busybox`?
2425

2526
The answer is simple: using url rewriting. In the `registry/` subdirectory of the project
26-
there is a trivial Flask application that speaks the Registry v2 protocol but instead of serving the blobs and manifests it redirects
27+
there is a trivial Go application that speaks the Registry v2 protocol but instead of serving the blobs and manifests it redirects
2728
to an IPFS gateway of your choice.
2829

2930
When pulling REPO:latest (with REPO=busybox in this example), Docker daemon will issue these requests:
@@ -34,9 +35,14 @@ GET /v2/REPO/blobs/sha256:47bcc53f74dc94b1920f0b34f6036096526296767650f223433fe6
3435
GET /v2/REPO/blobs/sha256:193bda8d9ac77416619eb556391a9c5447adb2abf12aab515d1b0c754637eb80
3536
GET /v2/REPO/blobs/sha256:a1b1b81d3d1afdb8fe119b002318c12c20934713b9754a40f702adb18a2540b9
3637
```
37-
So somehow you need encode the IPFS hash in `REPO`, then use it on the server to redirect to https://ipfs.io/ipfs/{HASH}/{NAME}/manifest/latest-v1.
38-
See Section "Demo" bellow for how this plays.
3938

39+
All the Go app does is produce IPFS links to a an IPFS gateway and redirect docker there:
40+
```
41+
GET /ipfs/HASH/manifest/latest
42+
GET /ipfs/HASH/blobs/sha256:47bcc53f74dc94b1920f0b34f6036096526296767650f223433fe65c35f149eb
43+
GET /ipfs/HASH/blobs/sha256:193bda8d9ac77416619eb556391a9c5447adb2abf12aab515d1b0c754637eb80
44+
GET /ipfs/HASH/blobs/sha256:a1b1b81d3d1afdb8fe119b002318c12c20934713b9754a40f702adb18a2540b9
45+
```
4046

4147

4248
# Installation
@@ -48,33 +54,35 @@ $ cd image2ipfs
4854
$ make install
4955

5056
$ image2ipfs -v
51-
0.0.4
57+
0.0.6
5258
```
5359

54-
If someone else will be running an ipfs-registry then you can install image2ipfs using pip
60+
You can also install using pip
5561
```bash
5662
$ pip install image2ipfs
5763

5864
$ image2ipfs -v
59-
65+
0.0.6
6066
```
6167

6268
# Running the registry
63-
You can pull from dockerhub. The second command requires less configuration but is less flexible.
64-
```
65-
docker run -td --name ipfs-registry -e IPFS_GATEWAY=http://{public-ip}:8080 -p 5000:5000 jvassev/ipfs-registry
69+
You can pull the official image from dockerhub. This example assumes the gateway is running on localhost. Consider using another gateway address as image2ipfs will serve redirects to it.
6670

71+
```
6772
docker run -td --name ipfs-registry -e IPFS_GATEWAY=http://localhost:8080 --net host jvassev/ipfs-registry
6873
```
6974

7075
Or build from source:
7176
```bash
72-
cd image2ipfs/registry
73-
make build run IPFS_GATEWAY=http://localhost:8080
77+
# build image locally
78+
make build-image
79+
80+
# or install to $GOPATH/bin
81+
make install
7482
```
75-
This will start a flask application pretending to be a docker registry on http://localhost:5000
7683

7784
# Configure Docker
85+
7886
As usual add `--insecure-registry localhost:5000` to your docker daemon args
7987

8088
# Demo
@@ -98,7 +106,7 @@ Server:
98106
OS/Arch: linux/amd64
99107

100108
$ image2ipfs -v
101-
0.0.4
109+
0.0.6
102110

103111
$ docker pull centos:7
104112
7: Pulling from library/centos
@@ -143,16 +151,15 @@ Status: Image is up to date for localhost:5000/ciqn5zu57ciucp3gw2hwxymuwz3tgjlvf
143151

144152
$ docker history localhost:5000/ciqn5zu57ciucp3gw2hwxymuwz3tgjlvfdfwg3xhwx456y4xxydkhmq/centos
145153
IMAGE CREATED CREATED BY SIZE COMMENT
146-
778a53015523 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
147-
<missing> 4 weeks ago /bin/sh -c #(nop) LABEL name=CentOS Base Imag 0 B
148-
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:6dd89087d4d418ca0c 196.7 MB
149-
<missing> 7 months ago /bin/sh -c #(nop) MAINTAINER The CentOS Proje 0 B
154+
778a53015523 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
155+
<missing> 4 weeks ago /bin/sh -c #(nop) LABEL name=CentOS Base Imag 0 B
156+
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:6dd89087d4d418ca0c 196.7 MB
157+
<missing> 7 months ago /bin/sh -c #(nop) MAINTAINER The CentOS Proje 0 B
150158
```
151159

152160
Depending on how you have started the ipfs-registry the docker daemon will be redirected to an IPFS gateway of your choice. By default the registry
153161
will redirect to the ipfs daemon running locally (http://localhost:8080).
154162

155-
156163
But what is this "Dockerized hash ciqn5zu57ciucp3gw2hwxymuwz3tgjlvfdfwg3xhwx456y4xxydkhmq" in the output?
157164
Docker requires image names to be all lowercase which doesn't play nicely with base58-encoded binary. A dockerized IPFS hash
158165
is just a base-32 of the same binary value. This is the reason why the ipfs-registry is not a simple nginx+rewrite rules: you need
@@ -161,25 +168,23 @@ to do base-32 to base-58 conversions. If you see a string starting with `ciq` th
161168

162169
In automated scenarios you'd probably want to run image2ipfs like this:
163170
```bash
164-
$ docker built -t $TAG .
171+
172+
# build whatever images
173+
$ docker built -t $TAG ...
165174
$ docker save $TAG | image2ipfs -q -r my-gateway.local:9090 | tee pull-url.txt
166175
my-gateway.local:9090/ciq..../centos
167176
```
168177

169-
`-r my-gateway.local` instructs image2ipfs what pull url to produce.
170-
Then you can distribute the pull-url.txt to downstream jobs that need to pull the image.
178+
`-r my-gateway.local` instructs image2ipfs what pull url to produce. In a CI/CD you can distribute this generated url to downstream jobs that need to pull it.
171179

172180
# What's next
173-
Not sure. It would be great if an IPFS gateway could speak the Registry v2 protocol at /v2/* so you don't need to run a registry.
174181

175-
When an image exported and processed both v1 and v2 versions of the manifests are produced. v1 manifest are not thoroughly tested though.
176-
The flask app reads the `Accepts` header and redirects to either latest-v1 or latest-v2. But the redirection is not to
177-
the IPFS gateway but to the same service which acts as a proxy just so that it can set the 'Content-type' header.
178-
Proxying small json documents is OK but if IPFS can store the mime-type of a file then even the manifests can directly be served by a gateway
182+
Not sure. It would be great if an IPFS gateway could speak the Registry v2 protocol at /v2/* so you don't need to run a registry.
179183

180184
The Dockerized hash can be shortened a bit if base-36 is used instead of base-32/hex.
181185

182186
# Synopsis
187+
183188
```
184189
usage: image2ipfs [-h] [--quiet] [--version] [--input INPUT] [--no-add]
185190
[--registry REGISTRY]
@@ -197,15 +202,18 @@ optional arguments:
197202
```
198203

199204
# Changelog
205+
200206
* 0.0.1: Broken, doesn't work
201207
* 0.0.2: Works only with docker <= 1.9.1
202208
* 0.0.3: Dockerized hash produced using base-32 (used to be hex/base-16)
203209
* 0.0.4: Support for schema version 2 and docker > 1.10
204210
* 0.0.5: image2ipfs: stop handling archives produced by docker < 1.10, ipfs-registry can still work with all post-1.6.x dockers
211+
* 0.0.6: Deprecate manifest v1. Rewrite image2ipfs-server in golang
205212

206213
# FAQ
214+
207215
> Why can't I use tags or references.
208216
209217
The tag is always "latest". The "real" reference is encoded in the name of the image, that is, the "dockerized hash". Even
210-
if you export myimage:my-tag, in the ipfs registry you get just tag "latest" but an image like 9a3eafb835d79e/myimage:latest.
211-
This is very similar to how gx and gx-go works [https://github.com/whyrusleeping/gx].
218+
if you export myimage:my-tag, in the IPFS registry you always tag "latest" but an image like ciq9a3eafb835d79e/myimage:latest.
219+
This is very similar to how gx and gx-go work [https://github.com/whyrusleeping/gx].

image2ipfs/defaults.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import os
1515

16-
VERSION='0.0.6'
16+
VERSION='0.0.7'
1717

1818
_VERBOSE=True
1919

image2ipfs/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ def compress_layer(path, blob_dir):
238238
with open(temp, 'wb') as f_out:
239239
# produce deterministic gzip files
240240
gz = gzip.GzipFile(filename='', mode='wb', fileobj=f_out, mtime=0)
241-
gz.write(f_in)
241+
gz.writelines(f_in)
242242
gz.close()
243243

244244
digest = sha256_file(temp)

0 commit comments

Comments
 (0)