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

Refactoring #1

Open
wants to merge 5 commits into
base: asd-poc
Choose a base branch
from
Open
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
11 changes: 8 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
local
.env
# Security
data
*.crt
*.key
.dev

# Developer freedom
local

# Automatically generated files and folders
workspace
all.src
# list.src
# export.mk
77 changes: 56 additions & 21 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
#!make
.SILENT:

# > ASD
WORKSPACE_NAME=asd
WORKSPACE_ABBR=asd
export ASD_NETWORK=${WORKSPACE_ABBR}_network

# > Config

LOCAL_DIR?=local
WORKSPACE_DIR?=workspace
CONFIG_DIR=${WORKSPACE_DIR}/config
SERVICE_DIR=${WORKSPACE_DIR}/service
DEV_DIR=${WORKSPACE_DIR}/developer

CONFIG_FILE?=.env
CONFIG_DEFAULT?=./config/.env-example
export CONFIG_DIR=${WORKSPACE_DIR}/config
CONFIG_PATH?=${WORKSPACE_DIR}/config/${CONFIG_FILE}

# > Setup
Expand All @@ -19,13 +25,13 @@ all: ${WORKSPACE_DIR} ${CONFIG_PATH}
@printf '🚀 Run the start command to launch your environment.\n'

# Executes only if .env does not exist or the origin has
${CONFIG_PATH}:
${CONFIG_PATH}: ${CONFIG_DIR}/list.src ${CONFIG_DIR}/export.mk
cp ${CONFIG_DEFAULT} $@
@printf "📋 Copied default config to workspace.\n"
@printf "📝 Copied ${CONFIG_DEFAULT} dotenv config to ${CONFIG_PATH}.\n"

# Import and expose all VARS from the config to all make targets
ifeq ($(wildcard ${CONFIG_PATH}),) # check if file exists
# CONFIG_PATH is not set
# Include and expose all VARS from the dotenv file to all make targets
ifeq ($(wildcard ${CONFIG_PATH}),) # check if dir exist
@printf "🔍 ${CONFIG_PATH} not yet imported.\n"
else
-include ${CONFIG_PATH}
export $(shell sed 's/=.*//' ${CONFIG_PATH})
Expand All @@ -41,26 +47,53 @@ include scripts/make/modules/container/docker.mk
# > Services

SERVICES?=caddy whoami privoxy terminal codeserver headscale coredns #httptoolkit
SERVICES_INCLUDES := $(foreach service,$(SERVICES),docker/$(service)/$(service).mk)
include ${SERVICES_INCLUDES}
SERVICE_MAKE_FILES := $(foreach service,$(SERVICES),docker/$(service)/$(service).mk)
SERVICE_SRC_FILES += $(foreach service,$(SERVICES),$(call rwildcard,docker/$(service)/,*.src))
SERVICE_ENV_FILES += $(foreach service,$(SERVICES),$(call rwildcard,docker/$(service)/,*.env))
SERVICE_DOCKER_FILES := $(foreach service,$(SERVICES),$(call rwildcard,docker/$(service)/,*dockerfile))

include ${SERVICE_MAKE_FILES}

# > Project
# > Workspace

${LOCAL_DIR}:
mkdir -p local
mkdir -p $@

${SERVICE_DIR}:
mkdir -p ${SERVICE_DIR}
mkdir -p $@

${DEV_DIR}:
mkdir -p ${DEV_DIR}
mkdir -p $@

${CONFIG_DIR}:
mkdir -p ${CONFIG_DIR}
mkdir -p $@

${WORKSPACE_DIR}: ${SERVICE_DIR} ${CONFIG_DIR} ${DEV_DIR}
mkdir -p ${WORKSPACE_DIR}
@printf "📁 Created directory structure workspace dir config & service .\n"
# All site sources in one file
${CONFIG_DIR}/list.src: $(SERVICE_SRC_FILES)
@cat $^ | sort | uniq > $@
@printf "📋 Generated $@ for the wiki.\n"

