diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..db38ef4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,65 @@ +FROM node:8.11.3-stretch + +MAINTAINER Andre Medeiros + +ENV EMBARK_VERSION=3.1.5 \ + GANACHE_VERSION=6.1.4 \ + GETH_VERSION=1.8.11-dea1ce05 \ + IPFS_VERSION=0.4.15 + +# IPFS: 5001 8080 +# Go Ethereum: 30303/tcp 30301/udp 8545 +# Embark: 8000 8546 8545 +# Swarm: 8500 +EXPOSE 5001 8080 30303/tcp 30301/udp 8545 8546 8000 8500 + +RUN adduser --disabled-password --shell /bin/bash --gecos "" embark \ + # Install geth + && curl -fsSLO --compressed "https://gethstore.blob.core.windows.net/builds/geth-alltools-linux-amd64-${GETH_VERSION}.tar.gz" \ + && tar -xvzf "geth-alltools-linux-amd64-${GETH_VERSION}.tar.gz" \ + && for geth_tool in \ + abigen \ + bootnode \ + evm \ + geth \ + puppeth \ + rlpdump \ + swarm \ + wnode \ + ; do \ + cp "geth-alltools-linux-amd64-${GETH_VERSION}/${geth_tool}" "/usr/local/bin/${geth_tool}"; \ + done \ + && rm -rf "geth-alltools-linux-amd64-${GETH_VERSION}*"\ + # Install ipfs + && curl -fsSLO --compressed "https://dist.ipfs.io/go-ipfs/v${IPFS_VERSION}/go-ipfs_v${IPFS_VERSION}_linux-amd64.tar.gz" \ + && tar -xvzf "go-ipfs_v${IPFS_VERSION}_linux-amd64.tar.gz" \ + && cp go-ipfs/ipfs /usr/local/bin/ipfs \ + && rm -rf go-ipfs "go-ipfs_v${IPFS_VERSION}_linux-amd64.tar.gz" \ + && mkdir /dapp \ + && chown embark:embark /dapp + +USER embark + +RUN mkdir /home/embark/.npm-packages \ + && echo prefix=/home/embark/.npm-packages > /home/embark/.npmrc \ + && for directive in \ + "export NPM_PACKAGES=\$HOME/.npm-packages" \ + "export NODE_PATH=\$NPM_PACKAGES/lib/node_modules:\$NODE_PATH" \ + "export PATH=\$NPM_PACKAGES/bin:\$PATH" \ + ; do \ + echo ${directive} >> /home/embark/.profile \ + && echo ${directive} >> /home/embark/.bashrc; \ + done \ + # Ensure we source the updated bashrc + && . ~/.bashrc \ + # Install embark and the simulator + && npm install -g "embark@${EMBARK_VERSION}" "ganache-cli@${GANACHE_VERSION}" \ + # Initialize IPFS + && ipfs init \ + # Cleanup build stuff + && echo "Done" + +WORKDIR /dapp + +CMD ["embark"] + diff --git a/README.md b/README.md index 1fe0c23..52be928 100644 --- a/README.md +++ b/README.md @@ -1 +1,67 @@ -# embark-docker \ No newline at end of file +# Embark for Docker + +## Updating versions + +* Open `Dockerfile` +* On the `ENV` directive, update necessary versions. + +An exception to this is the NodeJS version, which needs to be updated in the `FROM` directive instead. + +## Building + +Building requires Docker to be installed on your local machine. + +### Scripted + +If you have Ruby installed in your system, run: + +``` +$ ruby script/build +``` + +To release, add `--release` as a parameter of the build script. + +### Manually + +Building and releasing manually isn't too hard either, but there are a couple steps. + +#### Tags + +To facilitate the images being found, we tag them with the following rules (as an example, the `3.1.5` version will be used.) + +- Tag with `statusim/embark:latest` if `3.1.5` is the latest version. +- Tag with `statusim/embark:3.1.5` +- Tag with `statusim/embark:3.1` if `3.1.5` is the highest patch level on `3.1` +- Tag with `statusim/embark:3` if `3.1.5` is the highest minor and patch level on `3` + +#### Generating the image + +To generate the image, run: + +``` +docker build . -t statusim/embark: [...tags] +``` + +## Releasing + +Releasing requires that you're authenticated to Docker Hub. To do so, run: + +``` +$ docker login +``` + +### Scripted + +If you have Ruby installed in your system, run: + +``` +$ ruby script/build --release +``` + +### Manual + +Pushing the tags manually implies that the image has been previously built. To push your local images, run: + +``` +docker push statusim/embark:version +``` diff --git a/script/build b/script/build new file mode 100755 index 0000000..4a5131b --- /dev/null +++ b/script/build @@ -0,0 +1,73 @@ +#!/usr/bin/env ruby +require 'json' +require 'net/http' +require 'rubygems' + +class CLI + def run + puts 'Building latest' if latest? + puts "Tags: #{ tags_for_embark_version.join(', ') }" + + command = ['docker', 'build', '.'] + tags_for_embark_version.each { |tag| command << "-t=statusim/embark:#{tag}" } + + system(command.join(' ')) + + push_to_registry if ARGV.include?('--release') + end + + private + + def push_to_registry + tags_for_embark_version.each do |tag| + command = ['docker', 'push', "statusim/embark:#{tag}"] + system(command.join(' ')) + end + end + + def embark_versions + embark_versions ||= begin + package_info['time'].keys.map do |v| + Gem::Version.new(v) rescue nil + end.compact.select { |v| v < Gem::Version.new('7.0.0') } + end + end + + def package_info + package_info ||= begin + json = Net::HTTP.get('registry.npmjs.org', '/embark') + JSON.parse(json) + end + end + + + def embark_version + embark_version ||= begin + dockerfile_path = File.expand_path('../../Dockerfile', __FILE__) + dockerfile = File.open(dockerfile_path, 'r').read + Gem::Version.new(dockerfile.match(/EMBARK_VERSION=([0-9.]*)/)[1]) + end + end + + def latest? + package_info['dist-tags']['latest'] == embark_version.to_s + end + + def tags_for_embark_version + tags = [] + tags << 'latest' if latest? + tags << embark_version + + # Version being X.Y.Z, figure out if we're the largest X.Y + same_minor_versions = embark_versions.select { |ev| ev.segments[0..1] == embark_version.segments[0..1] }.sort + tags << embark_version.segments[0..1].join('.') if embark_version == same_minor_versions.last + + # Version being X.Y.Z, figure out if we're the latest X + same_major_versions = embark_versions.select { |ev| ev.segments[0] == embark_version.segments[0] }.sort + tags << embark_version.segments[0].to_s if embark_version == same_major_versions.last + + tags + end +end + +CLI.new.run