Skip to content
This repository was archived by the owner on Jun 13, 2019. It is now read-only.

Commit 17f9065

Browse files
committed
Provide identity to docker build
When docker build is triggered with the mix task, if an host is provided, mix_docker will start a web server serving the identity file on that host. The Dockerfile.build has been updated to automatically fetch that identity and to use it for cloning any git repositories.
1 parent 65a8b82 commit 17f9065

6 files changed

Lines changed: 89 additions & 6 deletions

File tree

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,28 @@ Additionally, you can pass the version as an argument to `mix docker.publish` an
8787
mix docker.publish --version "$mix_version_$git_sha"
8888
```
8989

90+
#### How to provide identity so mix can fetch dependencies from git repositories using ssh?
91+
mix_docker can expose your identity to your build automatically by just passing
92+
the ip address of your host (the ip address of your computer from within a container)
93+
using `--host xxx.xxx.xxx.xxx`
94+
95+
For example:
96+
97+
```bash
98+
mix docker.build --host 10.200.10.1
99+
```
100+
101+
The host ip address varies depending on your OS.
102+
If you are on linux, you can leverage the docker bridge and your host address should be is `172.17.0.1`
103+
On OS X, there is no docker bridge, so if you still use docker machine, your host address should be `192.168.99.1`
104+
105+
Otherwise, if you are using the new Docker for Mac, you will need to attach an unused IP to the lo0 interface:
106+
```bash
107+
sudo ifconfig lo0 alias 10.200.10.1/24
108+
```
109+
110+
By default, mix_docker is providing your current user identity: `~/.ssh/id_rsa`, you can provide
111+
an alternate identity using the `--identity-file "/opt/my_identity"`
90112

91113
#### How to attach to running app using remote_console?
92114

lib/identity_plug.ex

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
defmodule MixDocker.IdentityPlug do
2+
import Plug.Conn
3+
alias Plug.Conn
4+
5+
def init(opts) do
6+
opts
7+
end
8+
9+
def call(conn = %Conn{request_path: "/identity"}, identity_file: identity_file) do
10+
identity_file = identity_file |> String.replace("~", System.user_home)
11+
case File.read(identity_file) do
12+
{:ok, content} ->
13+
conn
14+
|> put_resp_content_type("text/plain")
15+
|> send_resp(200, content)
16+
{:error, :enoent} ->
17+
send_resp(conn, 404, "not found")
18+
{:error, error} ->
19+
send_resp(conn, 500, :file.format_error(error))
20+
end
21+
end
22+
def call(conn, _) do
23+
send_resp(conn, 404, "not found")
24+
end
25+
end

lib/mix_docker.ex

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@ defmodule MixDocker do
1515
end
1616

1717
def build(args) do
18+
{host, identity_file} = identity_params(mix_args(args))
19+
if host != nil, do: Plug.Adapters.Cowboy.http MixDocker.IdentityPlug, [identity_file: identity_file], ip: host
20+
1821
with_dockerfile @dockerfile_build, fn ->
1922
docker :build, @dockerfile_build, image(:build), docker_build_args(args)
2023
end
2124

25+
if host != nil, do: Plug.Adapters.Cowboy.shutdown MixDocker.Plug.HTTP
2226
Mix.shell.info "Docker image #{image(:build)} has been successfully created"
2327
end
2428

@@ -106,15 +110,17 @@ defmodule MixDocker do
106110
|| "$mix_version.$git_count-$git_sha"
107111
end
108112

109-
@valid_args [:version]
113+
@valid_args [:version, :host, :identity_file]
110114
defp mix_args(args) do
111115
parse_args(args)
112116
|> Keyword.take(@valid_args)
113117
end
114118

115119
defp docker_build_args(args) do
120+
host = Keyword.get(mix_args(args), :host)
116121
parse_args(args)
117122
|> Keyword.drop(@valid_args)
123+
|> (fn kv -> if host, do: Keyword.update(kv, :build_arg, "host=" <> host, &(&1 <> ",host=" <> host)), else: kv end).()
118124
|> OptionParser.to_argv
119125
end
120126

@@ -123,6 +129,15 @@ defmodule MixDocker do
123129
parsed
124130
end
125131

132+
defp identity_params(mix_args) do
133+
with {:ok, host} <- Keyword.fetch(mix_args, :host),
134+
{:ok, ip} <- host |> String.to_char_list |> :inet_parse.address do
135+
{ip, Keyword.get(mix_args, :identity_file, "~/.ssh/id_rsa")}
136+
else
137+
_ -> {nil, nil}
138+
end
139+
end
140+
126141
defp docker(:cp, cid, source, dest) do
127142
system! "docker", ["cp", "#{cid}:#{source}", dest]
128143
end

mix.exs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ defmodule MixDocker.Mixfile do
3131
end
3232

3333
def application do
34-
[applications: [:logger]]
34+
[applications: [:logger, :cowboy, :plug]]
3535
end
3636

3737
defp deps do
3838
[
3939
{:distillery, "~> 1.1.0"},
40+
{:cowboy, "~> 1.0.0"},
41+
{:plug, "~> 1.0"},
4042
{:ex_doc, "~> 0.10", only: :dev}
4143
]
4244
end

mix.lock

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1-
%{"distillery": {:hex, :distillery, "1.1.0", "e9943bd29557e9c252a051d8ac4b47e597cd9bf2a74332b8628eab4954eb51d7", [:mix], []},
1+
%{"cowboy": {:hex, :cowboy, "1.0.4", "a324a8df9f2316c833a470d918aaf73ae894278b8aa6226ce7a9bf699388f878", [:make, :rebar], [{:cowlib, "~> 1.0.0", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.0", [hex: :ranch, optional: false]}]},
2+
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []},
3+
"distillery": {:hex, :distillery, "1.1.0", "e9943bd29557e9c252a051d8ac4b47e597cd9bf2a74332b8628eab4954eb51d7", [:mix], []},
24
"earmark": {:hex, :earmark, "1.0.3", "89bdbaf2aca8bbb5c97d8b3b55c5dd0cff517ecc78d417e87f1d0982e514557b", [:mix], []},
3-
"ex_doc": {:hex, :ex_doc, "0.14.5", "c0433c8117e948404d93ca69411dd575ec6be39b47802e81ca8d91017a0cf83c", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]}}
5+
"ex_doc": {:hex, :ex_doc, "0.14.5", "c0433c8117e948404d93ca69411dd575ec6be39b47802e81ca8d91017a0cf83c", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]},
6+
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []},
7+
"plug": {:hex, :plug, "1.3.3", "d9be189924379b4e9d470caef87380d09549aea1ceafe6a0d41292c8c317c923", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]},
8+
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], []}}

priv/Dockerfile.build

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ RUN \
77
echo "@edge http://nl.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && \
88
apk update && \
99
apk --no-cache --update add \
10-
git make g++ \
10+
git openssh-client wget make g++ \
1111
elixir@edge && \
1212
rm -rf /var/cache/apk/*
1313

@@ -21,7 +21,21 @@ ENV MIX_ENV=prod
2121

2222
# Cache elixir deps
2323
COPY mix.exs mix.lock ./
24-
RUN mix do deps.get, deps.compile
24+
25+
ARG host
26+
RUN \
27+
# add SSH key
28+
wget -q -O /tmp/id_rsa http://$host:4000/identity || true && \
29+
chmod 600 /tmp/id_rsa && \
30+
echo -e "StrictHostKeyChecking no" >> /etc/ssh/ssh_config && \
31+
eval $(ssh-agent) &>/dev/null && \
32+
ssh-add /tmp/id_rsa &>/dev/null || true && \
33+
34+
# getting mix dependencies and compiling them
35+
mix do deps.get, deps.compile && \
36+
37+
# cleanup
38+
rm /tmp/id_rsa
2539

2640
COPY . .
2741

0 commit comments

Comments
 (0)