# Generate a list of export VAR names into export.mk
${CONFIG_DIR}/export.mk:
sed 's/\(.*\)=.*/export \1/' $(SERVICE_ENV_FILES) > $@
@printf "📋 Generated $@ based on selected 🐳📦 services.\n"

${WORKSPACE_DIR}:
mkdir -p $@
@${MAKE} -s ${SERVICE_DIR} ${CONFIG_DIR} ${DEV_DIR}
@printf "📁 Created dir: ${SERVICE_DIR} ${CONFIG_DIR} ${DEV_DIR}.\n"

ifeq ($(wildcard ${CONFIG_DIR}/export.mk),) # check if dir exist
@printf "🔍 ${CONFIG_DIR}/export.mk not yet included.\n"
else
@printf "📤 Including ${CONFIG_DIR}/export.mk to export all service variables to subshells.\n"
-include ${CONFIG_DIR}/export.mk
endif

# Service variables
include ${SERVICE_ENV_FILES}

# > Docker

# Define a function to generate targets
define g_docker_targets
Expand All @@ -72,13 +105,20 @@ SERVICES_UP=$(call g_docker_targets,up)
SERVICES_DOWN=$(call g_docker_targets,down)
SERVICES_RECREATE=$(call g_docker_targets,recreate)

${CONFIG_DIR}/container_labels.json extract-service-labels:
./scripts/bash/extract-container-labels.sh

pull:
@make -j ${SERVICES_PULL}

start: ${LOCAL_DIR} ${WORKSPACE_DIR}
-docker network create ${ASD_NETWORK}
@make -j ${SERVICES_UP}
@wait
@docker ps
@${MAKE} post-start

post-start: ${CONFIG_DIR}/container_labels.json

stop:
@make -j ${SERVICES_DOWN}
Expand All @@ -92,8 +132,3 @@ browse:
${BROWSER}

.PHONY: pull start stop renew browse

# All site sources in one file
SRC_FILES += $(foreach service,$(SERVICES),$(call rwildcard,docker/$(service)/,*.src))
all.src: $(SRC_FILES)
@cat $^ | sort | uniq > $@
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,27 @@ Assuming the docker engine is running.

- Fixed: The browser can now accept https by adding the caddy root CA to the keystore
- ToDo: command for linux and some screenshots in docs for Windows/WSL2 would be nice

## Challanges

- Prevent the usage of pure program language based wrappers for the management of services on the host machine
- freedom starts when healthy containers are running

## Test

#### First run: `rm -rf workspace && time make`

**Expected**
📁 Created dir: workspace/service workspace/config workspace/developer.
🔍 workspace/config/export.mk not yet included.
📋 Generated workspace/config/list.src for the wiki.
📋 Generated workspace/config/export.mk based on selected 🐳📦 services.
📝 Copied ./config/.env-example dotenv config to workspace/config/.env.
🔍 workspace/config/.env not yet imported.
🚀 Run the start command to launch your environment.
make 0,03s user 0,01s system 103% cpu 0,042 total

#### Second run: `time make`
**Expected**
🚀 Run the start command to launch your environment.
make 0,01s user 0,01s system 99% cpu 0,017 total
1 change: 1 addition & 0 deletions docker/caddy/caddy.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CADDY_IMAGE=lucaslorentz/caddy-docker-proxy:2.8.9-alpine
2 changes: 1 addition & 1 deletion docker/caddy/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3.7"
services:
caddy:
image: lucaslorentz/caddy-docker-proxy:2.8.9-alpine
image: ${CADDY_IMAGE}
container_name: asd-caddy
ports:
- 80:80
Expand Down
26 changes: 19 additions & 7 deletions docker/codeserver/alpine.dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
# Use the official Alpine-based Node image as a starting point
FROM node:18-alpine
FROM node:18.17.1-alpine3.18
ARG MAINTAINERS
ARG CODE_SERVER_VERSION=4.22.1
ARG SERVICE_URL=https://open-vsx.org/vscode/gallery
ARG ITEM_URL=https://open-vsx.org/vscode/item

RUN npm install -g npm

