diff --git a/docker/armv7l/Dockerfile b/docker/armv7l/Dockerfile index 80b89cca..b06cfa98 100644 --- a/docker/armv7l/Dockerfile +++ b/docker/armv7l/Dockerfile @@ -1,44 +1,55 @@ -# Get the base image by running the included `base.sh` script. -FROM archlinuxarm/odroid-xu3:latest +# Get the base image by running the included `mkimage-alpine.sh` script, or +# get a fresh copy from github.com/docker/docker/contrib/. +FROM alpine:edge # Copy app source. COPY . /tmp/build/ -# Sneak the stf and node executables into $PATH. -ENV PATH /app/bin:/opt/node/bin:$PATH +# Sneak the stf executable into $PATH. +ENV PATH /app/bin:$PATH # Build the whole thing. Since Docker Hub doesn't really support other archs, # we'll run a full daily build by ourselves, so it doesn't necessary have to # be separated into multiple steps for speed. -RUN set -x && \ - useradd --system --create-home stf && \ - echo 'Server = http://mirror.archlinuxarm.org/$arch/$repo' > /etc/pacman.d/mirrorlist && \ - pacman -Sy && \ - pacman --noconfirm -S zeromq protobuf git graphicsmagick yasm python2 pkg-config make gcc && \ - curl -o /opt/node.tar.xz https://nodejs.org/dist/v5.3.0/node-v5.3.0-linux-armv7l.tar.xz && \ - cd /opt && \ - tar xf node.tar.xz && \ - rm node.tar.xz && \ - mv node-* node && \ +# +# Node build taken from https://github.com/mhart/alpine-node and slightly adapted. +RUN set -xo pipefail && \ + echo '--- Updating repositories' && \ + echo '@testing http://nl.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories && \ + apk update && \ + echo '--- Building node' && \ + apk add curl make gcc g++ binutils-gold python linux-headers paxctl libgcc libstdc++ && \ + curl -sSL https://nodejs.org/dist/v5.7.0/node-v5.7.0.tar.gz | tar -xz && \ + cd /node-v* && \ + ./configure --prefix=/usr && \ + make -j$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ + make install && \ + paxctl -cm /usr/bin/node && \ + echo '--- Building app' && \ + addgroup -S stf && \ + adduser -S -G stf stf && \ chown -R stf:stf /tmp/build && \ cd /tmp/build && \ export PATH=$PWD/node_modules/.bin:$PATH && \ sed -i'' -e '/phantomjs/d' package.json && \ - export JOBS=$(nproc) && \ - runuser -u stf -- npm install --no-optional && \ - runuser -u stf -- npm pack && \ - mkdir -p /app && \ - tar xf stf-*.tgz --strip-components 1 -C /app && \ - runuser -u stf -- bower cache clean && \ - runuser -u stf -- npm prune --production && \ + apk add git zeromq-dev protobuf-dev graphicsmagick@testing && \ + export JOBS=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ + echo 'npm install --no-optional' | su stf -s /bin/sh && \ + echo '--- Assembling app' && \ + echo 'npm pack' | su stf -s /bin/sh && \ + tar -xzf stf-*.tgz && \ + mv package /app && \ + echo 'bower cache clean' | su stf -s /bin/sh && \ + echo 'npm prune --production' | su stf -s /bin/sh && \ mv node_modules /app && \ chown -R root:root /app && \ - runuser -u stf -- npm cache clean && \ + echo '--- Cleaning up' && \ + echo 'npm cache clean' | su stf -s /bin/sh && \ rm -rf /home/stf/.node-gyp && \ - cd /app && \ - rm -rf /tmp/* && \ - pacman --noconfirm -Rs git yasm python2 pkg-config make gcc && \ - pacman --noconfirm -Sc + apk del curl make gcc g++ binutils-gold python linux-headers paxctl && \ + rm -rf /node-v* \ + /usr/share/man /tmp/* /var/cache/apk/* /root/.npm /root/.node-gyp \ + /usr/lib/node_modules/npm/man /usr/lib/node_modules/npm/doc /usr/lib/node_modules/npm/html # Work in app dir by default. WORKDIR /app diff --git a/docker/armv7l/base.sh b/docker/armv7l/base.sh deleted file mode 100755 index 9dada7da..00000000 --- a/docker/armv7l/base.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail -wget http://archlinuxarm.org/os/ArchLinuxARM-odroid-xu3-latest.tar.gz | gunzip | docker import - archlinuxarm/odroid-xu3:latest diff --git a/docker/armv7l/mkimage-alpine.sh b/docker/armv7l/mkimage-alpine.sh new file mode 100755 index 00000000..c2326f3c --- /dev/null +++ b/docker/armv7l/mkimage-alpine.sh @@ -0,0 +1,90 @@ +#!/bin/sh + +# Originally from: +# https://github.com/docker/docker/blob/master/contrib/mkimage-alpine.sh + +set -e + +[ $(id -u) -eq 0 ] || { + printf >&2 '%s requires root\n' "$0" + exit 1 +} + +usage() { + printf >&2 '%s: [-r release] [-m mirror] [-s] [-c additional repository]\n' "$0" + exit 1 +} + +tmp() { + TMP=$(mktemp -d ${TMPDIR:-/var/tmp}/alpine-docker-XXXXXXXXXX) + ROOTFS=$(mktemp -d ${TMPDIR:-/var/tmp}/alpine-docker-rootfs-XXXXXXXXXX) + trap "rm -rf $TMP $ROOTFS" EXIT TERM INT +} + +apkv() { + curl -sSL $MAINREPO/$ARCH/APKINDEX.tar.gz | tar -Oxz | + grep --text '^P:apk-tools-static$' -A1 | tail -n1 | cut -d: -f2 +} + +getapk() { + curl -sSL $MAINREPO/$ARCH/apk-tools-static-$(apkv).apk | + tar -xz -C $TMP sbin/apk.static +} + +mkbase() { + $TMP/sbin/apk.static --repository $MAINREPO --update-cache --allow-untrusted \ + --root $ROOTFS --initdb add alpine-base +} + +conf() { + printf '%s\n' $MAINREPO > $ROOTFS/etc/apk/repositories + printf '%s\n' $ADDITIONALREPO >> $ROOTFS/etc/apk/repositories +} + +pack() { + local id + id=$(tar --numeric-owner -C $ROOTFS -c . | docker import - alpine:$REL) + + docker tag $id alpine:latest + docker run -i -t --rm alpine printf 'alpine:%s with id=%s created!\n' $REL $id +} + +save() { + [ $SAVE -eq 1 ] || return + + tar --numeric-owner -C $ROOTFS -c . | xz > rootfs.tar.xz +} + +while getopts "hr:m:s" opt; do + case $opt in + r) + REL=$OPTARG + ;; + m) + MIRROR=$OPTARG + ;; + s) + SAVE=1 + ;; + c) + ADDITIONALREPO=community + ;; + *) + usage + ;; + esac +done + +REL=${REL:-edge} +MIRROR=${MIRROR:-http://nl.alpinelinux.org/alpine} +SAVE=${SAVE:-0} +MAINREPO=$MIRROR/$REL/main +ADDITIONALREPO=$MIRROR/$REL/community +ARCH=${ARCH:-$(uname -m)} + +tmp +getapk +mkbase +conf +pack +save diff --git a/docker/armv7l/publish.sh b/docker/armv7l/publish.sh new file mode 100755 index 00000000..c95b54b0 --- /dev/null +++ b/docker/armv7l/publish.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh +set -xeuo pipefail +ARCH=armhf docker/armv7l/mkimage-alpine.sh +docker build -f docker/armv7l/Dockerfile -t openstf/stf-armv7l:latest +docker push openstf/stf-armv7l:latest