Skip to content

Commit 5bc3c15

Browse files
committed
Add self-contained installer container
Introduce a Docker-based installation approach that bundles all required tooling (kind, kubectl, helm, helmfile, cf CLI) in a single container image. Users now only need Docker installed on their host. Changes: - Add Dockerfile with Alpine base and all CLI tools - Add .dockerignore to keep image minimal - Refactor Makefile to run commands inside container - Mount temp/ and docker socket for cluster management - Update README with simplified prerequisites and usage - Modify init.sh to use native openssl/ssh-keygen (available in container) The original make targets (up, down, login, bootstrap) work as before, but now automatically build and use the installer container. Internal targets prefixed with _ can still be used directly if tools are installed on the host.
1 parent f46975c commit 5bc3c15

File tree

7 files changed

+163
-89
lines changed

7 files changed

+163
-89
lines changed

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.git
2+
.github
3+
*.md
4+
temp

.github/workflows/kind-cats.yaml

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,6 @@ jobs:
2020
--pid host \
2121
-v /lib/modules:/lib/modules:ro \
2222
alpine sh -c "sysctl -w fs.inotify.max_user_instances=512 && modprobe nfs && modprobe nfsd"
23-
- name: Install dependencies
24-
run: |
25-
mkdir -p $HOME/.local/bin && echo "$HOME/.local/bin" >> "$GITHUB_PATH"
26-
curl -L https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-linux-amd64 -o $HOME/.local/bin/kind
27-
chmod +x $HOME/.local/bin/kind
28-
curl -L https://github.com/helmfile/helmfile/releases/download/v${HELMFILE_VERSION}/helmfile_${HELMFILE_VERSION}_linux_amd64.tar.gz | tar -zx
29-
mv helmfile $HOME/.local/bin/helmfile
30-
curl -L "https://packages.cloudfoundry.org/stable?release=linux64-binary&version=${CF_CLI_VERSION}&source=github" | tar -zx
31-
mv cf8 $HOME/.local/bin/cf
32-
env:
33-
CF_CLI_VERSION: '8.14.1'
34-
KIND_VERSION: '0.30.0'
35-
HELMFILE_VERSION: '1.2.3'
3623
- name: Run make up
3724
env:
3825
ENABLE_NFS_VOLUME: "true"

.github/workflows/kind-smoke.yaml

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,6 @@ jobs:
3838
--privileged \
3939
--pid host \
4040
alpine sh -c "sysctl -w fs.inotify.max_user_instances=512"
41-
- name: Install dependencies
42-
if: steps.check_changes.outputs.skip != 'true'
43-
run: |
44-
mkdir -p $HOME/.local/bin && echo "$HOME/.local/bin" >> "$GITHUB_PATH"
45-
curl -L https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-linux-amd64 -o $HOME/.local/bin/kind
46-
chmod +x $HOME/.local/bin/kind
47-
curl -L https://github.com/helmfile/helmfile/releases/download/v${HELMFILE_VERSION}/helmfile_${HELMFILE_VERSION}_linux_amd64.tar.gz | tar -zx
48-
mv helmfile $HOME/.local/bin/helmfile
49-
curl -L "https://packages.cloudfoundry.org/stable?release=linux64-binary&version=${CF_CLI_VERSION}&source=github" | tar -zx
50-
mv cf8 $HOME/.local/bin/cf
51-
env:
52-
CF_CLI_VERSION: '8.14.1'
53-
KIND_VERSION: '0.30.0'
54-
HELMFILE_VERSION: '1.2.3'
5541
- name: Run make up
5642
if: steps.check_changes.outputs.skip != 'true'
5743
run: make up

