diff --git a/serving/samples/helloworld-elixir/.gcloudignore b/serving/samples/helloworld-elixir/.gcloudignore new file mode 100644 index 00000000000..9d29dd25001 --- /dev/null +++ b/serving/samples/helloworld-elixir/.gcloudignore @@ -0,0 +1,24 @@ +# For building with Google Cloud Build using the gcloud command line tool. +# Similar to .gitignore, except we want the /config/*.secrete.exs uploaded for the build. + +# App artifacts +/_build +/db +/deps +/*.ez + +# Generated on crash by the VM +erl_crash.dump + +# Generated on crash by NPM +npm-debug.log +/assets/package-lock.json + +# Static artifacts +/assets/node_modules + +# Since we are building assets from assets/, +# we ignore priv/static. You may want to comment +# this depending on your deployment strategy. +/priv/static/ + diff --git a/serving/samples/helloworld-elixir/Dockerfile b/serving/samples/helloworld-elixir/Dockerfile index 20f68416236..fd5395a7614 100644 --- a/serving/samples/helloworld-elixir/Dockerfile +++ b/serving/samples/helloworld-elixir/Dockerfile @@ -1,4 +1,5 @@ -FROM elixir:alpine +FROM elixir:1.6.6-alpine + ARG APP_NAME=hello ARG PHOENIX_SUBDIR=. ENV MIX_ENV=prod REPLACE_OS_VARS=true TERM=xterm @@ -8,6 +9,7 @@ RUN apk update \ && mix local.rebar --force \ && mix local.hex --force COPY . . + RUN mix do deps.get, deps.compile, compile RUN cd ${PHOENIX_SUBDIR}/assets \ && npm install \ @@ -17,8 +19,18 @@ RUN cd ${PHOENIX_SUBDIR}/assets \ RUN mix release --env=prod --verbose \ && mv _build/prod/rel/${APP_NAME} /opt/release \ && mv /opt/release/bin/${APP_NAME} /opt/release/bin/start_server + FROM alpine:latest RUN apk update && apk --no-cache --update add bash openssl-dev + +RUN addgroup -g 1000 appuser && \ + adduser -S -u 1000 -G appuser appuser + +RUN mkdir -p /opt/app/var +RUN chown appuser /opt/app/var + +USER appuser + ENV PORT=8080 MIX_ENV=prod REPLACE_OS_VARS=true WORKDIR /opt/app EXPOSE 8080 diff --git a/serving/samples/helloworld-elixir/README.md b/serving/samples/helloworld-elixir/README.md index 065e30d5a01..49cf13a270d 100644 --- a/serving/samples/helloworld-elixir/README.md +++ b/serving/samples/helloworld-elixir/README.md @@ -38,7 +38,8 @@ Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. ```docker # Start from a base image for elixir - FROM elixir:alpine + # Phoenix works best on pre 1.7 at the moment. + FROM elixir:1.6.6-alpine # Set up Elixir and Phoenix ARG APP_NAME=hello @@ -46,7 +47,7 @@ Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. ENV MIX_ENV=prod REPLACE_OS_VARS=true TERM=xterm WORKDIR /opt/app - # Compile assets. + # Update nodejs, rebar, and hex. RUN apk update \ && apk --no-cache --update add nodejs nodejs-npm \ && mix local.rebar --force \ @@ -69,10 +70,19 @@ Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. # Prepare final layer FROM alpine:latest RUN apk update && apk --no-cache --update add bash openssl-dev - ENV PORT=8080 MIX_ENV=prod REPLACE_OS_VARS=true - WORKDIR /opt/app + + # Add a user so the server will run as a non-root user. + RUN addgroup -g 1000 appuser && \ + adduser -S -u 1000 -G appuser appuser + # Pre-create necessary temp directory for erlang and set permissions. + RUN mkdir -p /opt/app/var + RUN chown appuser /opt/app/var + # Run everything else as 'appuser' + USER appuser # Document that the service listens on port 8080. + ENV PORT=8080 MIX_ENV=prod REPLACE_OS_VARS=true + WORKDIR /opt/app EXPOSE 8080 COPY --from=0 /opt/release . ENV RUNNER_LOG_DIR /var/log