Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ssh forwarding to docker #235

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,22 @@ ARG RUBY_VERSION
FROM ruby:$RUBY_VERSION-slim as base
```

### Forward your existing SSH agent connection to docker

Clone your private repositories during build.

```yaml
builder:
ssh: $HOME/.ssh/name_of_your_ssh_key
```

Then, include the following in your Dockerfile:

```dockerfile
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN --mount=type=ssh bundle install
```

### Using accessories for database, cache, search services

You can manage your accessory services via MRSK as well. Accessories are long-lived services that your app depends on. They are not updated when you deploy.
Expand Down
14 changes: 13 additions & 1 deletion lib/mrsk/commands/builder/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def pull
end

def build_options
[ *build_tags, *build_labels, *build_args, *build_secrets, *build_dockerfile ]
[ *build_tags, *build_labels, *build_args, *build_secrets, *build_ssh, *build_dockerfile ]
end

def build_context
Expand All @@ -34,6 +34,10 @@ def build_secrets
argumentize "--secret", secrets.collect { |secret| [ "id", secret ] }
end

def build_ssh
argumentize "--ssh", ssh_args
end

def build_dockerfile
argumentize "--file", dockerfile
end
Expand All @@ -42,6 +46,14 @@ def args
(config.builder && config.builder["args"]) || {}
end

def ssh_args
if config.builder && config.builder["ssh"]
"default=#{config.builder["ssh"]}"
else
"default"
end
end

def secrets
(config.builder && config.builder["secrets"]) || []
end
Expand Down
2 changes: 1 addition & 1 deletion test/cli/build_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class CliBuildTest < CliTestCase

test "push" do
run_command("push").tap do |output|
assert_match /docker buildx build --push --platform linux\/amd64,linux\/arm64 --builder mrsk-app-multiarch -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile \. as .*@localhost/, output
assert_match /docker buildx build --push --platform linux\/amd64,linux\/arm64 --builder mrsk-app-multiarch -t dhh\/app:999 -t dhh\/app:latest --label service="app" --ssh default --file Dockerfile \. as .*@localhost/, output
end
end

Expand Down
22 changes: 11 additions & 11 deletions test/commands/builder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,80 +9,80 @@ class CommandsBuilderTest < ActiveSupport::TestCase
builder = new_builder_command
assert_equal "multiarch", builder.name
assert_equal \
"docker buildx build --push --platform linux/amd64,linux/arm64 --builder mrsk-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile .",
"docker buildx build --push --platform linux/amd64,linux/arm64 --builder mrsk-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --ssh default --file Dockerfile .",
builder.push.join(" ")
end

test "target native when multiarch is off" do
builder = new_builder_command(builder: { "multiarch" => false })
assert_equal "native", builder.name
assert_equal \
"docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile . && docker push dhh/app:123 && docker push dhh/app:latest",
"docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --ssh default --file Dockerfile . && docker push dhh/app:123 && docker push dhh/app:latest",
builder.push.join(" ")
end

test "target multiarch remote when local and remote is set" do
builder = new_builder_command(builder: { "local" => { }, "remote" => { } })
assert_equal "multiarch/remote", builder.name
assert_equal \
"docker buildx build --push --platform linux/amd64,linux/arm64 --builder mrsk-app-multiarch-remote -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile .",
"docker buildx build --push --platform linux/amd64,linux/arm64 --builder mrsk-app-multiarch-remote -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --ssh default --file Dockerfile .",
builder.push.join(" ")
end

test "target native remote when only remote is set" do
builder = new_builder_command(builder: { "remote" => { "arch" => "amd64" } })
assert_equal "native/remote", builder.name
assert_equal \
"docker buildx build --push --platform linux/amd64 --builder mrsk-app-native-remote -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile .",
"docker buildx build --push --platform linux/amd64 --builder mrsk-app-native-remote -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --ssh default --file Dockerfile .",
builder.push.join(" ")
end

test "build args" do
builder = new_builder_command(builder: { "args" => { "a" => 1, "b" => 2 } })
assert_equal \
"-t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --file Dockerfile",
"-t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --ssh default --file Dockerfile",
builder.target.build_options.join(" ")
end

test "build secrets" do
builder = new_builder_command(builder: { "secrets" => ["token_a", "token_b"] })
assert_equal \
"-t dhh/app:123 -t dhh/app:latest --label service=\"app\" --secret id=\"token_a\" --secret id=\"token_b\" --file Dockerfile",
"-t dhh/app:123 -t dhh/app:latest --label service=\"app\" --secret id=\"token_a\" --secret id=\"token_b\" --ssh default --file Dockerfile",
builder.target.build_options.join(" ")
end

test "build dockerfile" do
builder = new_builder_command(builder: { "dockerfile" => "Dockerfile.xyz" })
assert_equal \
"-t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile.xyz",
"-t dhh/app:123 -t dhh/app:latest --label service=\"app\" --ssh default --file Dockerfile.xyz",
builder.target.build_options.join(" ")
end

test "build context" do
builder = new_builder_command(builder: { "context" => ".." })
assert_equal \
"docker buildx build --push --platform linux/amd64,linux/arm64 --builder mrsk-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile ..",
"docker buildx build --push --platform linux/amd64,linux/arm64 --builder mrsk-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --ssh default --file Dockerfile ..",
builder.push.join(" ")
end

test "native push with build args" do
builder = new_builder_command(builder: { "multiarch" => false, "args" => { "a" => 1, "b" => 2 } })
assert_equal \
"docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --file Dockerfile . && docker push dhh/app:123 && docker push dhh/app:latest",
"docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --ssh default --file Dockerfile . && docker push dhh/app:123 && docker push dhh/app:latest",
builder.push.join(" ")
end

test "multiarch push with build args" do
builder = new_builder_command(builder: { "args" => { "a" => 1, "b" => 2 } })
assert_equal \
"docker buildx build --push --platform linux/amd64,linux/arm64 --builder mrsk-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --file Dockerfile .",
"docker buildx build --push --platform linux/amd64,linux/arm64 --builder mrsk-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --ssh default --file Dockerfile .",
builder.push.join(" ")
end

test "native push with with build secrets" do
builder = new_builder_command(builder: { "multiarch" => false, "secrets" => [ "a", "b" ] })
assert_equal \
"docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --secret id=\"a\" --secret id=\"b\" --file Dockerfile . && docker push dhh/app:123 && docker push dhh/app:latest",
"docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --secret id=\"a\" --secret id=\"b\" --ssh default --file Dockerfile . && docker push dhh/app:123 && docker push dhh/app:latest",
builder.push.join(" ")
end

Expand Down
3 changes: 1 addition & 2 deletions test/integration/docker/vm/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ FROM ubuntu:22.10
WORKDIR /work

RUN apt-get update && apt-get -y install openssh-client openssh-server docker.io

RUN mkdir /root/.ssh && ln -s /shared/ssh/id_rsa.pub /root/.ssh/authorized_keys
RUN mkdir /root/.ssh && ln -s /shared/ssh/id_rsa.pub /root/.ssh/authorized_keys && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN mkdir -p /etc/docker/certs.d/registry:4443 && ln -s /shared/certs/domain.crt /etc/docker/certs.d/registry:4443/ca.crt

COPY boot.sh .
Expand Down