9.0 KiB
Embark for Docker
Quick start
In a Bash shell:
source <(curl -L https://bit.ly/run_embark)
run_embark demo
cd embark_demo
run_embark
Note that the run_embark demo
command will create an embark_demo
directory in
the docker host's $PWD
.
Usage via run.sh
run.sh
is a Bash script that simplifies usage of the embark container: publishing
ports, bind mounting a host volume, and so on. The script exports a shell
function named run_embark
.
Many aspects of run_embark
's behavior can be overridden with environment
variables, and that approach can be (optionally) combined with docker build
.
export EMBARK_DOCKER_IMAGE=statusim/embark
export EMBARK_DOCKER_TAG=custom
export EMBARK_DOCKERFILE='https://github.com/embark-framework/embark-docker.git#master'
export EMBARK_VERSION='embark-framework/embark#develop'
export NODE_VERSION=10.7.0
export RUNNER='https://raw.githubusercontent.com/embark-framework/embark-docker/master/run.sh'
docker build \
--build-arg EMBARK_VERSION=$EMBARK_VERSION \
--build-arg NODE_TAG=$NODE_TAG \
-t $EMBARK_DOCKER_IMAGE:$EMBARK_DOCKER_TAG \
$EMBARK_DOCKERFILE
source <(curl $RUNNER)
run_embark demo
cd embark_demo
run_embark
Review the
Dockerfile
and
run.sh
for all possible overrides.
It's possible to pass additional options to docker run
by specifying them
before --
.
run_embark [docker-run-opts] -- [command]
To completely replace the default docker run
options:
EMBARK_DOCKER_RUN_OPTS_REPLACE=true
run_embark [docker-run-opts] -- [command]
By default run_embark
invokes docker run
with the
--rm
option,
making the embark container ephemeral, i.e. it will not persist on the docker
host's file system after the container exits. To override this behavior:
EMBARK_DOCKER_RUN_RM=false
run_embark [docker-run-opts] -- [command]
Note that if you have EMBARK_DOCKER_RUN_OPTS_REPLACE=true
, then --rm
would
need to be provided in [docker-run-opts]
, i.e. EMBARK_DOCKER_RUN_RM
will be
effectively ignored.
Shortcuts
These are equivalent:
run_embark
run_embark run
run_embark embark run
The following are also equivalent:
run_embark demo
run_embark embark demo
The same is true for the rest of the embark
commands. To see the full list:
run_embark --help
Utilities
The container comes equipped with
nodeenv
and
nvm
. A default
Node.js environment is
installed via nodeenv
during image build and placed in
~embark/.local/nodeenv/default
. The default
environment is automatically
activated by the container's entrypoint.
Both nodeenv
and nvm
can be used in
interactive and non-interactive scripts.
nodeenv
These are equivalent:
nodeenv --prebuilt --node 10.7.0 ~/.local/nodeenv/my_node
simple_nodeenv 10.7.0 my_node
Activate and deactivate environments with nac
and denac
.
nac my_node
denac
Note that simple_nodeenv
automatically activates an environment after
installation, while nodeenv
does not.
nvm
If nvm
is preferable, it needs to be loaded first.
nvm_load
nvm install --latest-npm 8.11.3
nvm deactivate
and nvm unload
will work as expected. It's also possible to
move between nodeenv
and nvm
environments without first deactivating or
unloading.
nac default
nvm_load && nvm use v10.7.0
# ^ assuming 10.7.0 is already installed
nac default
micro
The micro
editor is installed during image
build, should you need to edit files within a running container.
install-extras.sh
Some nice-to-have utilities are not installed by default, but this can be done
by running
install-extras.sh
as the root
user in an already running container.
docker exec -it $container_id install-extras.sh
Commands
Simple
A single command with options can be supplied directly.
run_embark bash
run_embark node -i -e 'console.log(process.version)'
# ^ press return again to get a blank REPL prompt
run_embark ps -ef
Compound
Compound commands should be passed to bash -[i]c
.
run_embark bash -c 'ps -ef && ls / ; which embark'
run_embark bash -c 'nvm_load && nvm install --latest-npm 8.11.3 && node --version && npm --version'
Bash
here-documents
can be used to compose scripts without employing an abundance of &&
, ;
, and
\
. Just be mindful of umatched quotes and quotes-escaping when building
meta-scripts; in such scenarios, use of
envsubst
is probably called for.
run_embark bash -c 'exec bash << "SCRIPT"
simple_nodeenv 10.7.0 my_node
npm i -g http-server
exec http-server -p 8000
SCRIPT
'
Since run_embark
mounts the docker host's $PWD
into the container's /dapp
, and
since /dapp
is the container's default working directory, it's also possible
to do:
run_embark ./my_script.sh
# ^ assuming my_script.sh is in the docker host's $PWD
Just make sure the script has a #!
line and that you did chmod +x my_script.sh
on the docker host before invoking run_embark
.
$EMBARK_DOCKER_RUN
For greater flexibility, you can specify a script with
$EMBARK_DOCKER_RUN
. Arguments passed to run_embark
will be forwarded to the
script, and extra flags can be provided to docker run
to forward docker host
environment variables.
Keep in mind that such scripts will run as the embark
user owing to the
container's entrypoint.
#!/bin/bash
# this script is located at /path/to/my_script.sh on the docker host, not necessarily in host's $PWD
# dangling "
c=container!
echo $HOST_HOSTNAME
echo $HOSTNAME
echo $@
echo $1
# a comment
echo $2
echo $3
eval echo \\\$\$3
# another comment
Invoke with:
EMBARK_DOCKER_RUN=/path/to/my_script.sh
a=host!
run_embark -e HOST_HOSTNAME=$HOSTNAME -- $a b c
Node.js variant:
#!/usr/bin/env node
// this script is located at /path/to/my_node_script.js on the docker host, not necessarily in host's $PWD
const o = {c: 'container!'};
console.log(process.env.HOST_HOSTNAME);
console.log(process.env.HOSTNAME);
console.log(JSON.stringify(process.argv));
console.log(process.argv[2]);
console.log(process.argv[3]);
console.log(process.argv[4]);
console.log(o[process.argv[4]]);
Invoke the same way:
EMBARK_DOCKER_RUN=/path/to/my_node_script.js
a=host!
run_embark -e HOST_HOSTNAME=$HOSTNAME -- $a b c
docker exec
When executing compound commands via docer exec
in a running embark
container, su-exec
and bash -[i]c
can be used together.
docker exec -it $container_id su-exec embark \
bash -ic 'exec bash << "SCRIPT"
simple_nodeenv 10.7.0 my_node || nac my_node
npm i -g http-server
exec http-server -p 8000
SCRIPT
'
To go non-interactive, manually source the embark user's .bash_env
.
docker exec -it $container_id su-exec embark \
bash -c 'exec bash << "SCRIPT"
. ~/.bash_env
simple_nodeenv 10.7.0 my_node || nac my_node
npm i -g http-server
exec http-server -p 8000
SCRIPT
'
Container development
Updating versions
- Open
Dockerfile
- On the
ARG
directives, update necessary versions.
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
if3.1.5
is the latest version. - Tag with
statusim/embark:3.1.5
- Tag with
statusim/embark:3.1
if3.1.5
is the highest patch level on3.1
- Tag with
statusim/embark:3
if3.1.5
is the highest minor and patch level on3
Generating the image
To generate the image, run:
docker build . -t statusim/embark:<version> [...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