Dockerfile

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# renovate: datasource=docker depName=alpine
2+
FROM alpine:3.21@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709
3+
4+
# renovate: datasource=github-releases depName=kubernetes-sigs/kind
5+
ARG KIND_VERSION=v0.31.0
6+
# renovate: datasource=github-releases depName=kubernetes/kubernetes
7+
ARG KUBECTL_VERSION=v1.35.1
8+
# renovate: datasource=github-releases depName=helmfile/helmfile
9+
ARG HELMFILE_VERSION=v1.3.2
10+
# renovate: datasource=github-releases depName=helm/helm
11+
ARG HELM_VERSION=v4.1.1
12+
# renovate: datasource=github-releases depName=cloudfoundry/cli
13+
ARG CF_CLI_VERSION=v8.17.0
14+
15+
RUN apk add --no-cache \
16+
bash \
17+
curl \
18+
docker-cli \
19+
docker-cli-compose \
20+
jq \
21+
make \
22+
openssh-keygen \
23+
openssl
24+
25+
ARG TARGETARCH
26+
27+
RUN curl -fsSL "https://github.com/kubernetes-sigs/kind/releases/download/${KIND_VERSION}/kind-linux-${TARGETARCH}" -o /usr/local/bin/kind \
28+
&& chmod +x /usr/local/bin/kind
29+
30+
RUN curl -fsSL "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl" -o /usr/local/bin/kubectl \
31+
&& chmod +x /usr/local/bin/kubectl
32+
33+
RUN curl -fsSL "https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz" | tar xz -C /tmp \
34+
&& mv /tmp/linux-${TARGETARCH}/helm /usr/local/bin/helm \
35+
&& rm -rf /tmp/linux-${TARGETARCH}
36+
37+
RUN curl -fsSL "https://github.com/helmfile/helmfile/releases/download/${HELMFILE_VERSION}/helmfile_${HELMFILE_VERSION#v}_linux_${TARGETARCH}.tar.gz" | tar xz -C /tmp \
38+
&& mv /tmp/helmfile /usr/local/bin/helmfile \
39+
&& rm -rf /tmp/LICENSE /tmp/README*
40+
41+
RUN CF_ARCH=$([ "${TARGETARCH}" = "amd64" ] && echo "x86-64" || echo "${TARGETARCH}") \
42+
&& curl -fsSL "https://github.com/cloudfoundry/cli/releases/download/${CF_CLI_VERSION}/cf8-cli_${CF_CLI_VERSION#v}_linux_${CF_ARCH}.tgz" | tar xz -C /tmp \
43+
&& mv /tmp/cf8 /usr/local/bin/cf \
44+
&& rm -rf /tmp/LICENSE /tmp/NOTICE
45+
46+
WORKDIR /workspace
47+
48+
COPY . .
49+
50+
ENTRYPOINT ["/bin/bash", "-c"]
51+
CMD ["make"]

Makefile

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,79 @@
11
LOCAL = true
22
TARGET_ARCH ?= $(if $(filter true,$(LOCAL)),$(shell go env GOARCH),amd64)
3-
# renovate: dataSource=github-releases depName=helmfile/helmfile
4-
HELMFILE_VERSION ?= "1.3.2"
3+
IMAGE ?= cf-kind-deployment:latest
4+
DOCKER_SOCKET ?= $(shell docker context inspect --format '{{.Endpoints.docker.Host}}' | sed 's|unix://||')
5+
TTY_FLAG := $(shell [ -t 0 ] && echo "-it" || echo "-i")
56

6-
init: temp/certs/ca.key temp/certs/ca.crt temp/certs/ssh_key temp/certs/ssh_key.pub temp/secrets.sh temp/secrets.env
7+
# Common docker run options
8+
run_opts = --rm $(TTY_FLAG) \
9+
--network host \
10+
-v $(DOCKER_SOCKET):/var/run/docker.sock \
11+
-v "$$PWD/temp:/workspace/temp" \
12+
-e ENABLE_TCP_ROUTING \
13+
-e ENABLE_NFS_VOLUME \
14+
-e ENABLE_POLICY_SUPPORT \
15+
-e ENABLE_LOGGREGATOR \
16+
-e DISABLE_CACHE
717

8-
temp/certs/ca.key temp/certs/ca.crt temp/certs/ssh_key temp/certs/ssh_key.pub temp/secrets.sh temp/secrets.env:
9-
@ ./scripts/init.sh
18+
# Container run command
19+
run = docker run $(run_opts) $(IMAGE)
1020

