Fossil SCM
Broke the Dockerfile up into more layers to allow better local caching at build time. Further optimized build time by producing the Fossil source tarball from the local repo instead of hitting the home site if you use the container-image target, since we can be reasonably certain you're working from a repo checkout and thus have all the info available here locally already.
Commit
1da464eeb941e5de8631af4bb6c846dc82410b52e61cb03545dd672aa9d6a725
Parent
698587d41d0110b…
2 files changed
+79
-32
+4
-1
+79
-32
| --- Dockerfile | ||
| +++ Dockerfile | ||
| @@ -1,60 +1,107 @@ | ||
| 1 | 1 | # See www/containers.md for documentation on how to use this file. |
| 2 | 2 | |
| 3 | -# STAGE 1: Build a static Fossil binary atop Alpine Linux | |
| 3 | +## --------------------------------------------------------------------- | |
| 4 | +## STAGE 1: Build static Fossil & BusyBox binaries atop Alpine Linux | |
| 5 | +## --------------------------------------------------------------------- | |
| 4 | 6 | |
| 5 | 7 | FROM alpine:latest AS builder |
| 6 | -COPY containers/busybox-config /tmp/bbx/.config | |
| 7 | -ARG BBXVER="1_35_0" | |
| 8 | -ENV BBXURL "https://github.com/mirror/busybox/tarball/${BBXVER}" | |
| 9 | -ARG FSLVER="trunk" | |
| 10 | -ENV FSLURL "https://fossil-scm.org/home/tarball/?r=${FSLVER}" | |
| 11 | -ADD $BBXURL /tmp/bbx/src.tar.gz | |
| 12 | -ADD $FSLURL /tmp/fsl/src.tar.gz | |
| 13 | 8 | WORKDIR /tmp |
| 9 | + | |
| 10 | +### Bake the basic Alpine Linux into a base layer so we never have to | |
| 11 | +### repeat that step unless we change the package set. Although we're | |
| 12 | +### going to throw this layer away below, we still pass --no-cache | |
| 13 | +### because that cache is of no use in an immutable layer. Note that | |
| 14 | +### we allow the UPX step to fail: it isn't in the ARM distros. We'll | |
| 15 | +### check whether this optional piece exists before using it below. | |
| 14 | 16 | RUN set -x \ |
| 15 | - && apk update \ | |
| 16 | - && apk upgrade --no-cache \ | |
| 17 | - && apk add --no-cache \ | |
| 17 | + && apk update \ | |
| 18 | + && apk upgrade --no-cache \ | |
| 19 | + && apk add --no-cache \ | |
| 18 | 20 | gcc make moreutils \ |
| 19 | 21 | linux-headers musl-dev \ |
| 20 | 22 | openssl-dev openssl-libs-static \ |
| 21 | 23 | zlib-dev zlib-static \ |
| 22 | - && tar --strip-components=1 -C bbx -xzf bbx/src.tar.gz \ | |
| 23 | - && ( cd bbx && yes "" | make oldconfig && make -j11 ) \ | |
| 24 | - && tar -C fsl -xzf fsl/src.tar.gz \ | |
| 25 | - && m=fsl/src/main.mk ; grep -v '/skins/[a-ce-z]' $m | sponge $m \ | |
| 26 | - && fsl/configure --static CFLAGS='-Os -s' && make -j11 \ | |
| 27 | - && if apk add upx ; then upx -9 fossil bbx/busybox ; fi | |
| 28 | - | |
| 29 | -# STAGE 2: Pare that back to the bare essentials. | |
| 24 | + ; apk add --no-cache upx | |
| 25 | + | |
| 26 | +### Bake the custom BusyBox into another layer. The intent is that this | |
| 27 | +### changes only when we change BBXVER. That will force an update of | |
| 28 | +### the layers below, but this is a rare occurrence. | |
| 29 | +ARG BBXVER="1_35_0" | |
| 30 | +ENV BBXURL "https://github.com/mirror/busybox/tarball/${BBXVER}" | |
| 31 | +COPY containers/busybox-config /tmp/bbx/.config | |
| 32 | +ADD $BBXURL /tmp/bbx/src.tar.gz | |
| 33 | +RUN set -x \ | |
| 34 | + && tar --strip-components=1 -C bbx -xzf bbx/src.tar.gz \ | |
| 35 | + && ( cd bbx && yes "" | make oldconfig && make -j11 ) \ | |
| 36 | + && if [ -x /usr/bin/upx ] ; then upx -9q bbx/busybox ; fi | |
| 37 | + | |
| 38 | +### The changeable Fossil layer is the only one in the first stage that | |
| 39 | +### changes often, so add it last, to make it independent of the others. | |
| 40 | +### | |
| 41 | +### $FSLSTB can be either a file or a directory due to a ADD's bizarre | |
| 42 | +### behavior: it unpacks tarballs when added from a local file but not | |
| 43 | +### from a URL! It matters because we default to a URL in case you're | |
| 44 | +### building outside a Fossil checkout, but when building via the | |
| 45 | +### container-image target, we can avoid a costly hit on the Fossil | |
| 46 | +### project's home site by pulling the data from the local repo via the | |
| 47 | +### "tarball" command. This is a DVCS, after all! | |
| 48 | +ARG FSLVER="trunk" | |
| 49 | +ARG FSLURL="https://fossil-scm.org/home/tarball/src?r=${FSLVER}" | |
| 50 | +ENV FSLSTB=/tmp/fsl/src.tar.gz | |
| 51 | +ADD $FSLURL $FSLSTB | |
| 52 | +RUN set -x \ | |
| 53 | + && if [ -d $FSLSTB ] ; then mv $FSLSTB/src fsl ; \ | |
| 54 | + else tar -C fsl -xzf fsl/src.tar.gz ; fi \ | |
| 55 | + && m=fsl/src/src/main.mk \ | |
| 56 | + && grep -v '/skins/[a-ce-z]' $m | sponge $m \ | |
| 57 | + && fsl/src/configure --static CFLAGS='-Os -s' && make -j11 \ | |
| 58 | + && if [ -x /usr/bin/upx ] ; then upx -9q fossil ; fi | |
| 59 | + | |
| 60 | + | |
| 61 | +## --------------------------------------------------------------------- | |
| 62 | +## STAGE 2: Pare that back to the bare essentials. | |
| 63 | +## --------------------------------------------------------------------- | |
| 30 | 64 | |
| 31 | 65 | FROM scratch |
| 32 | 66 | WORKDIR /jail |
| 33 | 67 | ARG UID=499 |
| 34 | 68 | ENV PATH "/bin:/jail/bin" |
| 35 | -COPY --from=builder /tmp/fossil bin/ | |
| 69 | + | |
| 70 | +### Lay BusyBox down as the first base layer. Coupled with the host's | |
| 71 | +### kernel, this is the "OS." | |
| 36 | 72 | COPY --from=builder /tmp/bbx/busybox /bin/ |
| 37 | 73 | RUN [ "/bin/busybox", "--install", "/bin" ] |
| 74 | + | |
| 75 | +### Set up that base OS for our specific use without tying it to | |
| 76 | +### anything likely to change often. So long as the user leaves | |
| 77 | +### UID alone, this layer will be durable. | |
| 38 | 78 | RUN set -x \ |
| 39 | - && mkdir -m 755 dev \ | |
| 40 | - && mknod -m 666 dev/null c 1 3 \ | |
| 41 | - && mknod -m 444 dev/urandom c 1 9 \ | |
| 42 | - && mkdir -m 700 log museum \ | |
| 43 | 79 | && echo 'root:x:0:0:SysAdmin:/:/bin/nologin' > /etc/passwd \ |
| 44 | 80 | && echo 'root:x:0:root' > /etc/group \ |
| 45 | - && addgroup -g ${UID} fossil \ | |
| 46 | - && adduser -h `pwd` -g 'Fossil User' -G fossil -u ${UID} -S fossil \ | |
| 81 | + && addgroup -S -g ${UID} fossil \ | |
| 82 | + && adduser -S -h `pwd` -g 'Fossil User' -G fossil -u ${UID} fossil \ | |
| 83 | + && install -d -m 700 -o fossil -g fossil log museum \ | |
| 84 | + && install -d -m 755 -o fossil -g fossil dev \ | |
| 85 | + && mknod -m 666 dev/null c 1 3 \ | |
| 86 | + && mknod -m 444 dev/urandom c 1 9 | |
| 87 | + | |
| 88 | +### Do Fossil-specific things atop those base layers; this will change | |
| 89 | +### as often as the Fossil build-from-source layer above. | |
| 90 | +COPY --from=builder /tmp/fossil bin/ | |
| 91 | +RUN set -x \ | |
| 92 | + && ln -s /jail/bin/fossil /bin/f \ | |
| 47 | 93 | && echo -e '#!/bin/sh\nfossil sha1sum "$@"' > /bin/sha1sum \ |
| 48 | 94 | && echo -e '#!/bin/sh\nfossil sha3sum "$@"' > /bin/sha3sum \ |
| 49 | - && echo -e '#!/bin/sh\nfossil sqlite3 --no-repository "$@"' > /bin/sqlite3 \ | |
| 50 | - && ln -s /jail/bin/fossil /bin/f \ | |
| 51 | - && chmod +x /bin/sha?sum /bin/sqlite3 \ | |
| 52 | - && chown fossil:fossil . log museum | |
| 95 | + && echo -e '#!/bin/sh\nfossil sqlite3 --no-repository "$@"' > \ | |
| 96 | + /bin/sqlite3 \ | |
| 97 | + && chmod +x /bin/sha?sum /bin/sqlite3 | |
| 98 | + | |
| 53 | 99 | |
| 54 | -# Now we can run the stripped-down environment in a chroot jail, while | |
| 55 | -# leaving open the option to debug it live via the Busybox shell. | |
| 100 | +## --------------------------------------------------------------------- | |
| 101 | +## STAGE 3: Run! | |
| 102 | +## --------------------------------------------------------------------- | |
| 56 | 103 | |
| 57 | 104 | EXPOSE 8080/tcp |
| 58 | 105 | CMD [ \ |
| 59 | 106 | "bin/fossil", "server", \ |
| 60 | 107 | "--chroot", "/jail", \ |
| 61 | 108 |
| --- Dockerfile | |
| +++ Dockerfile | |
| @@ -1,60 +1,107 @@ | |
| 1 | # See www/containers.md for documentation on how to use this file. |
| 2 | |
| 3 | # STAGE 1: Build a static Fossil binary atop Alpine Linux |
| 4 | |
| 5 | FROM alpine:latest AS builder |
| 6 | COPY containers/busybox-config /tmp/bbx/.config |
| 7 | ARG BBXVER="1_35_0" |
| 8 | ENV BBXURL "https://github.com/mirror/busybox/tarball/${BBXVER}" |
| 9 | ARG FSLVER="trunk" |
| 10 | ENV FSLURL "https://fossil-scm.org/home/tarball/?r=${FSLVER}" |
| 11 | ADD $BBXURL /tmp/bbx/src.tar.gz |
| 12 | ADD $FSLURL /tmp/fsl/src.tar.gz |
| 13 | WORKDIR /tmp |
| 14 | RUN set -x \ |
| 15 | && apk update \ |
| 16 | && apk upgrade --no-cache \ |
| 17 | && apk add --no-cache \ |
| 18 | gcc make moreutils \ |
| 19 | linux-headers musl-dev \ |
| 20 | openssl-dev openssl-libs-static \ |
| 21 | zlib-dev zlib-static \ |
| 22 | && tar --strip-components=1 -C bbx -xzf bbx/src.tar.gz \ |
| 23 | && ( cd bbx && yes "" | make oldconfig && make -j11 ) \ |
| 24 | && tar -C fsl -xzf fsl/src.tar.gz \ |
| 25 | && m=fsl/src/main.mk ; grep -v '/skins/[a-ce-z]' $m | sponge $m \ |
| 26 | && fsl/configure --static CFLAGS='-Os -s' && make -j11 \ |
| 27 | && if apk add upx ; then upx -9 fossil bbx/busybox ; fi |
| 28 | |
| 29 | # STAGE 2: Pare that back to the bare essentials. |
| 30 | |
| 31 | FROM scratch |
| 32 | WORKDIR /jail |
| 33 | ARG UID=499 |
| 34 | ENV PATH "/bin:/jail/bin" |
| 35 | COPY --from=builder /tmp/fossil bin/ |
| 36 | COPY --from=builder /tmp/bbx/busybox /bin/ |
| 37 | RUN [ "/bin/busybox", "--install", "/bin" ] |
| 38 | RUN set -x \ |
| 39 | && mkdir -m 755 dev \ |
| 40 | && mknod -m 666 dev/null c 1 3 \ |
| 41 | && mknod -m 444 dev/urandom c 1 9 \ |
| 42 | && mkdir -m 700 log museum \ |
| 43 | && echo 'root:x:0:0:SysAdmin:/:/bin/nologin' > /etc/passwd \ |
| 44 | && echo 'root:x:0:root' > /etc/group \ |
| 45 | && addgroup -g ${UID} fossil \ |
| 46 | && adduser -h `pwd` -g 'Fossil User' -G fossil -u ${UID} -S fossil \ |
| 47 | && echo -e '#!/bin/sh\nfossil sha1sum "$@"' > /bin/sha1sum \ |
| 48 | && echo -e '#!/bin/sh\nfossil sha3sum "$@"' > /bin/sha3sum \ |
| 49 | && echo -e '#!/bin/sh\nfossil sqlite3 --no-repository "$@"' > /bin/sqlite3 \ |
| 50 | && ln -s /jail/bin/fossil /bin/f \ |
| 51 | && chmod +x /bin/sha?sum /bin/sqlite3 \ |
| 52 | && chown fossil:fossil . log museum |
| 53 | |
| 54 | # Now we can run the stripped-down environment in a chroot jail, while |
| 55 | # leaving open the option to debug it live via the Busybox shell. |
| 56 | |
| 57 | EXPOSE 8080/tcp |
| 58 | CMD [ \ |
| 59 | "bin/fossil", "server", \ |
| 60 | "--chroot", "/jail", \ |
| 61 |
| --- Dockerfile | |
| +++ Dockerfile | |
| @@ -1,60 +1,107 @@ | |
| 1 | # See www/containers.md for documentation on how to use this file. |
| 2 | |
| 3 | ## --------------------------------------------------------------------- |
| 4 | ## STAGE 1: Build static Fossil & BusyBox binaries atop Alpine Linux |
| 5 | ## --------------------------------------------------------------------- |
| 6 | |
| 7 | FROM alpine:latest AS builder |
| 8 | WORKDIR /tmp |
| 9 | |
| 10 | ### Bake the basic Alpine Linux into a base layer so we never have to |
| 11 | ### repeat that step unless we change the package set. Although we're |
| 12 | ### going to throw this layer away below, we still pass --no-cache |
| 13 | ### because that cache is of no use in an immutable layer. Note that |
| 14 | ### we allow the UPX step to fail: it isn't in the ARM distros. We'll |
| 15 | ### check whether this optional piece exists before using it below. |
| 16 | RUN set -x \ |
| 17 | && apk update \ |
| 18 | && apk upgrade --no-cache \ |
| 19 | && apk add --no-cache \ |
| 20 | gcc make moreutils \ |
| 21 | linux-headers musl-dev \ |
| 22 | openssl-dev openssl-libs-static \ |
| 23 | zlib-dev zlib-static \ |
| 24 | ; apk add --no-cache upx |
| 25 | |
| 26 | ### Bake the custom BusyBox into another layer. The intent is that this |
| 27 | ### changes only when we change BBXVER. That will force an update of |
| 28 | ### the layers below, but this is a rare occurrence. |
| 29 | ARG BBXVER="1_35_0" |
| 30 | ENV BBXURL "https://github.com/mirror/busybox/tarball/${BBXVER}" |
| 31 | COPY containers/busybox-config /tmp/bbx/.config |
| 32 | ADD $BBXURL /tmp/bbx/src.tar.gz |
| 33 | RUN set -x \ |
| 34 | && tar --strip-components=1 -C bbx -xzf bbx/src.tar.gz \ |
| 35 | && ( cd bbx && yes "" | make oldconfig && make -j11 ) \ |
| 36 | && if [ -x /usr/bin/upx ] ; then upx -9q bbx/busybox ; fi |
| 37 | |
| 38 | ### The changeable Fossil layer is the only one in the first stage that |
| 39 | ### changes often, so add it last, to make it independent of the others. |
| 40 | ### |
| 41 | ### $FSLSTB can be either a file or a directory due to a ADD's bizarre |
| 42 | ### behavior: it unpacks tarballs when added from a local file but not |
| 43 | ### from a URL! It matters because we default to a URL in case you're |
| 44 | ### building outside a Fossil checkout, but when building via the |
| 45 | ### container-image target, we can avoid a costly hit on the Fossil |
| 46 | ### project's home site by pulling the data from the local repo via the |
| 47 | ### "tarball" command. This is a DVCS, after all! |
| 48 | ARG FSLVER="trunk" |
| 49 | ARG FSLURL="https://fossil-scm.org/home/tarball/src?r=${FSLVER}" |
| 50 | ENV FSLSTB=/tmp/fsl/src.tar.gz |
| 51 | ADD $FSLURL $FSLSTB |
| 52 | RUN set -x \ |
| 53 | && if [ -d $FSLSTB ] ; then mv $FSLSTB/src fsl ; \ |
| 54 | else tar -C fsl -xzf fsl/src.tar.gz ; fi \ |
| 55 | && m=fsl/src/src/main.mk \ |
| 56 | && grep -v '/skins/[a-ce-z]' $m | sponge $m \ |
| 57 | && fsl/src/configure --static CFLAGS='-Os -s' && make -j11 \ |
| 58 | && if [ -x /usr/bin/upx ] ; then upx -9q fossil ; fi |
| 59 | |
| 60 | |
| 61 | ## --------------------------------------------------------------------- |
| 62 | ## STAGE 2: Pare that back to the bare essentials. |
| 63 | ## --------------------------------------------------------------------- |
| 64 | |
| 65 | FROM scratch |
| 66 | WORKDIR /jail |
| 67 | ARG UID=499 |
| 68 | ENV PATH "/bin:/jail/bin" |
| 69 | |
| 70 | ### Lay BusyBox down as the first base layer. Coupled with the host's |
| 71 | ### kernel, this is the "OS." |
| 72 | COPY --from=builder /tmp/bbx/busybox /bin/ |
| 73 | RUN [ "/bin/busybox", "--install", "/bin" ] |
| 74 | |
| 75 | ### Set up that base OS for our specific use without tying it to |
| 76 | ### anything likely to change often. So long as the user leaves |
| 77 | ### UID alone, this layer will be durable. |
| 78 | RUN set -x \ |
| 79 | && echo 'root:x:0:0:SysAdmin:/:/bin/nologin' > /etc/passwd \ |
| 80 | && echo 'root:x:0:root' > /etc/group \ |
| 81 | && addgroup -S -g ${UID} fossil \ |
| 82 | && adduser -S -h `pwd` -g 'Fossil User' -G fossil -u ${UID} fossil \ |
| 83 | && install -d -m 700 -o fossil -g fossil log museum \ |
| 84 | && install -d -m 755 -o fossil -g fossil dev \ |
| 85 | && mknod -m 666 dev/null c 1 3 \ |
| 86 | && mknod -m 444 dev/urandom c 1 9 |
| 87 | |
| 88 | ### Do Fossil-specific things atop those base layers; this will change |
| 89 | ### as often as the Fossil build-from-source layer above. |
| 90 | COPY --from=builder /tmp/fossil bin/ |
| 91 | RUN set -x \ |
| 92 | && ln -s /jail/bin/fossil /bin/f \ |
| 93 | && echo -e '#!/bin/sh\nfossil sha1sum "$@"' > /bin/sha1sum \ |
| 94 | && echo -e '#!/bin/sh\nfossil sha3sum "$@"' > /bin/sha3sum \ |
| 95 | && echo -e '#!/bin/sh\nfossil sqlite3 --no-repository "$@"' > \ |
| 96 | /bin/sqlite3 \ |
| 97 | && chmod +x /bin/sha?sum /bin/sqlite3 |
| 98 | |
| 99 | |
| 100 | ## --------------------------------------------------------------------- |
| 101 | ## STAGE 3: Run! |
| 102 | ## --------------------------------------------------------------------- |
| 103 | |
| 104 | EXPOSE 8080/tcp |
| 105 | CMD [ \ |
| 106 | "bin/fossil", "server", \ |
| 107 | "--chroot", "/jail", \ |
| 108 |
+4
-1
| --- Makefile.in | ||
| +++ Makefile.in | ||
| @@ -118,15 +118,18 @@ | ||
| 118 | 118 | Makefile: @srcdir@/Makefile.in $(SRCDIR)/main.mk @AUTODEPS@ |
| 119 | 119 | @AUTOREMAKE@ |
| 120 | 120 | touch @builddir@/Makefile |
| 121 | 121 | |
| 122 | 122 | # Container stuff |
| 123 | +SRCTB := src-@[email protected] | |
| 123 | 124 | container-image: |
| 125 | + $(APPNAME) tarball --name src @FOSSIL_CI_PFX@ $(SRCTB) | |
| 124 | 126 | docker build \ |
| 125 | 127 | --tag fossil:@FOSSIL_CI_PFX@ \ |
| 126 | - --build-arg FSLVER=@FOSSIL_CI_PFX@ \ | |
| 128 | + --build-arg FSLURL=$(SRCTB) \ | |
| 127 | 129 | $(DBFLAGS) @srcdir@ |
| 130 | + rm -f $(SRCTB) | |
| 128 | 131 | |
| 129 | 132 | container-run: container-image |
| 130 | 133 | docker run \ |
| 131 | 134 | --name fossil-@FOSSIL_CI_PFX@ \ |
| 132 | 135 | --cap-drop AUDIT_WRITE \ |
| 133 | 136 |
| --- Makefile.in | |
| +++ Makefile.in | |
| @@ -118,15 +118,18 @@ | |
| 118 | Makefile: @srcdir@/Makefile.in $(SRCDIR)/main.mk @AUTODEPS@ |
| 119 | @AUTOREMAKE@ |
| 120 | touch @builddir@/Makefile |
| 121 | |
| 122 | # Container stuff |
| 123 | container-image: |
| 124 | docker build \ |
| 125 | --tag fossil:@FOSSIL_CI_PFX@ \ |
| 126 | --build-arg FSLVER=@FOSSIL_CI_PFX@ \ |
| 127 | $(DBFLAGS) @srcdir@ |
| 128 | |
| 129 | container-run: container-image |
| 130 | docker run \ |
| 131 | --name fossil-@FOSSIL_CI_PFX@ \ |
| 132 | --cap-drop AUDIT_WRITE \ |
| 133 |
| --- Makefile.in | |
| +++ Makefile.in | |
| @@ -118,15 +118,18 @@ | |
| 118 | Makefile: @srcdir@/Makefile.in $(SRCDIR)/main.mk @AUTODEPS@ |
| 119 | @AUTOREMAKE@ |
| 120 | touch @builddir@/Makefile |
| 121 | |
| 122 | # Container stuff |
| 123 | SRCTB := src-@[email protected] |
| 124 | container-image: |
| 125 | $(APPNAME) tarball --name src @FOSSIL_CI_PFX@ $(SRCTB) |
| 126 | docker build \ |
| 127 | --tag fossil:@FOSSIL_CI_PFX@ \ |
| 128 | --build-arg FSLURL=$(SRCTB) \ |
| 129 | $(DBFLAGS) @srcdir@ |
| 130 | rm -f $(SRCTB) |
| 131 | |
| 132 | container-run: container-image |
| 133 | docker run \ |
| 134 | --name fossil-@FOSSIL_CI_PFX@ \ |
| 135 | --cap-drop AUDIT_WRITE \ |
| 136 |