diff --git a/docker/.gitkeep b/docker/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/docker/.gitkeep @@ -0,0 +1 @@ + diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..b24701d --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,48 @@ +FROM golang:alpine as build + +# Install git. +# Git is required for fetching the dependencies. +RUN apk update && apk add --no-cache git + +# Create appuser. +ENV USER=appuser +ENV UID=10001 +# See https://stackoverflow.com/a/55757473/12429735RUN +RUN adduser \ + --disabled-password \ + --gecos "" \ + --home "/nonexistent" \ + --shell "/sbin/nologin" \ + --no-create-home \ + --uid "${UID}" \ + "${USER}" + +WORKDIR /app +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . +RUN go get -d -v +RUN GOOS=linux go build -ldflags="-w -s" -o /app/howto + + + +FROM scratch + +ARG OPENAI_API_KEY +ENV OPENAI_API_KEY=${OPENAI_API_KEY} + +# To allow TLS requests to OpenAI +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt + +# Import the user and group files from the builder. +COPY --from=build /etc/passwd /etc/passwd +COPY --from=build /etc/group /etc/group + +WORKDIR /app +COPY --from=build /app/howto /app/howto + +# Use an unprivileged user. +USER appuser:appuser + +ENTRYPOINT ["/app/howto"] diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..38bc249 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,34 @@ +# Overview + +Run howto app in docker/podman container + +# Set up on shell + +## One time set up +```bash +./build.sh + +# Set API key +## Could be set also in ~/.bashrc file or similar +read -s OPENAI_API_KEY ; echo "export OPENAI_API_KEY=$OPENAI_API_KEY" >> + +# Set alias +echo "alias howto=\"$(realpath)/run.sh\"" >> ~/.bashrc +``` + +# Usage + +```bash +./run.sh "tar a file" + +# Or with alias +howto "tar a file" +``` + +# Security hardening + +Image runs: +- without (almost) any other filesystem files than binary itself (FROM scratch) +- with non-root user + +And provided run.sh script runs it with readonly container filesystem diff --git a/docker/build.sh b/docker/build.sh new file mode 100644 index 0000000..e8a2dfb --- /dev/null +++ b/docker/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +# Execute from root of repo +cd "$(git rev-parse --show-toplevel)" +docker build -f docker/Dockerfile -t sandbox-howto . diff --git a/docker/run.sh b/docker/run.sh new file mode 100644 index 0000000..abfea22 --- /dev/null +++ b/docker/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +CONFIG_DIR="$HOME/.howto/config" +docker run --read-only -v "$CONFIG_DIR:/nonexistent:rw" -e OPENAI_API_KEY=$OPENAI_API_KEY sandbox-howto $1