feature(docker) add support of multi-arch builds (#291)

This commit is contained in:
Timo Knapp 2021-01-19 12:05:39 +01:00 committed by coderaiser
parent 11cc63adcd
commit 99b93e760a
8 changed files with 104 additions and 255 deletions

67
.github/workflows/docker.yml vendored Normal file
View file

@ -0,0 +1,67 @@
name: Docker CI
on:
push:
tags:
- '*'
jobs:
buildx:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Use Node.js 14.x
uses: actions/setup-node@v1
with:
node-version: 14.x
- name: NPM Install
run: |
npm install
- name: NPM Lint
run: |
npm run lint
- name: NPM Build
id: npm-build
run: |
npm run build
echo "::set-output name=version::$(grep '"version":' package.json -m1 | cut -d\" -f4)"
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
# Docker Username and Password have to be set as secrets in GitHub repo.
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push base-image
uses: docker/build-push-action@v2
with:
context: .
file: docker/Dockerfile
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: true
tags: |
coderaiser/cloudcmd:latest
coderaiser/cloudcmd:${{ steps.npm-build.outputs.version }}
- name: Build and push alpine-image
uses: docker/build-push-action@v2
with:
context: .
file: docker/Dockerfile.alpine
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: true
tags: |
coderaiser/cloudcmd-alpine:latest
coderaiser/cloudcmd-alpine:${{ steps.npm-build.outputs.version }}

View file

@ -4,34 +4,32 @@ on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Use Node.js 14.x
uses: actions/setup-node@v1
with:
node-version: 14.x
- name: install
run: |
npm install
- name: lint
run: |
npm run lint
- name: build
run: |
npm run build
npm test
- name: test
run: |
npm test
- uses: actions/checkout@master
- name: Use Node.js 14.x
uses: actions/setup-node@v1
with:
node-version: 14.x
- name: coverage
run: |
npm run coverage
- name: install
run: |
npm install
- name: lint
run: |
npm run lint
- name: build
run: |
npm run build
npm test
- name: test
run: |
npm test
- name: coverage
run: |
npm run coverage

View file

@ -1,16 +1,9 @@
import {createRequire} from 'module';
import {run, parallel, cutEnv} from 'madrun';
const require = createRequire(import.meta.url);
const {version} = require('./package');
import {run, cutEnv} from 'madrun';
const testEnv = {
THREAD_IT_COUNT: 0,
};
const dockerName = 'coderaiser/cloudcmd';
export default {
'start': () => 'node bin/cloudcmd.mjs',
'start:dev': async () => await run('start', null, {
@ -31,91 +24,6 @@ export default {
'test:server': () => `tape 'test/**/*.js' 'server/**/*.spec.js' 'common/**/*.spec.js'`,
'wisdom': () => run(['lint:all', 'build', 'test']),
'wisdom:type': () => 'bin/release.mjs',
'docker:pull': () => 'docker pull node',
'docker:pull:alpine': () => 'docker pull mhart/alpine-node',
'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': () => {
const images = [
`${dockerName}:latest`,
`${dockerName}:latest-x64`,
// `${dockerName}:latest-arm32`,
// `${dockerName}:latest-arm64`,
].join(' ');
return `docker manifest create ${images}`;
},
'docker:manifest:push': () => `docker manifest push ${dockerName}:latest`,
'docker': () => run(['docker:x64', 'docker:alpine', 'docker:manifest:*']),
'docker-ci': () => run(['build', 'docker-login', 'docker']),
'docker-login': () => 'docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD',
'docker:x64': () => run([
'docker:pull',
'docker:build',
'docker:tag',
'docker:push',
'docker:push:latest',
]),
'docker:alpine': () => run([
'docker:pull:alpine',
'docker:build:alpine',
'docker:tag:alpine',
'docker:push:alpine',
'docker:push:alpine:latest',
]),
/*
'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': async () => `${await parallel('docker:rm:*')} || true`,
'coverage': async () => [testEnv, `nyc ${await cutEnv('test')}`],
'report': () => 'nyc report --reporter=text-lcov | coveralls',
'6to5': () => 'webpack --progress',
@ -137,19 +45,3 @@ export default {
'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}`;
}

View file

@ -8,7 +8,7 @@ cache:
os:
- linux
- os x
- os x
script:
- npm run lint && npm run build && npm run coverage && npm run report
@ -19,22 +19,3 @@ notifications:
on_failure: change
sudo: required
services:
- docker
before_deploy:
- echo '{"experimental":"enabled"}' | sudo tee /etc/docker/daemon.json
- mkdir -p $HOME/.docker
- echo '{"experimental":"enabled"}' | tee $HOME/.docker/config.json
- sudo service docker start
deploy:
provider: script
script: npm run docker-ci
skip_cleanup: true
on:
node: 14
condition: $TRAVIS_OS_NAME = linux
tags: true
all_branches: false

View file

@ -120,6 +120,16 @@ server.listen(port);
## Docker
The docker images are provided for mutliple architectures and types. The following list shows all existing images:
| Architecture | Type |
|----------------|--------------|
| amd64 | linux |
| arm/v7 | linux |
| arm64 (arm/v8) | linux |
| amd64 | linux-alpine |
| arm/v7 | linux-alpine |
| arm64 (arm/v8) | linux-alpine |
`Cloud Commander` could be used as a [docker container](https://hub.docker.com/r/coderaiser/cloudcmd/ "Docker container") this way:
```sh

View file

@ -1,31 +0,0 @@
# 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"]

View file

@ -1,31 +0,0 @@
# 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"]

View file

@ -56,43 +56,6 @@
"test:server": "madrun test:server",
"wisdom": "madrun wisdom",
"wisdom:type": "madrun wisdom:type",
"docker:pull": "madrun docker:pull",
"docker:pull:alpine": "madrun docker:pull:alpine",
"docker:pull:arm32": "madrun docker:pull:arm32",
"docker:pull:arm64": "madrun docker:pull:arm64",
"docker:push": "madrun docker:push",
"docker:push:latest": "madrun docker:push:latest",
"docker:push:alpine": "madrun docker:push:alpine",
"docker:push:alpine:latest": "madrun docker:push:alpine:latest",
"docker:push:arm32": "madrun docker:push:arm32",
"docker:push:arm32:latest": "madrun docker:push:arm32:latest",
"docker:push:arm64": "madrun docker:push:arm64",
"docker:push:arm64:latest": "madrun docker:push:arm64:latest",
"docker:build": "madrun docker:build",
"docker:build:alpine": "madrun docker:build:alpine",
"docker:build:arm32": "madrun docker:build:arm32",
"docker:build:arm64": "madrun docker:build:arm64",
"docker:manifest:create": "madrun docker:manifest:create",
"docker:manifest:push": "madrun docker:manifest:push",
"docker": "madrun docker",
"docker-ci": "madrun docker-ci",
"docker-login": "madrun docker-login",
"docker:x64": "madrun docker:x64",
"docker:alpine": "madrun docker:alpine",
"docker:manifest": "madrun docker:manifest",
"docker:tag": "madrun docker:tag",
"docker:tag:alpine": "madrun docker:tag:alpine",
"docker:tag:arm32": "madrun docker:tag:arm32",
"docker:tag:arm64": "madrun docker:tag:arm64",
"docker:rm:version": "madrun docker:rm:version",
"docker:rm:latest": "madrun docker:rm:latest",
"docker:rm:alpine": "madrun docker:rm:alpine",
"docker:rm:latest-alpine": "madrun docker:rm:latest-alpine",
"docker:rm:arm32": "madrun docker:rm:arm32",
"docker:rm:latest-arm32": "madrun docker:rm:latest-arm32",
"docker:rm:arm64": "madrun docker:rm:arm64",
"docker:rm:latest-arm64": "madrun docker:rm:latest-arm64",
"docker:rm-old": "madrun docker:rm-old",
"coverage": "madrun coverage",
"report": "madrun report",
"6to5": "madrun 6to5",
@ -247,4 +210,4 @@
"publishConfig": {
"access": "public"
}
}
}