├── .dockerignore ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── Dockerfile.m4 ├── LICENSE ├── Makefile ├── README.md ├── bin ├── app ├── mkimage ├── release_name ├── release_version ├── system_version └── version ├── dev.config ├── erlang.mk ├── rel ├── sys.config └── vm.args ├── relx.config └── src ├── eidfs.erl ├── eidfs_app.erl ├── eidfs_config.erl ├── eidfs_hello_world_resource.erl └── eidfs_sup.erl /.dockerignore: -------------------------------------------------------------------------------- 1 | .erlang.mk 2 | .git* 3 | *~ 4 | LICENSE 5 | Makefile 6 | bin 7 | ebin 8 | erlang.mk 9 | rel* 10 | src 11 | *.d 12 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | jobs: 7 | docker: 8 | name: Build OTP ${{matrix.otp}} 9 | strategy: 10 | matrix: 11 | include: 12 | - otp: 25.1 13 | - otp: 24.3 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: checkout 17 | uses: actions/checkout@v3 18 | - name: set up beam 19 | uses: erlef/setup-beam@v1 20 | with: 21 | otp-version: ${{matrix.otp}} 22 | - name: build 23 | run: make deps app rel 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.plt 3 | erl_crash.dump 4 | deps 5 | .eunit 6 | .DS_Store 7 | .erlang.mk.* 8 | ebin 9 | _rel 10 | relx 11 | logs 12 | .erlang.mk 13 | db 14 | xrefr 15 | *.d 16 | elvis 17 | elvis.config 18 | .fuse_hidden* 19 | recompile.log 20 | Dockerfile 21 | -------------------------------------------------------------------------------- /Dockerfile.m4: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012-2022 Peter Morgan 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | FROM scratch 16 | MAINTAINER Peter Morgan 17 | 18 | ENV BINDIR /erts-ERTS_VSN/bin 19 | ENV TZ=GMT 20 | 21 | ENTRYPOINT ["/erts-ERTS_VSN/bin/erlexec", "-boot_var", "ERTS_LIB_DIR", "/lib", "-boot", "/releases/REL_VSN/start", "-noinput", "-no_epmd", "-proto_dist", "inet_tls", "-config", "/releases/REL_VSN/sys.config", "-args_file", "/releases/REL_VSN/vm.args"] 22 | 23 | ADD _rel/REL_NAME/ / 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #-*- mode: makefile-gmake -*- 2 | # Copyright (c) 2012-2022 Peter Morgan 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | PROJECT = eidfs 17 | PROJECT_DESCRIPTION = Erlang in Docker from scratch 18 | PROJECT_VERSION = 0.0.2 19 | 20 | 21 | RELX_TAR = 0 22 | 23 | REL_DEPS = \ 24 | relx 25 | 26 | SHELL_OPTS = \ 27 | -config dev.config \ 28 | -s $(PROJECT) \ 29 | -s sync 30 | 31 | SHELL_DEPS = \ 32 | sync 33 | 34 | DEPS = \ 35 | cowboy \ 36 | shelly 37 | 38 | LOCAL_DEPS = \ 39 | sasl 40 | 41 | dep_shelly = git https://github.com/shortishly/shelly.git 42 | 43 | dep_cowboy_commit = 2.9.0 44 | dep_shelly_commit = 0.4.0 45 | 46 | include erlang.mk 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/shortishly/erlang-in-docker-from-scratch.svg)](https://travis-ci.org/shortishly/erlang-in-docker-from-scratch) 2 | 3 | When packaging an application as a [Docker](https://www.docker.com) 4 | container it is too easy to just be lazy and put `FROM debian` (other 5 | distributions are available, replace `debian` with your distribution 6 | of choice). For sure it is going to work, but you have just included 7 | dozens of libraries and binaries that your application 8 | [just does not need](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/). An 9 | image that could be tens of megabytes is now at least several 10 | hundred - we are building containers not virtual machines here! 11 | 12 | One of the things I like about [Go](https://golang.org) is that 13 | typical application binaries are small with no runtime 14 | dependencies. Fewer dependencies mean less patching and security 15 | headaches. The less friction in the CI build cycle, the better. Go 16 | achieves this by having statically linked applications meaning that 17 | just one binary is necessary in `ADD`, and they are typically built 18 | from 19 | [scratch](https://docs.docker.com/engine/userguide/eng-image/baseimages/) 20 | (etcd as a good [example](https://github.com/coreos/etcd/blob/master/scripts/build-docker#L12-L16)). 21 | 22 | [Erlang](http://www.erlang.org) was designed to be embedded in 23 | telecoms equipment, so we must be able to package applications in 24 | Docker with a small footprint too? 25 | 26 | This repository contains a regular erlang application that is packaged 27 | in a docker container from scratch. You will need both `erlang` 28 | installed and `docker` service running preferably on a Linux 29 | environment. The release needs to be built on Linux to be able to run 30 | on Linux because we are going include the ERTS. 31 | 32 | On MacOS you might want to run `shortishly/docker-erlang` 33 | which will give you erlang and docker packaged together in a shell 34 | (`brew install docker-machine` if you don't already have 35 | it): 36 | 37 | ```shell 38 | docker run \ 39 | -v /var/run/docker.sock:/var/run/docker.sock \ 40 | -t \ 41 | -i \ 42 | --rm \ 43 | shortishly/docker-erlang \ 44 | /bin/bash 45 | ``` 46 | 47 | Clone and build this 48 | [erlang-in-docker-from-scratch](https://github.com/shortishly/erlang-in-docker-from-scratch) 49 | repository, which contains a minimal erlang application that builds a 50 | release into the `_rel` directory: 51 | 52 | ```shell 53 | git clone https://github.com/shortishly/erlang-in-docker-from-scratch.git eidfs 54 | cd eidfs 55 | make 56 | ``` 57 | 58 | The `eidfs` application includes a simple 59 | [cowboy](https://github.com/ninenines/cowboy) "Hello World!" resource 60 | to show the container working. It also provides a secure shell daemon 61 | using [shelly](https://github.com/shortishly/shelly) into the BEAM 62 | enabling maintenance on the dockerised application. 63 | 64 | At the end of `make` a standard erlang release for the eidfs 65 | application is now present in the `_rel` directory. To make it run 66 | inside a scratch container we need to include any runtime dependencies 67 | too. This is where `mkimage` comes in: 68 | 69 | ```shell 70 | ./bin/mkimage 71 | ``` 72 | 73 | The `./bin/mkimage` script copies in any dynamic libraries that ERTS 74 | needs to run the erlang release: 75 | 76 | ```shell 77 | '/lib/x86_64-linux-gnu/libc.so.6' -> '_rel/eidfs/lib/x86_64-linux-gnu/libc.so.6' 78 | '/lib/x86_64-linux-gnu/libdl.so.2' -> '_rel/eidfs/lib/x86_64-linux-gnu/libdl.so.2' 79 | '/lib/x86_64-linux-gnu/libm.so.6' -> '_rel/eidfs/lib/x86_64-linux-gnu/libm.so.6' 80 | '/lib/x86_64-linux-gnu/libpthread.so.0' -> '_rel/eidfs/lib/x86_64-linux-gnu/libpthread.so.0' 81 | '/lib/x86_64-linux-gnu/librt.so.1' -> '_rel/eidfs/lib/x86_64-linux-gnu/librt.so.1' 82 | '/lib/x86_64-linux-gnu/libtinfo.so.5' -> '_rel/eidfs/lib/x86_64-linux-gnu/libtinfo.so.5' 83 | '/lib/x86_64-linux-gnu/libutil.so.1' -> '_rel/eidfs/lib/x86_64-linux-gnu/libutil.so.1' 84 | '/lib/x86_64-linux-gnu/libz.so.1' -> '_rel/eidfs/lib/x86_64-linux-gnu/libz.so.1' 85 | ``` 86 | 87 | It also copies `/bin/sh` so that we can run the release too. We can 88 | build a docker image for the release using the following command: 89 | 90 | ```shell 91 | docker build \ 92 | --build-arg REL_NAME=$(bin/release_name) \ 93 | --build-arg ERTS_VSN=$(bin/system_version) \ 94 | --pull=true \ 95 | --no-cache=true \ 96 | --force-rm=true \ 97 | -t $(bin/release_name):$(bin/version) . 98 | ``` 99 | 100 | The `$(bin/release_name)` `$(bin/system_version)` and `$(bin/version)` 101 | are short escripts that respond with the release name, system ERTS 102 | version and the application version respectively. 103 | 104 | Quite a lot of effort, what is the reward? Try `docker images` and 105 | look at the size of the resultant container: 106 | 107 | ```shell 108 | REPOSITORY TAG IMAGE ID CREATED SIZE 109 | eidfs 0.0.1 6748931f94e4 4 seconds ago 16.74 MB 110 | ``` 111 | 112 | We have a docker packaged erlang release in ~17MB. Lets run it! 113 | 114 | ```shell 115 | docker run \ 116 | --name $(bin/release_name) \ 117 | -e SHELLY_AUTHORIZED_KEYS="$(cat ~/.ssh/authorized_keys)" \ 118 | -d \ 119 | $(bin/release_name):$(bin/version) 120 | ``` 121 | 122 | The `SHELLY_AUTHORIZED_KEYS` will copy your *public* keys into the 123 | Docker container so that you can ssh directly into the BEAM to perform 124 | any operational maintenance. If you'd prefer not to, just remove that 125 | line from `docker run`. 126 | 127 | Check the logs using `docker logs $(bin/release_name)` and 128 | you will see lots of application startup messages from SASL. 129 | 130 | You can find the IP address of the containes that is running by using 131 | `docker inspect`: 132 | 133 | ```shell 134 | docker inspect --format={{.NetworkSettings.IPAddress}} $(bin/release_name) 135 | ``` 136 | 137 | We can `curl` the static "Hello World!" cowboy response by running: 138 | 139 | ```shell 140 | curl http://$(docker inspect --format={{.NetworkSettings.IPAddress}} $(bin/release_name))/hello 141 | ``` 142 | 143 | If you included the `SHELLY_AUTHORIZED_KEYS` in your `docker run` 144 | above you can also ssh directly into the BEAM running inside the 145 | docker container: 146 | 147 | ```shell 148 | ssh $(docker inspect --format={{.NetworkSettings.IPAddress}} $(bin/release_name)) 149 | ``` 150 | 151 | The first time you connect you will need accept the ssh host key for the application: 152 | 153 | ```shell 154 | ssh $(docker inspect --format={{.NetworkSettings.IPAddress}} $(bin/release_name)) 155 | The authenticity of host '172.17.0.2 (172.17.0.2)' can't be established. 156 | RSA key fingerprint is SHA256:1EIgSYLN9pP9mwvnBf8ibQ/1bpEangTKprKKWJ9jQ7s. 157 | RSA key fingerprint is MD5:69:b8:52:22:30:c7:56:b2:f9:66:e6:39:68:7f:9e:b3. 158 | Are you sure you want to continue connecting (yes/no)? yes 159 | Warning: Permanently added '172.17.0.2' (RSA) to the list of known hosts. 160 | Eshell V7.2.1 (abort with ^G) 161 | (minerl@127.0.0.1)1> 162 | ``` 163 | 164 | You can type `exit().` to quit the shell, keeping the container running. 165 | 166 | 167 | You might notice that the 168 | [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) 169 | used in the 170 | [Dockerfile](https://github.com/shortishly/erlang-in-docker-from-scratch/blob/master/Dockerfile) 171 | directly invokes `erlexec`. I have done this to reduce dependencies 172 | further so that the release, ERTS dynamic libraries, and `/bin/bash` 173 | only are present in the container. 174 | 175 | ```dockerfile 176 | FROM scratch 177 | MAINTAINER Peter Morgan 178 | 179 | ARG REL_NAME 180 | ARG REL_VSN=1 181 | ARG ERTS_VSN 182 | 183 | ENV BINDIR /erts-${ERTS_VSN}/bin 184 | ENV BOOT /releases/${REL_VSN}/${REL_NAME} 185 | ENV CONFIG /releases/${REL_VSN}/sys.config 186 | ENV ARGS_FILE /releases/${REL_VSN}/vm.args 187 | 188 | ENV TZ=GMT 189 | 190 | ENTRYPOINT exec ${BINDIR}/erlexec \ 191 | -boot_var /lib \ 192 | -boot ${BOOT} \ 193 | -noinput \ 194 | -config ${CONFIG} \ 195 | -args_file ${ARGS_FILE} 196 | 197 | ADD _rel/${REL_NAME}/ / 198 | ``` 199 | -------------------------------------------------------------------------------- /bin/app: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %% Copyright (c) 2013-2016 Peter Morgan 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | 18 | main([]) -> 19 | {application, Name, _} = application(), 20 | io:format("~w~n", [Name]). 21 | 22 | root_dir() -> 23 | filename:dirname(escript:script_name()). 24 | 25 | app() -> 26 | [Filename] = filelib:wildcard(filename:join([root_dir(),"../ebin/*.app"])), 27 | Filename. 28 | 29 | application() -> 30 | {ok, [{application, _, _} = Application]} = file:consult(app()), 31 | Application. 32 | -------------------------------------------------------------------------------- /bin/mkimage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright (c) 2012-2022 Peter Morgan 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | SCRIPT_DIR=$(dirname $0) 18 | REL_NAME=$(${SCRIPT_DIR}/app) 19 | RELEASE=_rel/${REL_NAME} 20 | 21 | # strip symbol information out of any ERTS binaries 22 | for fat in $(file _rel/*/erts-*/bin/*|grep "not stripped"|awk '{print $1}'|cut -d: -f1); do 23 | strip $fat &>/dev/null; 24 | done 25 | 26 | # copy any dynamically linked libaries used by ERTS into release 27 | for lib in $(ldd _rel/*/erts-*/bin/* _rel/*/lib/*/priv/lib/* $(which sh) 2>/dev/null|grep "=>"|awk '{print $3}'|sort|uniq); do 28 | mkdir -p $(dirname ${RELEASE}$lib) 29 | cp -Lv $lib ${RELEASE}$lib 30 | done 31 | 32 | # ensure that the link loader is present 33 | case `arch` in 34 | x86_64) 35 | mkdir -p ${RELEASE}/lib64 36 | cp -v /lib64/ld-linux*.so.* ${RELEASE}/lib64;; 37 | 38 | aarch64) 39 | cp -v /lib/ld-linux*.so.* ${RELEASE}/lib;; 40 | esac 41 | 42 | # and a shell 43 | cp /bin/sh ${RELEASE}/bin 44 | -------------------------------------------------------------------------------- /bin/release_name: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %% Copyright (c) 2016 Peter Morgan 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | 18 | main([]) -> 19 | io:format("~s~n", 20 | lists:foldl( 21 | fun 22 | ({release, {Name, _Version}, _}, A) -> 23 | [Name | A]; 24 | 25 | (_, A) -> 26 | A 27 | end, 28 | [], 29 | relx())). 30 | 31 | root_dir() -> 32 | filename:dirname(escript:script_name()). 33 | 34 | config() -> 35 | filename:join([root_dir(),"../relx.config"]). 36 | 37 | relx() -> 38 | {ok, Configuration} = file:consult(config()), 39 | Configuration. 40 | -------------------------------------------------------------------------------- /bin/release_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %% Copyright (c) 2016 Peter Morgan 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | 18 | main([]) -> 19 | io:format("~s~n", 20 | lists:foldl( 21 | fun 22 | ({release, {_Name, Version}, _}, A) -> 23 | [Version | A]; 24 | 25 | (_, A) -> 26 | A 27 | end, 28 | [], 29 | relx())). 30 | 31 | root_dir() -> 32 | filename:dirname(escript:script_name()). 33 | 34 | config() -> 35 | filename:join([root_dir(),"../relx.config"]). 36 | 37 | relx() -> 38 | {ok, Configuration} = file:consult(config()), 39 | Configuration. 40 | -------------------------------------------------------------------------------- /bin/system_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %% Copyright (c) 2013-2016 Peter Morgan 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | 18 | main([]) -> 19 | io:format("~s~n", [erlang:system_info(version)]). 20 | -------------------------------------------------------------------------------- /bin/version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %% Copyright (c) 2013-2016 Peter Morgan 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | 18 | main([]) -> 19 | io:format("~s~n", [version()]). 20 | 21 | root_dir() -> 22 | filename:dirname(escript:script_name()). 23 | 24 | app() -> 25 | [Filename] = filelib:wildcard(filename:join([root_dir(),"../ebin/*.app"])), 26 | Filename. 27 | 28 | version() -> 29 | {ok, [{application, _, Properties}]} = file:consult(app()), 30 | proplists:get_value(vsn, Properties). 31 | -------------------------------------------------------------------------------- /dev.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang -*- 2 | %% Copyright (c) 2012-2022 Peter Morgan 3 | %% 4 | %% Licensed under the Apache License, Version 2.0 (the "License"); 5 | %% you may not use this file except in compliance with the License. 6 | %% You may obtain a copy of the License at 7 | %% 8 | %% http://www.apache.org/licenses/LICENSE-2.0 9 | %% 10 | %% Unless required by applicable law or agreed to in writing, software 11 | %% distributed under the License is distributed on an "AS IS" BASIS, 12 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | %% See the License for the specific language governing permissions and 14 | %% limitations under the License. 15 | 16 | [{shelly, [{enabled, false}]}, 17 | {eidfs, [{http_port, 8080}]}]. 18 | -------------------------------------------------------------------------------- /rel/sys.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang -*- 2 | %% Copyright (c) 2012-2016 Peter Morgan 3 | %% 4 | %% Licensed under the Apache License, Version 2.0 (the "License"); 5 | %% you may not use this file except in compliance with the License. 6 | %% You may obtain a copy of the License at 7 | %% 8 | %% http://www.apache.org/licenses/LICENSE-2.0 9 | %% 10 | %% Unless required by applicable law or agreed to in writing, software 11 | %% distributed under the License is distributed on an "AS IS" BASIS, 12 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | %% See the License for the specific language governing permissions and 14 | %% limitations under the License. 15 | 16 | []. 17 | -------------------------------------------------------------------------------- /rel/vm.args: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shortishly/erlang-in-docker-from-scratch/dafb7c5b13854a850ba6d8090ea15c63c998f807/rel/vm.args -------------------------------------------------------------------------------- /relx.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang -*- 2 | %% Copyright (c) 2012-2022 Peter Morgan 3 | %% 4 | %% Licensed under the Apache License, Version 2.0 (the "License"); 5 | %% you may not use this file except in compliance with the License. 6 | %% You may obtain a copy of the License at 7 | %% 8 | %% http://www.apache.org/licenses/LICENSE-2.0 9 | %% 10 | %% Unless required by applicable law or agreed to in writing, software 11 | %% distributed under the License is distributed on an "AS IS" BASIS, 12 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | %% See the License for the specific language governing permissions and 14 | %% limitations under the License. 15 | 16 | {release, {eidfs, "1"}, [eidfs, sasl, runtime_tools]}. 17 | {extended_start_script, true}. 18 | {sys_config, "rel/sys.config"}. 19 | {vm_args, "rel/vm.args"}. 20 | {include_src, false}. 21 | {dev_mode, false}. 22 | {include_erts, true}. 23 | -------------------------------------------------------------------------------- /src/eidfs.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2022 Peter Morgan 2 | %% 3 | %% Licensed under the Apache License, Version 2.0 (the "License"); 4 | %% you may not use this file except in compliance with the License. 5 | %% You may obtain a copy of the License at 6 | %% 7 | %% http://www.apache.org/licenses/LICENSE-2.0 8 | %% 9 | %% Unless required by applicable law or agreed to in writing, software 10 | %% distributed under the License is distributed on an "AS IS" BASIS, 11 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | %% See the License for the specific language governing permissions and 13 | %% limitations under the License. 14 | 15 | 16 | -module(eidfs). 17 | 18 | 19 | -export([start/0]). 20 | 21 | 22 | start() -> 23 | application:ensure_all_started(?MODULE). 24 | -------------------------------------------------------------------------------- /src/eidfs_app.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2016-2022 Peter Morgan 2 | %% 3 | %% Licensed under the Apache License, Version 2.0 (the "License"); 4 | %% you may not use this file except in compliance with the License. 5 | %% You may obtain a copy of the License at 6 | %% 7 | %% http://www.apache.org/licenses/LICENSE-2.0 8 | %% 9 | %% Unless required by applicable law or agreed to in writing, software 10 | %% distributed under the License is distributed on an "AS IS" BASIS, 11 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | %% See the License for the specific language governing permissions and 13 | %% limitations under the License. 14 | 15 | -module(eidfs_app). 16 | 17 | 18 | -behaviour(application). 19 | -export([start/2]). 20 | -export([stop/1]). 21 | 22 | 23 | start(_Type, _Args) -> 24 | try 25 | {ok, Sup} = eidfs_sup:start_link(), 26 | {ok, Sup, #{listeners => [start_http(http)]}} 27 | catch 28 | _:Reason -> 29 | {error, Reason} 30 | end. 31 | 32 | 33 | stop(#{listeners := Listeners}) -> 34 | lists:foreach(fun cowboy:stop_listener/1, Listeners); 35 | 36 | stop(_State) -> 37 | ok. 38 | 39 | 40 | start_http(Prefix) -> 41 | {ok, _} = cowboy:start_clear(Prefix, 42 | [{port, eidfs_config:port(Prefix)}], 43 | #{env => dispatch(Prefix)}), 44 | Prefix. 45 | 46 | 47 | dispatch(Prefix) -> 48 | #{dispatch => cowboy_router:compile(resources(Prefix))}. 49 | 50 | 51 | resources(http) -> 52 | [{'_', 53 | [{<<"/hello">>, eidfs_hello_world_resource, []}]}]. 54 | -------------------------------------------------------------------------------- /src/eidfs_config.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2016-2022 Peter Morgan 2 | %% 3 | %% Licensed under the Apache License, Version 2.0 (the "License"); 4 | %% you may not use this file except in compliance with the License. 5 | %% You may obtain a copy of the License at 6 | %% 7 | %% http://www.apache.org/licenses/LICENSE-2.0 8 | %% 9 | %% Unless required by applicable law or agreed to in writing, software 10 | %% distributed under the License is distributed on an "AS IS" BASIS, 11 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | %% See the License for the specific language governing permissions and 13 | %% limitations under the License. 14 | 15 | -module(eidfs_config). 16 | 17 | 18 | -export([acceptors/1]). 19 | -export([port/1]). 20 | 21 | 22 | port(http) -> 23 | envy:to_integer(eidfs, http_port, default(80)). 24 | 25 | 26 | acceptors(http) -> 27 | envy:to_integer(eidfs, http_acceptors, default(100)). 28 | 29 | 30 | default(Default) -> 31 | [os_env, app_env, {default, Default}]. 32 | -------------------------------------------------------------------------------- /src/eidfs_hello_world_resource.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2016-2022 Peter Morgan 2 | %% 3 | %% Licensed under the Apache License, Version 2.0 (the "License"); 4 | %% you may not use this file except in compliance with the License. 5 | %% You may obtain a copy of the License at 6 | %% 7 | %% http://www.apache.org/licenses/LICENSE-2.0 8 | %% 9 | %% Unless required by applicable law or agreed to in writing, software 10 | %% distributed under the License is distributed on an "AS IS" BASIS, 11 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | %% See the License for the specific language governing permissions and 13 | %% limitations under the License. 14 | 15 | -module(eidfs_hello_world_resource). 16 | 17 | 18 | -export([init/2]). 19 | 20 | 21 | init(Req, Opts) -> 22 | Headers = #{<<"content-type">> => <<"text/plain">>}, 23 | {ok, cowboy_req:reply(200, Headers, <<"Hello world!\n">>, Req), Opts}. 24 | -------------------------------------------------------------------------------- /src/eidfs_sup.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2016-2022 Peter Morgan 2 | %% 3 | %% Licensed under the Apache License, Version 2.0 (the "License"); 4 | %% you may not use this file except in compliance with the License. 5 | %% You may obtain a copy of the License at 6 | %% 7 | %% http://www.apache.org/licenses/LICENSE-2.0 8 | %% 9 | %% Unless required by applicable law or agreed to in writing, software 10 | %% distributed under the License is distributed on an "AS IS" BASIS, 11 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | %% See the License for the specific language governing permissions and 13 | %% limitations under the License. 14 | 15 | -module(eidfs_sup). 16 | 17 | 18 | -behaviour(supervisor). 19 | -export([init/1]). 20 | -export([start_link/0]). 21 | 22 | 23 | start_link() -> 24 | supervisor:start_link({local, ?MODULE}, ?MODULE, []). 25 | 26 | 27 | init([]) -> 28 | Procs = [], 29 | {ok, {{one_for_one, 1, 5}, Procs}}. 30 | --------------------------------------------------------------------------------