11-
install:
12-
kind get kubeconfig --name cfk8s > temp/kubeconfig
13-
docker run --rm --net=host --env-file temp/secrets.env \
14-
--env ENABLE_TCP_ROUTING \
15-
--env ENABLE_NFS_VOLUME \
16-
--env ENABLE_POLICY_SUPPORT \
17-
--env ENABLE_LOGGREGATOR \
18-
-v "$$PWD/temp/certs:/certs" -v "$$PWD/temp/kubeconfig:/helm/.kube/config:ro" -v "$$PWD:/wd" --workdir /wd ghcr.io/helmfile/helmfile:v$(HELMFILE_VERSION) helmfile sync
21+
# Default targets (container-based)
22+
up: _build-installer-quiet
23+
$(run) "make _create-kind _init _install"
24+
25+
down: _build-installer-quiet
26+
$(run) "make _delete-kind"
27+
rm -rf temp
1928

2029
login:
21-
@ . temp/secrets.sh; \
30+
@ . ./temp/secrets.sh; \
2231
cf login -a https://api.127-0-0-1.nip.io -u ccadmin -p "$$CC_ADMIN_PASSWORD" --skip-ssl-validation
2332

24-
create-kind:
33+
bootstrap: _build-installer-quiet
34+
$(run) "make login _bootstrap"
35+
36+
bootstrap-complete: _build-installer-quiet
37+
$(run) "make login _bootstrap-complete"
38+
39+
shell: _build-installer-quiet
40+
docker run $(run_opts) -v "$$PWD:/workspace" $(IMAGE) "bash"
41+
42+
# Build the installer container (verbose)
43+
build-installer:
44+
docker build -t $(IMAGE) .
45+
46+
# Build the installer container (quiet)
47+
_build-installer-quiet:
48+
@docker build -q -t $(IMAGE) . > /dev/null
49+
50+
# Internal targets (run inside container or on host with tools installed)
51+
_init: temp/certs/ca.key temp/certs/ca.crt temp/certs/ssh_key temp/certs/ssh_key.pub temp/secrets.sh temp/secrets.env
52+
53+
temp/certs/ca.key temp/certs/ca.crt temp/certs/ssh_key temp/certs/ssh_key.pub temp/secrets.sh temp/secrets.env:
54+
@ ./scripts/init.sh
55+
56+
_install:
57+
kind get kubeconfig --name cfk8s > temp/kubeconfig
58+
@ . ./temp/secrets.sh && KUBECONFIG=temp/kubeconfig helmfile sync
59+
60+
_create-kind:
2561
@ ./scripts/create-kind.sh
2662

27-
delete-kind:
63+
_delete-kind:
2864
@ ./scripts/delete-kind.sh
2965

30-
create-org:
66+
_create-org:
3167
cf create-org test
3268
cf create-space -o test test
3369
cf target -o test -s test
3470
@ ./scripts/set_feature_flags.sh
3571

36-
bootstrap: create-org
72+
_bootstrap: _create-org
3773
@ ./scripts/upload_buildpacks.sh
3874

39-
bootstrap-complete: create-org
75+
_bootstrap-complete: _create-org
4076
@ ALL_BUILDPACKS=true ./scripts/upload_buildpacks.sh
4177

42-
up: create-kind init install
43-
44-
down: delete-kind
45-
@ rm -rf temp
46-
47-
PHONY: install login create-kind delete-kind up down create-org bootstrap bootstrap-complete
78+
.PHONY: up down login bootstrap bootstrap-complete shell build-installer
79+
.PHONY: _init _install _create-kind _delete-kind _create-org _bootstrap _bootstrap-complete _build-installer-quiet

README.md

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,10 @@ This repository provides a simple and fast way to run Cloud Foundry locally. It
44

55
## Prerequisites
66

