Hyper-optimized Dockerfile for running multiple Habitat services

This Dockerfile template is designed for deploying a set of services with habitat-compose, but could also easily be stripped down a bit to build a single-service container without habitat-compose.

Habitat’s Docker exporter can provide equivalent containers, but this solution enables users to build containers with docker build . --build-arg HAB_LICENSE=accept-no-persist and not need to have Habitat installed or know how to use it. It also is highly optimized to produce slim layers and minimize how many new bytes need to be uploaded/stored for application updates.

FROM jarvus/habitat-compose:latest as habitat
ARG HAB_LICENSE=no-accept
ENV HAB_LICENSE=$HAB_LICENSE
ENV STUDIO_TYPE=Dockerfile
ENV HAB_ORIGIN=myorigin
RUN hab origin key generate
# pre-layer pkg_deps from ./habitat/plan.sh
COPY habitat/plan.sh /habitat/plan.sh
RUN hab pkg install \
    $({ cat '/habitat/plan.sh' && echo 'echo "${pkg_deps[@]/$pkg_origin\/*/}"'; } | hab pkg exec core/bash bash) \
    && hab pkg exec core/coreutils rm -rf /hab/{artifacts,src}/
# pre-layer pkg_deps from ./habitat/composite/plan.sh
COPY habitat/composite/plan.sh /habitat/composite/plan.sh
RUN hab pkg install \
    $({ cat '/habitat/composite/plan.sh' && echo 'echo "${pkg_deps[@]/$pkg_origin\/*/}"'; } | hab pkg exec core/bash bash) \
    && hab pkg exec core/coreutils rm -rf /hab/{artifacts,src}/


FROM habitat as builder
# pre-layer all pkg_build_deps from ./habitat/plan.sh
RUN hab pkg install \
    core/hab-plan-build \
    $({ cat '/habitat/plan.sh' && echo 'echo "${pkg_build_deps[@]/$pkg_origin\/*/}"'; } | hab pkg exec core/bash bash) \
    && hab pkg exec core/coreutils rm -rf /hab/{artifacts,src}/
# pre-layer all pkg_build_deps from ./habitat/composite/plan.sh
RUN hab pkg install \
    $({ cat '/habitat/composite/plan.sh' && echo 'echo "${pkg_build_deps[@]/$pkg_origin\/*/}"'; } | hab pkg exec core/bash bash) \
    && hab pkg exec core/coreutils rm -rf /hab/{artifacts,src}/
# build application
COPY . /src
RUN hab pkg exec core/hab-plan-build hab-plan-build /src
RUN hab pkg exec core/hab-plan-build hab-plan-build /src/habitat/composite


FROM habitat as runtime
# install .hart artifact from builder stage
COPY --from=builder /hab/cache/artifacts/$HAB_ORIGIN-* /hab/cache/artifacts/
RUN hab pkg install /hab/cache/artifacts/$HAB_ORIGIN-* \
    && hab pkg exec core/coreutils rm -rf /hab/{artifacts,src}/


# configure persistent volumes
RUN hab pkg exec core/coreutils mkdir -p /hab/svc/{mysql,myapp}/data \
    && hab pkg exec core/coreutils chown hab:hab -R /hab/svc/{mysql,myapp}/data

VOLUME ["/hab/svc/mysql/data", "/hab/svc/myapp/data"]


# configure entrypoint
ENTRYPOINT ["hab", "sup", "run"]
CMD ["myorigin/myapp-composite"]

:heart: this. This is similar to the “shim” container model I’ve been messing with. Excited to try this soon if I can.

1 Like