chainpoint / chainpoint-gateway

Chainpoint Gateway
https://chainpoint.org
Apache License 2.0
27 stars 12 forks source link

Make the docker image smaller and prepare for builds for other architectures #21

Closed filoozom closed 5 years ago

filoozom commented 5 years ago

Prepare for other architectures

Simply remove the dependency on tini and replace it with Docker's --init flag. The same could be achieved by simply adding the right binary for each architecture, but this way the same Dockerfile can be used for all architectures.

This image was tested on amd64 and arm32v7 (Raspberry Pi, although it takes ~45 minutes to build the image).

Make the Docker image smaller

I guess it would also be possible to remove all those dependencies: https://github.com/docker-library/buildpack-deps/blob/d7da72aaf3bb93fecf5fcb7c6ff154cb0c55d1d1/stretch/Dockerfile

Alternative Alpine image

FROM node:alpine

LABEL MAINTAINER="Glenn Rempe <glenn@tierion.com>"
WORKDIR /home/node/app
ENV NODE_ENV production

# Install dependencies and create directories
RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \
  apk add --no-cache gosu@testing && \
  apk add --no-cache --virtual .build build-base linux-headers git python && \
  mkdir -p /home/node/app/keys/backups && \
  mkdir -p /home/node/app/rocksdb

# Copy all necessary JS files
COPY package.json yarn.lock auth-keys-print.js server.js tor-exit-nodes.txt cert.crt cert.key /home/node/app/
COPY lib /home/node/app/lib
COPY ui/build /home/node/app/ui

# Install NodeJS dependencies then remove build packages
RUN JOBS=max npm install --production && \
  apk del --no-cache .build

EXPOSE 8080
ENTRYPOINT ["gosu", "node:node"]
CMD ["yarn", "start"]

The issue with the Alpine version is that it doesn't support arm32v7, which was the whole point of all these changes (didn't get it to work with arm32v6 on RPi, although it might have been my own fault now that I think about it - will try again).

grempe commented 5 years ago

Docker-compose format version 3.7 requires Docker Engine 18.06.0 or above:

https://github.com/docker/compose/blob/master/CHANGELOG.md#1220-2018-07-17

However, this latest version does not appear to be an available option for installation on standard Ubuntu 16.0.4 LTS yet.

https://cl.ly/7e42e0cff949/Image%2525202018-10-12%252520at%25252011.49.49%252520AM.png

Without this, how can we expect typical Node operators to upgrade to this new requirement when this change would be applied to chainpoint-node repo in addition to this one?

The removal of tini then cannot be done, as I see it now, without full support of the full suite of docker, docker-compose being easily (automatically via Makefile) upgradeable to latest required versions. Otherwise init call in docker-compose.yaml will fail. No?

If you'd like to do the other layer flattening changes in this PR, leaving the tini issue for later that would be a good start though.

Regarding the new Alpine Dockerfile for experimentation. Would it make sense to include that in this dir as Dockerfile.alpine in a separate pull request?

filoozom commented 5 years ago

Where do you get your docker-ce version from? Your install script contains:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update

On a fresh Ubuntu 16.04 (Xenial), I get:

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.4 LTS"

$ apt show docker-ce
Package: docker-ce
Version: 18.06.1~ce~3-0~ubuntu
Priority: optional
Section: admin
Maintainer: Docker <support@docker.com>
Installed-Size: 198 MB
Depends: iptables, init-system-helpers (>= 1.18~), lsb-base (>= 4.1+Debian11ubuntu7), libc6 (>= 2.17), libdevmapper1.02.1 (>= 2:1.02.97), libltdl7 (>= 2.4.6), libseccomp2 (>= 2.3.0), libsystemd0
Recommends: aufs-tools, ca-certificates, cgroupfs-mount | cgroup-lite, git, pigz, xz-utils, apparmor
Conflicts: docker (<< 1.5~), docker-ee, docker-engine, docker-engine-cs, docker.io, lxc-docker, lxc-docker-virtual-package
Replaces: docker-engine
Homepage: https://www.docker.com
Download-Size: 40.0 MB
APT-Sources: https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
Description: Docker: the open-source application container engine
 Docker is an open source project to build, ship and run any application as a
 lightweight container
 .
 Docker containers are both hardware-agnostic and platform-agnostic. This means
 they can run anywhere, from your laptop to the largest cloud compute instance and
 everything in between - and they don't require you to use a particular
 language, framework or packaging system. That makes them great building blocks
 for deploying and scaling web apps, databases, and backend services without
 depending on a particular stack or provider.

And I guess it would make sense to add Dockerfile.alpine. It does work for amd64 and is significantly smaller, but I haven't gotten it to work on RPi for some reason (tried again today with arm32v6 specifically but always get error Command failed with signal "SIGILL"..

grempe commented 5 years ago

On that server (built with a packer.io script), it is installed via:

    {
      "type": "shell",
      "inline": [
        "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -",
        "sudo add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\"",
        "sudo apt-get update",
        "apt-cache policy docker-ce",
        "sudo apt-get install -y docker-ce make",
        "sudo usermod -aG docker ${USER}"
      ]
    },
    {
      "type": "shell",
      "inline": [
        "sudo mkdir -p /usr/local/bin",
        "sudo curl -s -L \"https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose",
        "sudo chmod +x /usr/local/bin/docker-compose"
      ]
    },

However, keep in mind. This all has to work, without Node operator intervention, on all Nodes in the Chainpoint Network upon next upgrade.