7-
The following tools need to be installed:
7+
- [Docker](https://docs.docker.com/engine/install/) (with Docker Compose), alternatives like colima or podman may also work.
8+
- [`cf` CLI](https://docs.cloudfoundry.org/cf-cli/install-go-cli.html) (v8.17.0+)
89

9-
- [`docker`](https://docs.docker.com/engine/install/)
10-
- [`kind`](https://kind.sigs.k8s.io/docs/user/quick-start/#installing-from-release-binaries) (v0.31.0 or higher)
11-
- [`kubectl`](https://kubernetes.io/docs/tasks/tools/#kubectl) (v1.35.1 or higher)
12-
- `make`:
13-
- It should be already installed on MacOS and Linux.
14-
- For Windows installation see: <https://gnuwin32.sourceforge.net/packages/make.htm>
10+
All other tools (kind, kubectl, helm, helmfile) are bundled in the installer container.
1511

1612
## Run the Installation
1713

@@ -46,12 +42,27 @@ make down
4642

4743
You can configure the installation by setting following environment variables:
4844

49-
| environment variable | default | component(s) to be installed |
50-
| ----------------------- | ------- | ---------------------------------------------------------------------- |
51-
| `ENABLE_LOGGREGATOR` | `true` | Loggregator |
52-
| `ENABLE_POLICY_SUPPORT` | `true` | policy-serverver, policy-agent, bosh-dns, service-discovery-controller |
53-
| `ENABLE_TCP_ROUTING` | `true` | cf-tcp-router, routing-api |
54-
| `ENABLE_NFS_VOLUME` | `false` | nfsbroker |
45+
| Environment Variable | Default | Description |
46+
|---------------------|---------|-------------|
47+
| `ENABLE_LOGGREGATOR` | `true` | Install Loggregator |
48+
| `ENABLE_POLICY_SUPPORT` | `true` | Install policy-server, policy-agent, bosh-dns, service-discovery-controller |
49+
| `ENABLE_TCP_ROUTING` | `true` | Install cf-tcp-router, routing-api |
50+
| `ENABLE_NFS_VOLUME` | `false` | Install nfsbroker |
51+
| `DISABLE_CACHE` | `false` | Disable registry pull-through caches |
52+
| `DOCKER_SOCKET` | auto-detected | Path to Docker socket (override if auto-detection fails) |
53+
54+
Example:
55+
56+
```bash
57+
ENABLE_NFS_VOLUME=true make up
58+
```
59+
60+
## Additional Commands
61+
62+
| Command | Description |
63+
|---------|-------------|
64+
| `make shell` | Open a development shell (mounts local source code for development/testing) |
65+
| `make build-installer` | Build the installer container without running it |
5566

5667
## Unsupported Features
5768

scripts/init.sh

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,30 @@
22

33
set -euo pipefail
44

5-
mkdir -p temp/certs
6-
7-
OPENSSL="docker run --rm -v $(pwd)/temp/certs:/certs -v $(pwd)/certs/all-in-one.conf:/all-in-one.conf alpine/openssl"
8-
SSH_KEYGEN="docker run --rm -v $(pwd)/temp/certs:/certs --entrypoint /usr/bin/ssh-keygen linuxserver/openssh-server"
9-
10-
$OPENSSL genrsa -traditional -out /certs/ca.key 4096
11-
$OPENSSL req -x509 -key /certs/ca.key -out /certs/ca.crt -days 365 -noenc -subj "/CN=ca/O=ca" \
12-
-config /all-in-one.conf -extensions v3_ca > /dev/null 2>&1
13-
$OPENSSL req -new -keyout /certs/all-in-one.key -out /certs/all-in-one.csr -noenc -config /all-in-one.conf > /dev/null 2>&1
14-
$OPENSSL x509 -req -in /certs/all-in-one.csr -CA /certs/ca.crt -CAkey /certs/ca.key -CAcreateserial \
15-
-out /certs/all-in-one.crt -days 365 -copy_extensions copy > /dev/null 2>&1
16-
17-
rm -f temp/certs/ssh_key temp/certs/ssh_key.pub
18-
$SSH_KEYGEN -t rsa -b 4096 -f /certs/ssh_key -N "" > /dev/null 2>&1
19-
20-
echo "export BLOBSTORE_PASSWORD=$($OPENSSL rand -hex 16)" > temp/secrets.sh
21-
echo "export DB_PASSWORD=$($OPENSSL rand -hex 16)" >> temp/secrets.sh
22-
echo "export OAUTH_CLIENTS_SECRET=$($OPENSSL rand -hex 16)" >> temp/secrets.sh
23-
echo "export DIEGO_SSH_CREDENTIALS=$($OPENSSL rand -hex 16)" >> temp/secrets.sh
24-
echo "export CC_ADMIN_PASSWORD=$($OPENSSL rand -hex 16)" >> temp/secrets.sh
25-
echo "export UAA_ADMIN_SECRET=$($OPENSSL rand -hex 16)" >> temp/secrets.sh
26-
echo "export SSH_PROXY_KEY_FINGERPRINT=$($SSH_KEYGEN -l -E md5 -f /certs/ssh_key.pub | cut -d' ' -f2 | cut -d: -f2-)" >> temp/secrets.sh
27-
28-
sed 's/^export //g' temp/secrets.sh > temp/secrets.env
5+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
7+
8+
mkdir -p "${ROOT_DIR}/temp/certs"
9+
10+
CERTS_DIR="${ROOT_DIR}/temp/certs"
11+
CONF_FILE="${ROOT_DIR}/certs/all-in-one.conf"
12+
13+
openssl genrsa -traditional -out "${CERTS_DIR}/ca.key" 4096
14+
openssl req -x509 -key "${CERTS_DIR}/ca.key" -out "${CERTS_DIR}/ca.crt" -days 365 -noenc -subj "/CN=ca/O=ca" \
15+
-config "${CONF_FILE}" -extensions v3_ca > /dev/null 2>&1
16+
openssl req -new -keyout "${CERTS_DIR}/all-in-one.key" -out "${CERTS_DIR}/all-in-one.csr" -noenc -config "${CONF_FILE}" > /dev/null 2>&1
17+
openssl x509 -req -in "${CERTS_DIR}/all-in-one.csr" -CA "${CERTS_DIR}/ca.crt" -CAkey "${CERTS_DIR}/ca.key" -CAcreateserial \
18+
-out "${CERTS_DIR}/all-in-one.crt" -days 365 -copy_extensions copy > /dev/null 2>&1
19+
20+
rm -f "${CERTS_DIR}/ssh_key" "${CERTS_DIR}/ssh_key.pub"
21+
ssh-keygen -t rsa -b 4096 -f "${CERTS_DIR}/ssh_key" -N "" > /dev/null 2>&1
22+
23+
echo "export BLOBSTORE_PASSWORD=$(openssl rand -hex 16)" > "${ROOT_DIR}/temp/secrets.sh"
24+
echo "export DB_PASSWORD=$(openssl rand -hex 16)" >> "${ROOT_DIR}/temp/secrets.sh"
25+
echo "export OAUTH_CLIENTS_SECRET=$(openssl rand -hex 16)" >> "${ROOT_DIR}/temp/secrets.sh"
26+
echo "export DIEGO_SSH_CREDENTIALS=$(openssl rand -hex 16)" >> "${ROOT_DIR}/temp/secrets.sh"
27+
echo "export CC_ADMIN_PASSWORD=$(openssl rand -hex 16)" >> "${ROOT_DIR}/temp/secrets.sh"
28+
echo "export UAA_ADMIN_SECRET=$(openssl rand -hex 16)" >> "${ROOT_DIR}/temp/secrets.sh"
29+
echo "export SSH_PROXY_KEY_FINGERPRINT=$(ssh-keygen -l -E md5 -f "${CERTS_DIR}/ssh_key.pub" | cut -d' ' -f2 | cut -d: -f2-)" >> "${ROOT_DIR}/temp/secrets.sh"
30+
31+
sed 's/^export //g' "${ROOT_DIR}/temp/secrets.sh" > "${ROOT_DIR}/temp/secrets.env"

0 commit comments

Comments
 (0)