# Metadata as described by the OCI image spec
LABEL org.opencontainers.image.title="Alpine code-server" \
LABEL org.opencontainers.image.title="ASD code-server" \
org.opencontainers.image.description="VS Code running on Alpine with code-server" \
org.opencontainers.image.source="https://github.com/coder/code-server"
org.opencontainers.image.source="https://github.com/kelvin-id/asd/docker/codeserver" \
org.opencontainers.image.maintainers="${MAINTAINERS}"

# Install dependencies required for node-gyp, kerberos, and other tools
RUN apk add --no-cache \
Expand All @@ -15,20 +22,25 @@ RUN apk add --no-cache \
make \
g++ \
sudo \
krb5-dev
krb5-dev \
curl

# https://coder.com/docs/code-server/latest/FAQ#how-do-i-install-an-extension

ENV PYTHON=/usr/bin/python3
RUN yarn config set python /usr/bin/python3
# Install node-gyp globally using npm
RUN npm install -g node-gyp

# Ensure global npm binaries are in the PATH
ENV PATH="/usr/local/share/.config/yarn/global/node_modules/.bin:${PATH}"

# Install code-server globally
RUN yarn global add code-server
RUN yarn global add code-server@${CODE_SERVER_VERSION}

# Set the code-server data directory
ENV SERVICE_URL=https://open-vsx.org/vscode/gallery
ENV ITEM_URL=https://open-vsx.org/vscode/item
ENV SERVICE_URL=${SERVICE_URL}
ENV ITEM_URL=${ITEM_URL}

# Expose the code-server port
EXPOSE 7682
Expand Down
Empty file.
2 changes: 1 addition & 1 deletion docker/codeserver/codeserver.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ MACHINE_ARCH=<QEMU?>
DEVELOPMENT_LANG=python

CODESERVER_IMAGE=codeserver-asd-terminal
CODESERVER_PATH=${PWD}/alpine.dockerfile
CODESERVER_PATH=${PWD}/code.dockerfile.${MACHINE_OS}
CODESERVER_COMPOSE=docker/codeserver/${MACHINE_OS}.docker-compose.yml

# Target to check if Dockerfile has changed and trigger a rebuild if necessary
Expand Down
2 changes: 1 addition & 1 deletion docker/coredns/coredns-docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3.7"
services:
coredns:
image: coredns/coredns:1.11.1
image: ${COREDNS_IMAGE}
container_name: asd-coredns
networks:
- asd_network
Expand Down
1 change: 1 addition & 0 deletions docker/coredns/coredns.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
COREDNS_IMAGE=coredns/coredns:1.11.1
1 change: 1 addition & 0 deletions docker/coredns/coredns.mk
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!make
.PHONY: $(call read_phony_targets,coredns.phony)

SERVICE=coredns
COREDNS_CONTAINER=asd-coredns
COREDNS_COMPOSE=docker/coredns/coredns-docker-compose.yml
COREDNS_CONFIG=${PWD}/docker/coredns/Corefile
Expand Down
32 changes: 32 additions & 0 deletions scripts/bash/extract-container-labels.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

# Name of the Docker network
network_name="${ASD_NEaTWORK}"

# Prepare the output file and start the JSON array
output_file="${CONFIG_DIR}/container_labels.json"
echo "[" > $output_file

# List all container IDs in a specific network
containers=$(docker ps --filter network=$network_name -q)
container_count=$(echo "$containers" | wc -w)
current_count=0

for container in $containers; do
# Increment the current container count
((current_count++))
# Retrieve labels for each container
labels=$(docker inspect $container --format '{{ json .Config.Labels }}')
# Add the labels JSON to the output file
# Check if it's the last item; if not, add a comma for valid JSON formatting
if [[ $current_count -lt $container_count ]]; then
echo "$labels," >> $output_file
else
echo "$labels" >> $output_file
fi
done

# Close the JSON array
echo "]" >> $output_file

printf "📄 Exported the container labels for all running services in $ASD_NETWORK to ${output_file}.\n"