From ca5958d696057cff94c533a9005a1a3a090efd31 Mon Sep 17 00:00:00 2001 From: Daniel Dent Date: Wed, 21 Jan 2015 04:09:47 -0800 Subject: [PATCH] Meteor 1.0.3.1 support. ONBUILD tags added. * Resolves #1 * Deprecates demeteorizer support. * Updated README * Meteor releases <= 1.0.2.1 now have their artifacts frozen to releases on this GitHub repo. --- 1.0.1/Dockerfile | 3 +- 1.0.1/meteor-installer.patch | 2 +- 1.0.2.1/Dockerfile | 3 +- 1.0.2.1/meteor-installer.patch | 2 +- 1.0.2/Dockerfile | 3 +- 1.0.2/meteor-installer.patch | 2 +- 1.0.3.1-onbuild/Dockerfile | 11 ++++++ 1.0.3.1/Dockerfile | 31 +++++++++++++++++ 1.0.3.1/meteor-installer.patch | 55 ++++++++++++++++++++++++++++++ 1.0.3.1/vboxsf-shim.sh | 10 ++++++ README.md | 62 ++++++++++++++++++++++------------ latest/Dockerfile | 2 +- latest/meteor-installer.patch | 2 +- onbuild/Dockerfile | 11 ++++++ 14 files changed, 169 insertions(+), 30 deletions(-) create mode 100644 1.0.3.1-onbuild/Dockerfile create mode 100644 1.0.3.1/Dockerfile create mode 100644 1.0.3.1/meteor-installer.patch create mode 100755 1.0.3.1/vboxsf-shim.sh create mode 100644 onbuild/Dockerfile diff --git a/1.0.1/Dockerfile b/1.0.1/Dockerfile index 97cbc90..83f2531 100644 --- a/1.0.1/Dockerfile +++ b/1.0.1/Dockerfile @@ -5,6 +5,7 @@ ENV METEOR_VERSION 1.0.1 ENV METEOR_INSTALLER_SHA256 56737bd411f136e35cea34681db3ceabc10ee00f98371b9fee5270102ace7a3c ENV METEOR_LINUX_X86_32_SHA256 df48d2bb09c818fa7ad62bfc9a649e0e9132146a756928713f3443b91f74a0ce ENV METEOR_LINUX_X86_64_SHA256 bd8976dbbe3719a5a26d4064685ea8ef70d21086d5a3fad6ebd380a476878ceb +ENV TARBALL_URL_OVERRIDE https://github.com/DanielDent/docker-meteor/releases/download/v${RELEASE}/meteor-bootstrap-${PLATFORM}-${RELEASE}.tar.gz # 1. Download & verify the meteor installer. # 2. Patch it to validate the meteor tarball's checksums. @@ -12,7 +13,7 @@ ENV METEOR_LINUX_X86_64_SHA256 bd8976dbbe3719a5a26d4064685ea8ef70d21086d5a3fad6e COPY meteor-installer.patch /tmp/meteor/meteor-installer.patch COPY vboxsf-shim.sh /usr/local/bin/vboxsf-shim -RUN curl -SL https://install.meteor.com/ -o /tmp/meteor/inst \ +RUN curl -SL https://github.com/DanielDent/docker-meteor/releases/download/v1.0.1/installer-1.0.1.sh -o /tmp/meteor/inst \ && sed -e "s/^RELEASE=.*/RELEASE=\"\$METEOR_VERSION\"/" /tmp/meteor/inst > /tmp/meteor/inst-canonical \ && echo $METEOR_INSTALLER_SHA256 /tmp/meteor/inst-canonical | sha256sum -c \ && patch /tmp/meteor/inst /tmp/meteor/meteor-installer.patch \ diff --git a/1.0.1/meteor-installer.patch b/1.0.1/meteor-installer.patch index 26dde97..775bc97 100644 --- a/1.0.1/meteor-installer.patch +++ b/1.0.1/meteor-installer.patch @@ -38,7 +38,7 @@ echo "Downloading Meteor distribution" -curl --progress-bar --fail "$TARBALL_URL" | tar -xzf - -C "$INSTALL_TMPDIR" -o +INSTALLER_TARBALL=$(mktemp) -+eval curl --progress-bar --fail "${TARBALL_URL_OVERRIDE:-$TARBALL_URL}" > $INSTALLER_TARBALL ++eval curl -L --progress-bar --fail "${TARBALL_URL_OVERRIDE:-$TARBALL_URL}" > $INSTALLER_TARBALL +# If we got passed an explicit version, then we also expect +# to be passed that version's checksums. +if [ "${METEOR_VERSION:-latest}" != "latest" ]; then diff --git a/1.0.2.1/Dockerfile b/1.0.2.1/Dockerfile index d0f6a95..fc8608c 100644 --- a/1.0.2.1/Dockerfile +++ b/1.0.2.1/Dockerfile @@ -5,6 +5,7 @@ ENV METEOR_VERSION 1.0.2.1 ENV METEOR_INSTALLER_SHA256 56737bd411f136e35cea34681db3ceabc10ee00f98371b9fee5270102ace7a3c ENV METEOR_LINUX_X86_32_SHA256 d44108ee1f303232119004649b7c3fffe8c758f27af51fa3a4823c9385114034 ENV METEOR_LINUX_X86_64_SHA256 dea6204ba3f0495bf83152bdc114b71e1929345fb442b7c37765251c09527132 +ENV TARBALL_URL_OVERRIDE https://github.com/DanielDent/docker-meteor/releases/download/v${RELEASE}/meteor-bootstrap-${PLATFORM}-${RELEASE}.tar.gz # 1. Download & verify the meteor installer. # 2. Patch it to validate the meteor tarball's checksums. @@ -12,7 +13,7 @@ ENV METEOR_LINUX_X86_64_SHA256 dea6204ba3f0495bf83152bdc114b71e1929345fb442b7c37 COPY meteor-installer.patch /tmp/meteor/meteor-installer.patch COPY vboxsf-shim.sh /usr/local/bin/vboxsf-shim -RUN curl -SL https://install.meteor.com/ -o /tmp/meteor/inst \ +RUN curl -SL https://github.com/DanielDent/docker-meteor/releases/download/v1.0.2.1/installer-1.0.2.1.sh -o /tmp/meteor/inst \ && sed -e "s/^RELEASE=.*/RELEASE=\"\$METEOR_VERSION\"/" /tmp/meteor/inst > /tmp/meteor/inst-canonical \ && echo $METEOR_INSTALLER_SHA256 /tmp/meteor/inst-canonical | sha256sum -c \ && patch /tmp/meteor/inst /tmp/meteor/meteor-installer.patch \ diff --git a/1.0.2.1/meteor-installer.patch b/1.0.2.1/meteor-installer.patch index 26dde97..775bc97 100644 --- a/1.0.2.1/meteor-installer.patch +++ b/1.0.2.1/meteor-installer.patch @@ -38,7 +38,7 @@ echo "Downloading Meteor distribution" -curl --progress-bar --fail "$TARBALL_URL" | tar -xzf - -C "$INSTALL_TMPDIR" -o +INSTALLER_TARBALL=$(mktemp) -+eval curl --progress-bar --fail "${TARBALL_URL_OVERRIDE:-$TARBALL_URL}" > $INSTALLER_TARBALL ++eval curl -L --progress-bar --fail "${TARBALL_URL_OVERRIDE:-$TARBALL_URL}" > $INSTALLER_TARBALL +# If we got passed an explicit version, then we also expect +# to be passed that version's checksums. +if [ "${METEOR_VERSION:-latest}" != "latest" ]; then diff --git a/1.0.2/Dockerfile b/1.0.2/Dockerfile index f1dcf0b..582ff25 100644 --- a/1.0.2/Dockerfile +++ b/1.0.2/Dockerfile @@ -5,6 +5,7 @@ ENV METEOR_VERSION 1.0.2 ENV METEOR_INSTALLER_SHA256 56737bd411f136e35cea34681db3ceabc10ee00f98371b9fee5270102ace7a3c ENV METEOR_LINUX_X86_32_SHA256 6d4a05171951f6e9182a052afccab8ea9fc1da1cc08ea5774b961bf18b4f9f04 ENV METEOR_LINUX_X86_64_SHA256 a1e6622a843d45bb883d43679751041dcd06d9b7ee6b2058b6fd3fd030669011 +ENV TARBALL_URL_OVERRIDE https://github.com/DanielDent/docker-meteor/releases/download/v${RELEASE}/meteor-bootstrap-${PLATFORM}-${RELEASE}.tar.gz # 1. Download & verify the meteor installer. # 2. Patch it to validate the meteor tarball's checksums. @@ -12,7 +13,7 @@ ENV METEOR_LINUX_X86_64_SHA256 a1e6622a843d45bb883d43679751041dcd06d9b7ee6b2058b COPY meteor-installer.patch /tmp/meteor/meteor-installer.patch COPY vboxsf-shim.sh /usr/local/bin/vboxsf-shim -RUN curl -SL https://install.meteor.com/ -o /tmp/meteor/inst \ +RUN curl -SL https://github.com/DanielDent/docker-meteor/releases/download/v1.0.2/installer-1.0.2.sh -o /tmp/meteor/inst \ && sed -e "s/^RELEASE=.*/RELEASE=\"\$METEOR_VERSION\"/" /tmp/meteor/inst > /tmp/meteor/inst-canonical \ && echo $METEOR_INSTALLER_SHA256 /tmp/meteor/inst-canonical | sha256sum -c \ && patch /tmp/meteor/inst /tmp/meteor/meteor-installer.patch \ diff --git a/1.0.2/meteor-installer.patch b/1.0.2/meteor-installer.patch index 26dde97..775bc97 100644 --- a/1.0.2/meteor-installer.patch +++ b/1.0.2/meteor-installer.patch @@ -38,7 +38,7 @@ echo "Downloading Meteor distribution" -curl --progress-bar --fail "$TARBALL_URL" | tar -xzf - -C "$INSTALL_TMPDIR" -o +INSTALLER_TARBALL=$(mktemp) -+eval curl --progress-bar --fail "${TARBALL_URL_OVERRIDE:-$TARBALL_URL}" > $INSTALLER_TARBALL ++eval curl -L --progress-bar --fail "${TARBALL_URL_OVERRIDE:-$TARBALL_URL}" > $INSTALLER_TARBALL +# If we got passed an explicit version, then we also expect +# to be passed that version's checksums. +if [ "${METEOR_VERSION:-latest}" != "latest" ]; then diff --git a/1.0.3.1-onbuild/Dockerfile b/1.0.3.1-onbuild/Dockerfile new file mode 100644 index 0000000..14a7c1d --- /dev/null +++ b/1.0.3.1-onbuild/Dockerfile @@ -0,0 +1,11 @@ +FROM danieldent/meteor:1.0.3.1 +ONBUILD COPY . /opt/src +ONBUILD WORKDIR /opt/src +ONBUILD RUN meteor build .. --directory \ + && cd ../bundle/programs/server \ + && npm install \ + && rm -rf /opt/src +ONBUILD WORKDIR /opt/bundle +ONBUILD USER nobody +ONBUILD ENV PORT 3000 +CMD ["/usr/local/bin/node", "main.js"] \ No newline at end of file diff --git a/1.0.3.1/Dockerfile b/1.0.3.1/Dockerfile new file mode 100644 index 0000000..b3f1663 --- /dev/null +++ b/1.0.3.1/Dockerfile @@ -0,0 +1,31 @@ +FROM node:0.10 +MAINTAINER Daniel Dent (https://www.danieldent.com/) + +ENV METEOR_VERSION 1.0.3.1 +ENV METEOR_INSTALLER_SHA256 4020ef4d3bc257cd570b5b2d49e3490699c52d0fd98453e29b7addfbdfba9c80 +ENV METEOR_LINUX_X86_32_SHA256 d6260e20aa723109d1ed0be4bbc260cf33322110e1075e230587d29e8c327be2 +ENV METEOR_LINUX_X86_64_SHA256 d732cb54215bde3f08002b49364d45f827cf25db291608f8a625d0f7e70ca97e + +# 1. Download & verify the meteor installer. +# 2. Patch it to validate the meteor tarball's checksums. +# 3. Install meteor + +COPY meteor-installer.patch /tmp/meteor/meteor-installer.patch +COPY vboxsf-shim.sh /usr/local/bin/vboxsf-shim +RUN curl -SL https://install.meteor.com/ -o /tmp/meteor/inst \ + && sed -e "s/^RELEASE=.*/RELEASE=\"\$METEOR_VERSION\"/" /tmp/meteor/inst > /tmp/meteor/inst-canonical \ + && echo $METEOR_INSTALLER_SHA256 /tmp/meteor/inst-canonical | sha256sum -c \ + && patch /tmp/meteor/inst /tmp/meteor/meteor-installer.patch \ + && chmod +x /tmp/meteor/inst \ + && /tmp/meteor/inst \ + && rm -rf /tmp/meteor + +# 4. Install demeteorizer (using my fork of demeteorizer until Dockerfile support is merged upstream) + +RUN npm install -g DanielDent/demeteorizer#v2.1.0 \ + && npm cache clear + +VOLUME /app +WORKDIR /app +EXPOSE 3000 +CMD [ "meteor" ] diff --git a/1.0.3.1/meteor-installer.patch b/1.0.3.1/meteor-installer.patch new file mode 100644 index 0000000..775bc97 --- /dev/null +++ b/1.0.3.1/meteor-installer.patch @@ -0,0 +1,55 @@ +--- meteor-installer 2014-12-10 15:22:12.232084632 -0800 ++++ meteor-installer.new 2014-12-10 15:27:20.532084632 -0800 +@@ -31,6 +31,11 @@ + ## know what shell the user has. Debian uses 'dash' for 'sh', for + ## example. + ++# If METEOR_VERSION is set, we want to install that instead. ++if [ "${METEOR_VERSION}" != "latest" ] ; then ++ RELEASE="${METEOR_VERSION:-$RELEASE}" ++fi ++ + PREFIX="/usr/local" + + set -e +@@ -41,7 +46,7 @@ + + + UNAME=$(uname) +-if [ "$UNAME" != "Linux" -a "$UNAME" != "Darwin" ] ; then ++if [ "$UNAME" != "Linux" ] ; then + echo "Sorry, this OS is not supported yet." + exit 1 + fi +@@ -73,8 +78,10 @@ + LINUX_ARCH=$(uname -m) + if [ "${LINUX_ARCH}" = "i686" ] ; then + PLATFORM="os.linux.x86_32" ++ TARBALL_CHECKSUM="${METEOR_LINUX_X86_32_SHA256:-}" + elif [ "${LINUX_ARCH}" = "x86_64" ] ; then + PLATFORM="os.linux.x86_64" ++ TARBALL_CHECKSUM="${METEOR_LINUX_X86_64_SHA256:-}" + else + echo "Unusable architecture: ${LINUX_ARCH}" + echo "Meteor only supports i686 and x86_64 for now." +@@ -118,7 +125,19 @@ + rm -rf "$INSTALL_TMPDIR" + mkdir "$INSTALL_TMPDIR" + echo "Downloading Meteor distribution" +-curl --progress-bar --fail "$TARBALL_URL" | tar -xzf - -C "$INSTALL_TMPDIR" -o ++INSTALLER_TARBALL=$(mktemp) ++eval curl -L --progress-bar --fail "${TARBALL_URL_OVERRIDE:-$TARBALL_URL}" > $INSTALLER_TARBALL ++# If we got passed an explicit version, then we also expect ++# to be passed that version's checksums. ++if [ "${METEOR_VERSION:-latest}" != "latest" ]; then ++ if ! echo "$TARBALL_CHECKSUM $INSTALLER_TARBALL" | sha256sum -c; then ++ rm -rf "${INSTALLER_TARBALL}" ++ echo "Installer tarball checksum failed." ++ exit 1 ++ fi ++fi ++tar -xzf $INSTALLER_TARBALL -C "$INSTALL_TMPDIR" -o ++rm -rf "${INSTALLER_TARBALL}" + # bomb out if it didn't work, eg no net + test -x "${INSTALL_TMPDIR}/.meteor/meteor" + mv "${INSTALL_TMPDIR}/.meteor" "$HOME" diff --git a/1.0.3.1/vboxsf-shim.sh b/1.0.3.1/vboxsf-shim.sh new file mode 100755 index 0000000..2da81dd --- /dev/null +++ b/1.0.3.1/vboxsf-shim.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# If there's a .meteor/local directory we can mount on top of, we create a directory in /tmp for a bind mount. +# This allows MongoDB to acquire the lock it needs and meteor's development server to be happy with filesystem sync. + +if ! [ -d /tmp/meteor-local ]; then + mkdir /tmp/meteor-local && mount -o bind /tmp/meteor-local .meteor/local || rmdir /tmp/meteor-local +fi + +exec "$@" diff --git a/README.md b/README.md index 47522cd..e70de89 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ # Supported tags and respective `Dockerfile` links - [`latest` (*latest/Dockerfile*)](https://github.com/DanielDent/docker-meteor/blob/master/latest/Dockerfile) -- [`1.0.2.1`, `1.0`, `1` (*1.0.2.1/Dockerfile*)](https://github.com/DanielDent/docker-meteor/blob/master/1.0.2.1/Dockerfile) +- [`onbuild` (*onbuild/Dockerfile*)](https://github.com/DanielDent/docker-meteor/blob/master/onbuild/Dockerfile) +- [`1.0.3.1`, `1.0`, `1` (*1.0.3.1/Dockerfile*)](https://github.com/DanielDent/docker-meteor/blob/master/1.0.3.1/Dockerfile) +- [`1.0.3.1-onbuild`, `1.0-onbuild`, `1-onbuild` (*1.0.3.1-onbuild/Dockerfile*)](https://github.com/DanielDent/docker-meteor/blob/master/1.0.3.1-onbuild/Dockerfile) +- [`1.0.2.1`, (*1.0.2.1/Dockerfile*)](https://github.com/DanielDent/docker-meteor/blob/master/1.0.2.1/Dockerfile) - [`1.0.2`, (*1.0.2/Dockerfile*)](https://github.com/DanielDent/docker-meteor/blob/master/1.0.2/Dockerfile) - [`1.0.1`, (*1.0.1/Dockerfile*)](https://github.com/DanielDent/docker-meteor/blob/master/1.0.1/Dockerfile) @@ -15,24 +18,27 @@ With Meteor you write apps: * that send data over the wire, rather than HTML * using your choice of popular open-source libraries -Documentation is available at http://docs.meteor.com/ +Documentation is available at [http://docs.meteor.com/](http://docs.meteor.com/). # What's included in these images? -[Meteor](https://www.meteor.com/), a fork of [demeteorizer](https://github.com/DanielDent/demeteorizer) with Dockerfile -support, and a [small shim](https://github.com/DanielDent/docker-meteor/blob/master/latest/vboxsf-shim.sh) that +[Meteor](https://www.meteor.com/) and a [small shim](https://github.com/DanielDent/docker-meteor/blob/master/latest/vboxsf-shim.sh) that addresses a compatibility issue with boot2docker. +A fork of [demeteorizer](https://github.com/DanielDent/demeteorizer) with a patch for Dockerfile support remains +included in this release. Support has been deprecated and demeteorizer will be dropped from future releases. +The patch has not been merged upstream and demeteorizer is not required with the currently documented workflow. + # Why use these images? * To install a packaged, specific version of Meteor. -* To dockerize a Meteor app for your Continuous Integration/Continuous Delivery/Production environments. +* To Dockerize a Meteor app for your Continuous Integration/Continuous Delivery/Production environments. * To have a repeatable and easily maintained development environment. * To do Meteor development on Windows (using boot2docker). -The `latest` tag builds whatever Meteor publishes at https://install.meteor.com/, as long as the install script does -not change. Images tagged for a specific Meteor version checksum both the installer and the tarball the installer -downloads. +The `latest` tag builds whatever Meteor publishes at [https://install.meteor.com/](https://install.meteor.com/), as long +as the install script does not change. Images tagged for a specific Meteor version checksum both the installer and the +tarball the installer downloads. # How to use these images @@ -63,31 +69,43 @@ provides in development mode. docker run --name mydb -d mongo docker run --cap-add SYS_ADMIN -it --rm -p 3000:3000 --link mydb:db -e "MONGO_URL=mongodb://db" -v "$(pwd)":/app danieldent/meteor vboxsf-shim meteor -## Example: Dockerizing your Meteor App for CI/CD/Production - -Create a `Dockerfile` for your Meteor app. Place it somewhere where it won't cause problems, such as in `.meteor/Dockerfile`. +## Example: Dockerizing your Meteor App for CI/CD/Production Builds - FROM node:0.10-onbuild - EXPOSE 3000 - ENV PORT 3000 - USER nobody +Create a `.dockerignore` file in your Meteor source directory to exclude Meteor's development build cache. -In this example, your Meteor app will run as `nobody` within the Docker container. This ensures the app does not have -write access to its own files, which could help reduce the impact of certain security issues. It also makes it harder to -accidentally write code which makes changes to the filesystem. + .meteor/local -Dockerize your app: +Create a `Dockerfile` for your Meteor app and place it in your Meteor source directory. Use one of the onbuild tags. - docker run -it --rm -v "$(pwd)":/app danieldent/meteor demeteorizer -D .meteor/Dockerfile + FROM danieldent/meteor:onbuild -Build the Docker image for your app: +Build the Docker image for your app (assumes you are currently in the Meteor source directory): - docker build -t exampleapp .demeteorized + docker build -t exampleapp . Run your app in its container, using another Docker container for the MongoDB database: + docker run --name exampleAppDb -d mongo docker run -it --rm -p 3000:3000 --link exampleAppDb:db -e "MONGO_URL=mongodb://db" -e "ROOT_URL=http://localhost:3000" exampleapp +# Defaults + +By default, your Meteor app will run as `nobody` within the Docker container. This ensures the app does not have +write access to its own files, which could help reduce the impact of certain security issues. It also makes it harder to +accidentally write code which makes changes to the filesystem. Port 3000 will be exposed by default. Here's a +`Dockerfile` which changes the defaults. It usually shouldn't be necessary to change the port on which your Meteor app +listens - Docker's port mapping features allows the port used *inside* the container to be different than the port +which is exposed *outside* the container. + + FROM danieldent/meteor:onbuild + EXPOSE 4000 + ENV PORT 4000 + USER root + +While it's possible to set additional variables as part of the build (such as `MONGO_URL`, `ROOT_URL`, or +`METEOR_SETTINGS`), it may be a better choice to [pass configuration that is likely to vary between deployments of the +application as runtime environment variables](http://12factor.net/config). + # Issues, Contributing If you run into any problems with these images, please check for issues on [GitHub](https://github.com/DanielDent/docker-meteor/issues). diff --git a/latest/Dockerfile b/latest/Dockerfile index 74d3611..187a8ec 100644 --- a/latest/Dockerfile +++ b/latest/Dockerfile @@ -2,7 +2,7 @@ FROM node:latest MAINTAINER Daniel Dent (https://www.danieldent.com/) ENV METEOR_VERSION latest -ENV METEOR_INSTALLER_SHA256 56737bd411f136e35cea34681db3ceabc10ee00f98371b9fee5270102ace7a3c +ENV METEOR_INSTALLER_SHA256 4020ef4d3bc257cd570b5b2d49e3490699c52d0fd98453e29b7addfbdfba9c80 ENV METEOR_LINUX_X86_32_SHA256 latest ENV METEOR_LINUX_X86_64_SHA256 latest diff --git a/latest/meteor-installer.patch b/latest/meteor-installer.patch index 26dde97..775bc97 100644 --- a/latest/meteor-installer.patch +++ b/latest/meteor-installer.patch @@ -38,7 +38,7 @@ echo "Downloading Meteor distribution" -curl --progress-bar --fail "$TARBALL_URL" | tar -xzf - -C "$INSTALL_TMPDIR" -o +INSTALLER_TARBALL=$(mktemp) -+eval curl --progress-bar --fail "${TARBALL_URL_OVERRIDE:-$TARBALL_URL}" > $INSTALLER_TARBALL ++eval curl -L --progress-bar --fail "${TARBALL_URL_OVERRIDE:-$TARBALL_URL}" > $INSTALLER_TARBALL +# If we got passed an explicit version, then we also expect +# to be passed that version's checksums. +if [ "${METEOR_VERSION:-latest}" != "latest" ]; then diff --git a/onbuild/Dockerfile b/onbuild/Dockerfile new file mode 100644 index 0000000..f45a428 --- /dev/null +++ b/onbuild/Dockerfile @@ -0,0 +1,11 @@ +FROM danieldent/meteor:latest +ONBUILD COPY . /opt/src +ONBUILD WORKDIR /opt/src +ONBUILD RUN meteor build .. --directory \ + && cd ../bundle/programs/server \ + && npm install \ + && rm -rf /opt/src +ONBUILD WORKDIR /opt/bundle +ONBUILD USER nobody +ONBUILD ENV PORT 3000 +CMD ["/usr/local/bin/node", "main.js"] \ No newline at end of file