Merge pull request #17 from anoldguy/switch-to-docker-secrets
Enable docker secrets as a more secure alternative to build args
This commit is contained in:
36
README.md
36
README.md
@@ -146,26 +146,44 @@ builder:
|
|||||||
multiarch: false
|
multiarch: false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Configuring build secrets for new images
|
||||||
|
|
||||||
|
Some images need a secret passed in during build time, like a GITHUB_TOKEN to give access to private gem repositories. This can be done by having the secret in ENV, then referencing it like so in the configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
builder:
|
||||||
|
secrets:
|
||||||
|
- GITHUB_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
This build secret can then be used in the Dockerfile:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Install application gems
|
||||||
|
COPY Gemfile Gemfile.lock ./
|
||||||
|
|
||||||
|
# Private repositories need an access token during the build
|
||||||
|
RUN --mount=type=secret,id=GITHUB_TOKEN \
|
||||||
|
BUNDLE_GITHUB__COM=x-access-token:$(cat /run/secrets/GITHUB_TOKEN) \
|
||||||
|
bundle install
|
||||||
|
```
|
||||||
|
|
||||||
### Configuring build args for new images
|
### Configuring build args for new images
|
||||||
|
|
||||||
Some images might need an argument passed in during build time, like a GITHUB_TOKEN to give access to private gem repositories. This can be done like so:
|
Build arguments that aren't secret can be configured like so:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
builder:
|
builder:
|
||||||
args:
|
args:
|
||||||
GITHUB_TOKEN: <%= ENV["GITHUB_TOKEN"] %>
|
RUBY_VERSION: 3.2.0
|
||||||
```
|
```
|
||||||
|
|
||||||
This build arg can then be used in the Dockerfile:
|
This build argument can then be used in the Dockerfile:
|
||||||
|
|
||||||
```
|
```
|
||||||
# Private repositories need an access token during the build
|
# Private repositories need an access token during the build
|
||||||
ARG GITHUB_TOKEN
|
ARG RUBY_VERSION
|
||||||
ENV BUNDLE_GITHUB__COM=x-access-token:$GITHUB_TOKEN
|
FROM ruby:$RUBY_VERSION-slim as base
|
||||||
|
|
||||||
# Install application gems
|
|
||||||
COPY Gemfile Gemfile.lock ./
|
|
||||||
RUN bundle install
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
require "mrsk/commands/base"
|
require "mrsk/commands/base"
|
||||||
|
|
||||||
class Mrsk::Commands::Builder::Base < Mrsk::Commands::Base
|
class Mrsk::Commands::Builder::Base < Mrsk::Commands::Base
|
||||||
delegate :argumentize, to: Mrsk::Configuration
|
delegate :argumentize, to: Mrsk::Utils
|
||||||
|
|
||||||
def pull
|
def pull
|
||||||
docker :pull, config.absolute_image
|
docker :pull, config.absolute_image
|
||||||
@@ -11,8 +11,16 @@ class Mrsk::Commands::Builder::Base < Mrsk::Commands::Base
|
|||||||
argumentize "--build-arg", args, redacted: true
|
argumentize "--build-arg", args, redacted: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def build_secrets
|
||||||
|
argumentize "--secret", secrets.collect { |secret| [ "id", secret ] }
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def args
|
def args
|
||||||
config.builder["args"] || {}
|
config.builder["args"] || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def secrets
|
||||||
|
config.builder["secrets"] || []
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ require "mrsk/utils"
|
|||||||
|
|
||||||
class Mrsk::Configuration
|
class Mrsk::Configuration
|
||||||
delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :config, allow_nil: true
|
delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :config, allow_nil: true
|
||||||
|
delegate :argumentize, to: Mrsk::Utils
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def create_from(base_config_file, destination: nil)
|
def create_from(base_config_file, destination: nil)
|
||||||
@@ -18,10 +19,6 @@ class Mrsk::Configuration
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def argumentize(argument, attributes, redacted: false)
|
|
||||||
attributes.flat_map { |k, v| [ argument, redacted ? Mrsk::Utils.redact("#{k}=#{v}") : "#{k}=#{v}" ] }
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def load_config_file(file)
|
def load_config_file(file)
|
||||||
if file.exist?
|
if file.exist?
|
||||||
@@ -94,7 +91,7 @@ class Mrsk::Configuration
|
|||||||
|
|
||||||
def env_args
|
def env_args
|
||||||
if config.env.present?
|
if config.env.present?
|
||||||
self.class.argumentize "-e", config.env
|
argumentize "-e", config.env
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
class Mrsk::Configuration::Role
|
class Mrsk::Configuration::Role
|
||||||
delegate :argumentize, to: Mrsk::Configuration
|
delegate :argumentize, to: Mrsk::Utils
|
||||||
|
|
||||||
attr_accessor :name
|
attr_accessor :name
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
module Mrsk::Utils
|
module Mrsk::Utils
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
|
# Return a list of shell arguments using the same named argument against the passed attributes.
|
||||||
|
def argumentize(argument, attributes, redacted: false)
|
||||||
|
attributes.flat_map { |k, v| [ argument, redacted ? redact("#{k}=#{v}") : "#{k}=#{v}" ] }
|
||||||
|
end
|
||||||
|
|
||||||
# Copied from SSHKit::Backend::Abstract#redact to be available inside Commands classes
|
# Copied from SSHKit::Backend::Abstract#redact to be available inside Commands classes
|
||||||
def redact(arg) # Used in execute_command to hide redact() args a user passes in
|
def redact(arg) # Used in execute_command to hide redact() args a user passes in
|
||||||
arg.to_s.extend(SSHKit::Redaction) # to_s due to our inability to extend Integer, etc
|
arg.to_s.extend(SSHKit::Redaction) # to_s due to our inability to extend Integer, etc
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ class CommandsBuilderTest < ActiveSupport::TestCase
|
|||||||
assert_equal [ "--build-arg", "a=1", "--build-arg", "b=2" ], builder.target.build_args
|
assert_equal [ "--build-arg", "a=1", "--build-arg", "b=2" ], builder.target.build_args
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "build secrets" do
|
||||||
|
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge({ builder: { "secrets" => ["token_a", "token_b"] } })))
|
||||||
|
assert_equal [ "--secret", "id=token_a", "--secret", "id=token_b" ], builder.target.build_secrets
|
||||||
|
end
|
||||||
|
|
||||||
test "native push with build args" do
|
test "native push with build args" do
|
||||||
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge({ builder: { "multiarch" => false, "args" => { "a" => 1, "b" => 2 } } })))
|
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge({ builder: { "multiarch" => false, "args" => { "a" => 1, "b" => 2 } } })))
|
||||||
assert_equal [ :docker, :build, "-t", "--build-arg", "a=1", "--build-arg", "b=2", "dhh/app:123", ".", "&&", :docker, :push, "dhh/app:123" ], builder.push
|
assert_equal [ :docker, :build, "-t", "--build-arg", "a=1", "--build-arg", "b=2", "dhh/app:123", ".", "&&", :docker, :push, "dhh/app:123" ], builder.push
|
||||||
|
|||||||
Reference in New Issue
Block a user