├── VERSION ├── CONTRIBUTORS.md ├── .gitignore ├── .dockerignore ├── LICENSE ├── README.md ├── Makefile └── Dockerfile /VERSION: -------------------------------------------------------------------------------- 1 | 23.2.3 2 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Contributors 2 | 3 | - Mårten Wikström (@mwik) 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .sonarlint 3 | .vscode 4 | dive.log 5 | slim.report.json 6 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .sonarlint 6 | .vscode 7 | CONTRIBUTORS.md 8 | dive.log 9 | Dockerfile 10 | LICENSE 11 | Makefile 12 | README.md 13 | slim.report.json 14 | VERSION 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 - 2021 beardedeagle. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker + Alpine + Erlang = Love 2 | 3 | This Dockerfile provides a good base build image to use in multistage builds for Erlang apps. It comes with the latest version of Alpine, Erlang and Rebar. It is intended for use in creating release images with or for your application and allows you to avoid cross-compiling releases. The exception of course is if your app has NIFs which require a native compilation toolchain, but that is an exercise left to the user. 4 | 5 | No effort has been made to make this image suitable to run in unprivileged environments. The repository owner is not responsible for any loses that result from improper usage or security practices, as it is expected that the user of this image will implement proper security practices themselves. 6 | 7 | ## Software/Language Versions 8 | 9 | ```shell 10 | Alpine 3.13.1 11 | OTP/Erlang 23.2.3 12 | Rebar 3.14.3 13 | Git 2.30.0 14 | ``` 15 | 16 | ## Usage 17 | 18 | To boot straight to a erl prompt in the image: 19 | 20 | ```shell 21 | $ docker run --rm -i -t beardedeagle/alpine-erlang-builder erl 22 | Erlang/OTP 23 [erts-11.1.7] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] 23 | 24 | Eshell V11.1.7 (abort with ^G) 25 | 1> 26 | ``` 27 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help version test erl shell build clean rebuild release 2 | .NOTPARALLEL: build rebuild release 3 | .DEFAULT_GOAL := help 4 | 5 | VERSION ?= `cat VERSION` 6 | MIN_VERSION := $(shell echo $(VERSION) | sed 's/\([0-9][0-9]*\)\.\([0-9][0-9]*\)\(\.[0-9][0-9]*\)*/\1.\2/') 7 | IMAGE_NAME ?= beardedeagle/alpine-erlang-builder 8 | 9 | help: ## Show this message 10 | @echo "$(IMAGE_NAME):$(VERSION)" 11 | @echo 12 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}' 13 | 14 | version: ## Show Makefile version 15 | @echo -e 'OTP/Erlang version: $(shell echo $(VERSION))' 16 | @echo -e 'Maintainer: beardedeagle ' 17 | @echo -e 'Last modified: 2020-11-05' 18 | 19 | test: ## Test Docker image 20 | @docker run --rm -it $(IMAGE_NAME):$(VERSION) erl -version 21 | 22 | erl: ## Run erl shell in Docker image 23 | @docker run --rm -it $(IMAGE_NAME):$(VERSION) erl 24 | 25 | shell: ## Boot to shell prompt in Docker image 26 | @docker run --rm -it $(IMAGE_NAME):$(VERSION) /bin/bash 27 | 28 | build: ## Build Docker images 29 | @docker build --force-rm -t $(IMAGE_NAME):$(VERSION) -t $(IMAGE_NAME):$(MIN_VERSION) -t $(IMAGE_NAME):latest . 30 | 31 | clean: ## Clean up generated Docker images 32 | @docker rmi --force $(IMAGE_NAME):$(VERSION) $(IMAGE_NAME):$(MIN_VERSION) $(IMAGE_NAME):latest 33 | 34 | rebuild: clean build ## Rebuild Docker images 35 | 36 | release: build ## Build and release Docker images to Docker Hub 37 | @docker push $(IMAGE_NAME):$(VERSION) 38 | @docker push $(IMAGE_NAME):$(MIN_VERSION) 39 | @docker push $(IMAGE_NAME):latest 40 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.13.1 as base_stage 2 | 3 | LABEL maintainer="beardedeagle " 4 | 5 | # Important! Update this no-op ENV variable when this Dockerfile 6 | # is updated with the current date. It will force refresh of all 7 | # of the base images. 8 | ENV REFRESHED_AT=2021-02-02 \ 9 | OTP_VER=23.2.3 \ 10 | REBAR3_VER=3.14.3 \ 11 | TERM=xterm \ 12 | LANG=C.UTF-8 13 | 14 | RUN set -xe \ 15 | && apk --no-cache update \ 16 | && apk --no-cache upgrade \ 17 | && apk add --no-cache \ 18 | bash \ 19 | git \ 20 | openssl \ 21 | zlib \ 22 | && rm -rf /root/.cache \ 23 | && rm -rf /var/cache/apk/* \ 24 | && rm -rf /tmp/* 25 | 26 | FROM base_stage as deps_stage 27 | 28 | RUN set -xe \ 29 | && apk add --no-cache --virtual .build-deps \ 30 | autoconf \ 31 | curl \ 32 | dpkg \ 33 | dpkg-dev \ 34 | g++ \ 35 | gcc \ 36 | make \ 37 | musl-dev \ 38 | ncurses-dev \ 39 | openssl-dev \ 40 | rsync \ 41 | sed \ 42 | tar \ 43 | unzip \ 44 | zlib-dev 45 | 46 | FROM deps_stage as erlang_stage 47 | 48 | RUN set -xe \ 49 | && OTP_DOWNLOAD_URL="https://github.com/erlang/otp/archive/OTP-${OTP_VER}.tar.gz" \ 50 | && OTP_DOWNLOAD_SHA256="3160912856ba734bd9c17075e72f469b9d4b913f3ab9652ee7e0fb406f0f0f2c" \ 51 | && curl -fSL -o otp-src.tar.gz "${OTP_DOWNLOAD_URL}" \ 52 | && echo "${OTP_DOWNLOAD_SHA256} otp-src.tar.gz" | sha256sum -c - \ 53 | && export ERL_TOP="/usr/src/otp_src_${OTP_VER%%@*}" \ 54 | && mkdir -vp "${ERL_TOP}" \ 55 | && tar -xzf otp-src.tar.gz -C "${ERL_TOP}" --strip-components=1 \ 56 | && rm otp-src.tar.gz \ 57 | && ( cd "${ERL_TOP}" \ 58 | && ./otp_build autoconf \ 59 | && gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" \ 60 | && ./configure --build="${gnuArch}" \ 61 | --without-javac \ 62 | --without-wx \ 63 | --without-debugger \ 64 | --without-observer \ 65 | --without-jinterface \ 66 | --without-cosEvent\ 67 | --without-cosEventDomain \ 68 | --without-cosFileTransfer \ 69 | --without-cosNotification \ 70 | --without-cosProperty \ 71 | --without-cosTime \ 72 | --without-cosTransactions \ 73 | --without-et \ 74 | --without-gs \ 75 | --without-ic \ 76 | --without-megaco \ 77 | --without-orber \ 78 | --without-percept \ 79 | --without-typer \ 80 | --without-odbc \ 81 | --disable-hipe \ 82 | --enable-m64-build \ 83 | --enable-threads \ 84 | --enable-shared-zlib \ 85 | --enable-ssl=dynamic-ssl-lib \ 86 | --enable-kernel-poll \ 87 | && make -j$(getconf _NPROCESSORS_ONLN) \ 88 | && make install ) \ 89 | && rm -rf "${ERL_TOP}" \ 90 | && find /usr/local -regex '/usr/local/lib/erlang/\(lib/\|erts-\).*/\(man\|doc\|obj\|c_src\|emacs\|info\|examples\)' | xargs rm -rf \ 91 | && find /usr/local -name src | xargs -r find | grep -v '\.hrl$' | xargs rm -v || true \ 92 | && find /usr/local -name src | xargs -r find | xargs rmdir -vp || true \ 93 | && scanelf --nobanner -E ET_EXEC -BF '%F' --recursive /usr/local | xargs -r strip --strip-all \ 94 | && scanelf --nobanner -E ET_DYN -BF '%F' --recursive /usr/local | xargs -r strip --strip-unneeded 95 | 96 | FROM erlang_stage as rebar3_stage 97 | 98 | RUN set -xe \ 99 | && REBAR3_DOWNLOAD_URL="https://github.com/erlang/rebar3/archive/${REBAR3_VER}.tar.gz" \ 100 | && REBAR3_DOWNLOAD_SHA256="69024b30f17b52c61e5e0568cbf9a2db325eb646ae230c48858401507394f5c0" \ 101 | && curl -fSL -o rebar3-src.tar.gz "${REBAR3_DOWNLOAD_URL}" \ 102 | && echo "${REBAR3_DOWNLOAD_SHA256} rebar3-src.tar.gz" | sha256sum -c - \ 103 | && mkdir -p /usr/src/rebar3-src \ 104 | && tar -xzf rebar3-src.tar.gz -C /usr/src/rebar3-src --strip-components=1 \ 105 | && rm -f rebar3-src.tar.gz \ 106 | && cd /usr/src/rebar3-src \ 107 | && HOME="${PWD}" ./bootstrap \ 108 | && install -v ./rebar3 /usr/local/bin/ 109 | 110 | FROM deps_stage as stage 111 | 112 | COPY --from=rebar3_stage /usr/local /opt/rebar3 113 | 114 | RUN set -xe \ 115 | && rsync -a /opt/rebar3/ /usr/local \ 116 | && apk del .build-deps \ 117 | && rm -rf /root/.cache \ 118 | && rm -rf /var/cache/apk/* \ 119 | && rm -rf /tmp/* 120 | 121 | FROM base_stage 122 | 123 | COPY --from=stage /usr/local /usr/local 124 | --------------------------------------------------------------------------------