Skip to content

Commit 0605226

Browse files
wilcorreaCopilot
andcommitted
feat: add copilot-sandbox image with multi-arch CI
- Dockerfile based on node:24-slim with git, gh, docker CLI, AWS CLI, uv, SDKMAN - CA certificate handled via runtime volume mount (not build-time ARG) - GitHub Actions workflow builds linux/amd64 + linux/arm64 - Publishes to ghcr.io/devitools/copilot-sandbox:latest + SHA tag - Triggers on push to copilot-sandbox/** or workflow_dispatch Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 569534e commit 0605226

File tree

22 files changed

+3386
-0
lines changed

22 files changed

+3386
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Build copilot-sandbox
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- copilot-sandbox/**
9+
workflow_dispatch:
10+
11+
env:
12+
REGISTRY: ghcr.io
13+
IMAGE_NAME: ghcr.io/devitools/copilot-sandbox
14+
15+
jobs:
16+
build-and-push:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
packages: write
21+
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Set up QEMU
27+
uses: docker/setup-qemu-action@v3
28+
29+
- name: Set up Docker Buildx
30+
uses: docker/setup-buildx-action@v3
31+
32+
- name: Log in to GitHub Container Registry
33+
uses: docker/login-action@v3
34+
with:
35+
registry: ${{ env.REGISTRY }}
36+
username: ${{ github.actor }}
37+
password: ${{ secrets.GITHUB_TOKEN }}
38+
39+
- name: Extract metadata
40+
id: meta
41+
uses: docker/metadata-action@v5
42+
with:
43+
images: ${{ env.IMAGE_NAME }}
44+
tags: |
45+
type=raw,value=latest,enable={{is_default_branch}}
46+
type=sha,prefix=,format=short
47+
48+
- name: Build and push
49+
uses: docker/build-push-action@v6
50+
with:
51+
context: ./copilot-sandbox
52+
platforms: linux/amd64,linux/arm64
53+
push: true
54+
tags: ${{ steps.meta.outputs.tags }}
55+
labels: ${{ steps.meta.outputs.labels }}
56+
cache-from: type=gha
57+
cache-to: type=gha,mode=max

copilot-sandbox/Dockerfile

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
FROM node:24-slim
2+
3+
LABEL maintainer="william.correa@picpay.com"
4+
LABEL description="Copilot Sandbox - Docker container for GitHub Copilot CLI"
5+
6+
# Install minimal packages needed for CA cert setup and subsequent steps
7+
RUN apt-get update && apt-get install -y --no-install-recommends \
8+
ca-certificates \
9+
curl \
10+
&& rm -rf /var/lib/apt/lists/*
11+
12+
# Install remaining system dependencies
13+
RUN apt-get update && apt-get install -y --no-install-recommends \
14+
git \
15+
gnupg \
16+
wget \
17+
unzip \
18+
zip \
19+
build-essential \
20+
jq \
21+
python3 \
22+
python3-venv \
23+
sed \
24+
openssh-client \
25+
&& curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | \
26+
dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
27+
&& chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
28+
&& echo "deb [signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | \
29+
tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
30+
&& apt-get update \
31+
&& apt-get install -y --no-install-recommends gh \
32+
&& apt-get clean \
33+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
34+
35+
# Install Docker CLI only (no daemon needed — we mount the host socket)
36+
# Uses TARGETARCH (set automatically by BuildKit) for cross-platform builds.
37+
ARG TARGETARCH
38+
RUN case "${TARGETARCH:-amd64}" in \
39+
amd64) DOCKER_ARCH="x86_64" ; COMPOSE_ARCH="x86_64" ;; \
40+
arm64) DOCKER_ARCH="aarch64" ; COMPOSE_ARCH="aarch64" ;; \
41+
*) DOCKER_ARCH="${TARGETARCH}" ; COMPOSE_ARCH="${TARGETARCH}" ;; \
42+
esac \
43+
&& curl -fsSL "https://download.docker.com/linux/static/stable/${DOCKER_ARCH}/docker-27.5.1.tgz" -o docker.tgz \
44+
&& tar -xzf docker.tgz --strip-components=1 -C /usr/local/bin docker/docker \
45+
&& rm docker.tgz \
46+
&& docker --version \
47+
&& mkdir -p /usr/local/lib/docker/cli-plugins \
48+
&& curl -fsSL "https://github.com/docker/compose/releases/download/v2.33.1/docker-compose-linux-${COMPOSE_ARCH}" \
49+
-o /usr/local/lib/docker/cli-plugins/docker-compose \
50+
&& chmod +x /usr/local/lib/docker/cli-plugins/docker-compose \
51+
&& docker compose version
52+
53+
# Install AWS CLI v2
54+
RUN case "${TARGETARCH:-amd64}" in \
55+
amd64) AWS_ARCH="x86_64" ;; \
56+
arm64) AWS_ARCH="aarch64" ;; \
57+
*) AWS_ARCH="x86_64" ;; \
58+
esac \
59+
&& curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-${AWS_ARCH}.zip" -o awscliv2.zip \
60+
&& unzip -q awscliv2.zip \
61+
&& ./aws/install \
62+
&& rm -rf aws awscliv2.zip \
63+
&& aws --version
64+
65+
# Install uv (Python package manager, includes uvx)
66+
# Pinned to a specific version to avoid supply-chain risk from mutable :latest tag.
67+
COPY --from=ghcr.io/astral-sh/uv:0.10.4 /uv /uvx /usr/local/bin/
68+
69+
# Install SDKMAN
70+
ENV SDKMAN_DIR="/root/.sdkman"
71+
ENV PATH="$SDKMAN_DIR/bin:$PATH"
72+
RUN curl -s "https://get.sdkman.io" | bash \
73+
&& bash -c "source $SDKMAN_DIR/bin/sdkman-init.sh \
74+
&& sdk version"
75+
76+
# Persistent cache directory (mounted from host ~/.copilot-sandbox)
77+
RUN mkdir -p /opt/copilot-sandbox
78+
79+
# Allow non-root users to register themselves in /etc/passwd at runtime.
80+
# Required when running with --user UID:GID where the UID doesn't exist in the
81+
# image. Tools like git, ssh, and Node.js fail without a valid passwd entry.
82+
# World-writable is necessary because the UID is arbitrary and has no pre-existing
83+
# group membership in the image. The container is ephemeral and single-user.
84+
RUN chmod 666 /etc/passwd /etc/group
85+
86+
# Copy Copilot customizations
87+
COPY container/instructions/ /opt/copilot-sandbox/instructions/
88+
COPY container/skills/ /opt/copilot-sandbox/skills/
89+
90+
# Copy scripts
91+
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
92+
COPY user-entrypoint.sh /usr/local/bin/user-entrypoint.sh
93+
COPY bin/jira bin/http bin/confluence bin/notify-arandu bin/xdg-open bin/docker-compose /usr/local/bin/
94+
RUN chmod 755 /usr/local/bin/entrypoint.sh /usr/local/bin/user-entrypoint.sh \
95+
/usr/local/bin/jira /usr/local/bin/http /usr/local/bin/confluence \
96+
/usr/local/bin/notify-arandu /usr/local/bin/xdg-open /usr/local/bin/docker-compose
97+
98+
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
99+
CMD ["copilot"]

0 commit comments

Comments
 (0)