From 7fcc860beaf561b0d06f2e84330e3eb709d19269 Mon Sep 17 00:00:00 2001 From: Timo Knapp Date: Wed, 29 Jan 2020 09:12:25 +0100 Subject: [PATCH] feature(docker) add Dockerfile for arm based clients such as rpi (#268) --- .dockerignore | 3 +- .madrun.js | 79 ++++++++++++++++--- .npmignore | 2 +- .travis.yml | 45 ++++++----- Dockerfile => docker/Dockerfile | 2 +- Dockerfile.alpine => docker/Dockerfile.alpine | 2 +- docker/arm/Dockerfile.arm32v7 | 31 ++++++++ docker/arm/Dockerfile.arm64v8 | 31 ++++++++ 8 files changed, 157 insertions(+), 38 deletions(-) rename Dockerfile => docker/Dockerfile (92%) rename Dockerfile.alpine => docker/Dockerfile.alpine (94%) create mode 100644 docker/arm/Dockerfile.arm32v7 create mode 100644 docker/arm/Dockerfile.arm64v8 diff --git a/.dockerignore b/.dockerignore index 627bba19..4f398708 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,8 +11,7 @@ yarn-error.log yarn.lock now.json -Dockerfile -Dockerfile.alpine +docker webpack.config.js cssnano.config.js diff --git a/.madrun.js b/.madrun.js index 1b1ba9af..32da105c 100644 --- a/.madrun.js +++ b/.madrun.js @@ -57,12 +57,22 @@ module.exports = { 'wisdom:type': () => 'bin/release.js', 'docker:pull:node': () => 'docker pull node', 'docker:pull:alpine': () => 'docker pull mhart/alpine-node', - 'docker:push': () => `docker push coderaiser/cloudcmd:${version}`, - 'docker:push:latest': () => 'docker push coderaiser/cloudcmd:latest', - 'docker:push:alpine': () => `docker push coderaiser/cloudcmd:${version}-alpine`, - 'docker:push:alpine:latest': () => 'docker push coderaiser/cloudcmd:latest-alpine', - 'docker:build': () => `docker build -t coderaiser/cloudcmd:${version} .`, - 'docker:build:alpine': () => `docker build -f Dockerfile.alpine -t coderaiser/cloudcmd:${version}-alpine .`, + 'docker:pull:arm32': () => 'docker pull arm32v7/node:slim', + 'docker:pull:arm64': () => 'docker pull arm64v8/node:slim', + 'docker:push': () => dockerPush('x64', version), + 'docker:push:latest': () => dockerPush('x64'), + 'docker:push:alpine': () => dockerPush('alpine', version), + 'docker:push:alpine:latest': () => dockerPush('alpine'), + 'docker:push:arm32': () => dockerPush('arm32', version), + 'docker:push:arm32:latest': () => dockerPush('arm32'), + 'docker:push:arm64': () => dockerPush('arm64', version), + 'docker:push:arm64:latest': () => dockerPush('arm64'), + 'docker:build': () => dockerBuild('docker/Dockerfile', 'x64', version), + 'docker:build:alpine': () => dockerBuild('docker/Dockerfile.alpine', 'alpine', version), + 'docker:build:arm32': () => dockerBuild('docker/arm/Dockerfile.arm32v7', 'arm32', version), + 'docker:build:arm64': () => dockerBuild('docker/arm/Dockerfile.arm64v8', 'arm64', version), + 'docker:manifest:create': () => 'docker manifest create coderaiser/cloudcmd:latest coderaiser/cloudcmd:latest-x64 coderaiser/cloudcmd:latest-arm32 coderaiser/cloudcmd:latest-arm64', + 'docker:manifest:push': () => 'docker manifest push coderaiser/cloudcmd:latest', 'docker': () => run(['docker:pull*', 'docker:build*', 'docker:tag*', 'docker:push*']), 'docker-ci': () => run(['build', 'docker-login', 'docker']), 'docker-login': () => 'docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD', @@ -75,12 +85,39 @@ module.exports = { 'docker:push:alpine:latest', ]), - 'docker:tag': () => `docker tag coderaiser/cloudcmd:${version} coderaiser/cloudcmd:latest`, - 'docker:tag:alpine': () => `docker tag coderaiser/cloudcmd:${version}-alpine coderaiser/cloudcmd:latest-alpine`, - 'docker:rm:version': () => `docker rmi -f coderaiser/cloudcmd:${version}`, - 'docker:rm:latest': () => 'docker rmi -f coderaiser/cloudcmd:latest', - 'docker:rm:alpine': () => `docker rmi -f coderaiser/cloudcmd:${version}-alpine`, - 'docker:rm:latest-alpine': () => 'docker rmi -f coderaiser/cloudcmd:latest-alpine', + 'docker:arm32': () => run([ + 'docker:pull:arm32', + 'docker:build:arm32', + 'docker:tag:arm32', + 'docker:push:arm32', + 'docker:push:arm32:latest', + ]), + + 'docker:arm64': () => run([ + 'docker:pull:arm64', + 'docker:build:arm64', + 'docker:tag:arm64', + 'docker:push:arm64', + 'docker:push:arm64:latest', + ]), + + 'docker:manifest': () => run([ + 'docker:manifest:create', + 'docker:manifest:push', + ]), + + 'docker:tag': () => dockerTag('x64', version), + 'docker:tag:alpine': () => dockerTag('alpine', version), + 'docker:tag:arm32': () => dockerTag('arm32', version), + 'docker:tag:arm64': () => dockerTag('arm64', version), + 'docker:rm:version': () => dockerRmi('x64', version), + 'docker:rm:latest': () => dockerRmi('x64'), + 'docker:rm:alpine': () => dockerRmi('alpine', version), + 'docker:rm:latest-alpine': () => dockerRmi('alpine'), + 'docker:rm:arm32': () => dockerRmi('arm32', version), + 'docker:rm:latest-arm32': () => dockerRmi('arm32'), + 'docker:rm:arm64': () => dockerRmi('arm64', version), + 'docker:rm:latest-arm64': () => dockerRmi('arm64'), 'docker:rm-old': () => `${parallel('docker:rm:*')} || true`, 'coverage': () => `${env} nyc ${run('test:base')}`, 'report': () => 'nyc report --reporter=text-lcov | coveralls', @@ -89,7 +126,7 @@ module.exports = { '6to5:client:dev': () => `NODE_ENV=development ${run('6to5', '--mode development')}`, 'pre6to5:client': () => 'rimraf dist', 'pre6to5:client:dev': () => 'rimraf dist-dev', - 'watch:client': () => run('6to5:client','--watch'), + 'watch:client': () => run('6to5:client', '--watch'), 'watch:client:dev': () => run('6to5:client:dev', '--watch'), 'watch:server': () => 'nodemon bin/cloudcmd.js', 'watch:lint': () => `nodemon -w client -w server -w webpack.config.js -x ${run('lint')}`, @@ -102,3 +139,19 @@ module.exports = { 'build:client:dev': () => run('6to5:client:dev'), 'heroku-postbuild': () => run('6to5:client'), }; + +function dockerPush(type, version = 'latest') { + return `docker push coderaiser/cloudcmd:${version}-${type}`; +} + +function dockerBuild(file, type, version) { + return `docker build -f ${file} -t coderaiser/cloudcmd:${version}-${type} .`; +} + +function dockerTag(type, version) { + return `docker tag coderaiser/cloudcmd:${version}-${type} coderaiser/cloudcmd:latest-${type}`; +} + +function dockerRmi(type, version = 'latest') { + return `docker rmi -f coderaiser/cloudcmd:${version}-${type}`; +} \ No newline at end of file diff --git a/.npmignore b/.npmignore index 778b7c0e..f0c9ab36 100644 --- a/.npmignore +++ b/.npmignore @@ -2,7 +2,7 @@ *.spec.js *.fixture.js* manifest.yml -Dockerfile* +docker docker-compose.yml test fixture diff --git a/.travis.yml b/.travis.yml index 709d9926..7e45964a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,20 @@ language: node_js node_js: - - 13 - - 12 - - 10 + - 13 + - 12 + - 10 cache: npm: false matrix: - allow_failures: - - os: windows + allow_failures: + - os: windows os: - - linux - - osx - - windows + - linux + - osx + - windows # https://docs.travis-ci.com/user/customizing-the-build/#git-end-of-line-conversion-control # need for windows @@ -26,22 +26,27 @@ script: - npm run lint && npm run build && npm run coverage && npm run report notifications: - email: - on_success: never - on_failure: change + email: + on_success: never + on_failure: change sudo: required services: - docker -deploy: - provider: script - script: npm run docker-ci - skip_cleanup: true - on: - node: '10' - condition: $TRAVIS_OS_NAME = linux - tags: true - all_branches: false +before_deploy: + - echo '{"experimental":"enabled"}' | sudo tee /etc/docker/daemon.json + - mkdir -p $HOME/.docker + - echo '{"experimental":"enabled"}' | sudo tee $HOME/.docker/config.json + - sudo service docker start +deploy: + provider: script + script: npm run docker-ci + skip_cleanup: true + on: + node: "10" + condition: $TRAVIS_OS_NAME = linux + tags: true + all_branches: false diff --git a/Dockerfile b/docker/Dockerfile similarity index 92% rename from Dockerfile rename to docker/Dockerfile index 72452c5b..a24b5e91 100644 --- a/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,5 @@ FROM node -MAINTAINER Coderaiser +LABEL maintainer="Coderaiser" RUN mkdir -p /usr/src/app WORKDIR /usr/src/app diff --git a/Dockerfile.alpine b/docker/Dockerfile.alpine similarity index 94% rename from Dockerfile.alpine rename to docker/Dockerfile.alpine index 9a31583e..3c85fce5 100644 --- a/Dockerfile.alpine +++ b/docker/Dockerfile.alpine @@ -1,5 +1,5 @@ FROM node:alpine -MAINTAINER Coderaiser +LABEL maintainer="Coderaiser" RUN mkdir -p /usr/src/app WORKDIR /usr/src/app diff --git a/docker/arm/Dockerfile.arm32v7 b/docker/arm/Dockerfile.arm32v7 new file mode 100644 index 00000000..ca249cae --- /dev/null +++ b/docker/arm/Dockerfile.arm32v7 @@ -0,0 +1,31 @@ +# Dockerfile to be used in an ARMv7 environment like Raspverry PI 4 +FROM arm32v7/node:slim +LABEL maintainer="Coderaiser, tea-mo903" + +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +COPY package.json /usr/src/app/ + +RUN apt-get update && apt-get -y install python3 make g++ + +ENV PYTHON python3 + +RUN npm config set package-lock false && \ + npm install --production && \ + npm i gritty && \ + npm cache clean --force + +RUN apt-get -y remove --purge python3 make g++ + +COPY . /usr/src/app + +WORKDIR / + +ENV cloudcmd_terminal true +ENV cloudcmd_terminal_path gritty +ENV cloudcmd_open false + +EXPOSE 8000 + +ENTRYPOINT ["/usr/src/app/bin/cloudcmd.js"] diff --git a/docker/arm/Dockerfile.arm64v8 b/docker/arm/Dockerfile.arm64v8 new file mode 100644 index 00000000..e27e2e68 --- /dev/null +++ b/docker/arm/Dockerfile.arm64v8 @@ -0,0 +1,31 @@ +# Dockerfile to be used in an ARMv7 environment like Raspverry PI 4 +FROM arm64v8/node:slim +LABEL maintainer="Coderaiser, tea-mo903" + +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +COPY package.json /usr/src/app/ + +RUN apt-get update && apt-get -y install python3 make g++ + +ENV PYTHON python3 + +RUN npm config set package-lock false && \ + npm install --production && \ + npm i gritty && \ + npm cache clean --force + +RUN apt-get -y remove --purge python3 make g++ + +COPY . /usr/src/app + +WORKDIR / + +ENV cloudcmd_terminal true +ENV cloudcmd_terminal_path gritty +ENV cloudcmd_open false + +EXPOSE 8000 + +ENTRYPOINT ["/usr/src/app/bin/cloudcmd.js"]