This commit is contained in:
2025-10-28 19:57:51 -05:00
parent 9f17603c1e
commit 65b278e33f
27 changed files with 875 additions and 227 deletions

View File

@@ -0,0 +1,72 @@
# TSYSDevStack SupportStack Demo - Environment Settings
# Auto-generated file for MVP components: docker-socket-proxy, homepage, wakaapi
# General Settings
TSYSDEVSTACK_ENVIRONMENT=demo
TSYSDEVSTACK_PROJECT_NAME=TSYSDevStack-SupportStack-Demo
TSYSDEVSTACK_NETWORK_NAME=tsysdevstack_supportstack_network
# User/Group Settings
TSYSDEVSTACK_UID=1000
TSYSDEVSTACK_GID=1000
TSYSDEVSTACK_DOCKER_GID=996
# Docker Socket Proxy Settings
DOCKER_SOCKET_PROXY_NAME=tsysdevstack-supportstack-demo-docker-socket-proxy
DOCKER_SOCKET_PROXY_IMAGE=tecnativa/docker-socket-proxy:0.1
DOCKER_SOCKET_PROXY_SOCKET_PATH=/var/run/docker.sock
DOCKER_SOCKET_PROXY_NETWORK=tsysdevstack_supportstack_network
# Docker API Permissions
DOCKER_SOCKET_PROXY_CONTAINERS=1
DOCKER_SOCKET_PROXY_IMAGES=1
DOCKER_SOCKET_PROXY_NETWORKS=1
DOCKER_SOCKET_PROXY_VOLUMES=1
DOCKER_SOCKET_PROXY_BUILD=1
DOCKER_SOCKET_PROXY_MANIFEST=1
DOCKER_SOCKET_PROXY_PLUGINS=1
DOCKER_SOCKET_PROXY_VERSION=1
# Homepage Settings
HOMEPAGE_NAME=tsysdevstack-supportstack-demo-homepage
HOMEPAGE_IMAGE=gethomepage/homepage:latest
HOMEPAGE_PORT=4000
HOMEPAGE_NETWORK=tsysdevstack_supportstack_network
HOMEPAGE_CONFIG_PATH=./config/homepage
# WakaAPI Settings
WAKAAPI_NAME=tsysdevstack-supportstack-demo-wakaapi
WAKAAPI_IMAGE=n1try/wakapi:latest
WAKAAPI_PORT=4001
WAKAAPI_NETWORK=tsysdevstack_supportstack_network
WAKAAPI_CONFIG_PATH=./config/wakaapi
WAKAAPI_WAKATIME_API_KEY=
WAKAAPI_DATABASE_PATH=./config/wakaapi/database
# Resource Limits (for single user demo capacity)
# docker-socket-proxy
DOCKER_SOCKET_PROXY_MEM_LIMIT=128m
DOCKER_SOCKET_PROXY_CPU_LIMIT=0.25
# homepage
HOMEPAGE_MEM_LIMIT=256m
HOMEPAGE_CPU_LIMIT=0.5
# wakaapi
WAKAAPI_MEM_LIMIT=192m
WAKAAPI_CPU_LIMIT=0.3
# Health Check Settings
HEALTH_CHECK_INTERVAL=30s
HEALTH_CHECK_TIMEOUT=10s
HEALTH_CHECK_START_PERIOD=30s
HEALTH_CHECK_RETRIES=3
# Timeouts
DOCKER_SOCKET_PROXY_CONNECTION_TIMEOUT=30s
HOMEPAGE_STARTUP_TIMEOUT=60s
WAKAAPI_INITIALIZATION_TIMEOUT=45s
DOCKER_COMPOSE_STARTUP_TIMEOUT=120s
# Localhost binding
BIND_ADDRESS=127.0.0.1

View File

@@ -0,0 +1,40 @@
---
# Homepage configuration - Enable Docker service discovery
title: TSYSDevStack SupportStack
# Docker configuration - Enable automatic service discovery
docker:
socket: /var/run/docker.sock
# Services configuration - Enable Docker discovery
services: []
# Bookmarks
bookmarks:
- Developer:
- Github:
href: https://github.com/
abbr: GH
- Social:
- Reddit:
href: https://reddit.com/
abbr: RE
- Entertainment:
- YouTube:
href: https://youtube.com/
abbr: YT
# Widgets
widgets:
- resources:
cpu: true
memory: true
disk: /
- search:
provider: duckduckgo
target: _blank
# Proxy configuration
proxy:
allowedHosts: "*"
allowedHeaders: "*"

View File

@@ -0,0 +1,3 @@
---
# Docker configuration for Homepage service discovery
socket: /var/run/docker.sock

View File

@@ -0,0 +1,8 @@
---
# Services configuration for Homepage Docker discovery
# Automatically discover Docker services with Homepage labels
- Support Stack:
- tsysdevstack-docker-socket-proxy
- tsysdevstack-homepage
- tsysdevstack-wakaapi

View File

@@ -1,25 +1,42 @@
---
# Homepage configuration
title: TSYSDevStack SupportStack
background: /images/background-1.jpg
background:
headerStyle: boxed
layout:
Support Stack:
style: row
columns: 4
items:
- type: docker
name: Docker Socket Proxy
icon: docker.png
href: http://tsysdevstack-docker-socket-proxy:2375
container: tsysdevstack-docker-socket-proxy
showStats: true
- type: wakapi
name: WakaAPI
icon: wakatime.png
href: http://127.0.0.1:4001
container: tsysdevstack-wakaapi
showStats: true
# Configure allowed hosts for the proxy
# Docker configuration
docker:
socket: /var/run/docker.sock
# Services configuration
services: []
# Bookmarks
bookmarks:
- Developer:
- Github:
href: https://github.com/
abbr: GH
- Social:
- Reddit:
href: https://reddit.com/
abbr: RE
- Entertainment:
- YouTube:
href: https://youtube.com/
abbr: YT
# Widgets
widgets:
- resources:
cpu: true
memory: true
disk: /
- search:
provider: duckduckgo
target: _blank
# Proxy configuration
proxy:
allowedHosts: "*"
allowedHeaders: "*"

View File

@@ -1,40 +0,0 @@
services:
docker-socket-proxy:
image: tecnativa/docker-socket-proxy:0.1
container_name: tsysdevstack-docker-socket-proxy
restart: unless-stopped
networks:
- tsysdevstack_supportstack_network
environment:
CONTAINERS: "1"
IMAGES: "1"
NETWORKS: "1"
VOLUMES: "1"
BUILD: "1"
MANIFEST: "1"
PLUGINS: "1"
VERSION: "1"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
mem_limit: 128m
mem_reservation: 128m
deploy:
resources:
limits:
cpus: '0.25'
memory: 128M
reservations:
cpus: '0.25'
memory: 128M
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
interval: 30s
timeout: 10s
start_period: 30s
retries: 3
# Note: No ports exposed as per requirement for internal network only
networks:
tsysdevstack_supportstack_network:
external: true
name: tsysdevstack_supportstack_network

View File

@@ -1,45 +0,0 @@
services:
homepage:
image: gethomepage/homepage:latest
container_name: tsysdevstack-homepage
restart: unless-stopped
networks:
- tsysdevstack_supportstack_network
ports:
- "127.0.0.1:4000:3000"
environment:
- PORT=3000
- HOMEPAGE_URL=http://localhost:4000
- BASE_URL=http://localhost:4000
- HOMEPAGE_ALLOWED_HOSTS=localhost:4000,127.0.0.1:4000
volumes:
- ./config/homepage:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro # For Docker integration
mem_limit: 256m
mem_reservation: 128m
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
start_period: 60s # Longer start period for homepage
retries: 3
# Homepage integration labels for automatic discovery
labels:
homepage.group: "Support Stack"
homepage.name: "Homepage Dashboard"
homepage.icon: "homepage.png"
homepage.href: "http://127.0.0.1:4000"
homepage.description: "Homepage dashboard for Support Stack"
networks:
tsysdevstack_supportstack_network:
external: true
name: tsysdevstack_supportstack_network

View File

@@ -1,51 +0,0 @@
services:
wakaapi:
image: n1try/wakapi:latest
container_name: tsysdevstack-wakaapi
restart: unless-stopped
networks:
- tsysdevstack_supportstack_network
ports:
- "127.0.0.1:4001:3000"
environment:
- WAKAPI_PASSWORD_SALT=TSYSDevStackSupportStackDemoSalt12345678
- WAKAPI_DB_TYPE=sqlite3
- WAKAPI_DB_NAME=/data/wakapi.db
- WAKAPI_PORT=3000
- WAKAPI_PUBLIC_URL=http://127.0.0.1:4001
- WAKAPI_ALLOW_SIGNUP=true
- WAKAPI_WAKATIME_API_KEY=${WAKAAPI_WAKATIME_API_KEY:-""}
volumes:
- wakaapi_data:/data
mem_limit: 192m
mem_reservation: 128m
deploy:
resources:
limits:
cpus: '0.3'
memory: 192M
reservations:
cpus: '0.2'
memory: 128M
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/api"]
interval: 30s
timeout: 10s
start_period: 60s # Longer start period for wakaapi
retries: 5
# Homepage integration labels for automatic discovery
labels:
homepage.group: "Development Tools"
homepage.name: "WakaAPI"
homepage.icon: "wakatime.png"
homepage.href: "http://127.0.0.1:4001"
homepage.description: "WakaTime API for coding metrics"
networks:
tsysdevstack_supportstack_network:
external: true
name: tsysdevstack_supportstack_network
volumes:
wakaapi_data:
name: wakaapi_data
external: true

View File

@@ -0,0 +1,49 @@
services:
docker-socket-proxy:
image: ${DOCKER_SOCKET_PROXY_IMAGE}
container_name: ${DOCKER_SOCKET_PROXY_NAME}
restart: unless-stopped
networks:
- tsysdevstack_supportstack_network
environment:
CONTAINERS: ${DOCKER_SOCKET_PROXY_CONTAINERS}
IMAGES: ${DOCKER_SOCKET_PROXY_IMAGES}
NETWORKS: ${DOCKER_SOCKET_PROXY_NETWORKS}
VOLUMES: ${DOCKER_SOCKET_PROXY_VOLUMES}
BUILD: ${DOCKER_SOCKET_PROXY_BUILD}
MANIFEST: ${DOCKER_SOCKET_PROXY_MANIFEST}
PLUGINS: ${DOCKER_SOCKET_PROXY_PLUGINS}
VERSION: ${DOCKER_SOCKET_PROXY_VERSION}
volumes:
- ${DOCKER_SOCKET_PROXY_SOCKET_PATH}:${DOCKER_SOCKET_PROXY_SOCKET_PATH}
mem_limit: ${DOCKER_SOCKET_PROXY_MEM_LIMIT}
mem_reservation: ${DOCKER_SOCKET_PROXY_MEM_LIMIT}
deploy:
resources:
limits:
cpus: '${DOCKER_SOCKET_PROXY_CPU_LIMIT}'
memory: ${DOCKER_SOCKET_PROXY_MEM_LIMIT}
reservations:
cpus: '${DOCKER_SOCKET_PROXY_CPU_LIMIT}'
memory: ${DOCKER_SOCKET_PROXY_MEM_LIMIT}
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
interval: ${HEALTH_CHECK_INTERVAL}
timeout: ${HEALTH_CHECK_TIMEOUT}
start_period: ${HEALTH_CHECK_START_PERIOD}
retries: ${HEALTH_CHECK_RETRIES}
# Homepage integration labels for automatic discovery
labels:
homepage.group: "Support Stack"
homepage.name: "Docker Socket Proxy"
homepage.icon: "docker.png"
homepage.href: "http://${BIND_ADDRESS}:${HOMEPAGE_PORT}"
homepage.description: "Docker socket proxy for secure access"
homepage.type: "docker"
# NOTE: Docker-socket-proxy must run as root to configure HAProxy
# user: "${TSYSDEVSTACK_UID}:${TSYSDEVSTACK_DOCKER_GID}" # Read-only access to Docker socket
networks:
tsysdevstack_supportstack_network:
external: true
name: ${TSYSDEVSTACK_NETWORK_NAME}

View File

@@ -0,0 +1,47 @@
services:
homepage:
image: ${HOMEPAGE_IMAGE}
container_name: ${HOMEPAGE_NAME}
restart: unless-stopped
networks:
- tsysdevstack_supportstack_network
ports:
- "${BIND_ADDRESS}:${HOMEPAGE_PORT}:3000"
environment:
- PORT=3000
- HOMEPAGE_URL=http://${BIND_ADDRESS}:${HOMEPAGE_PORT}
- BASE_URL=http://${BIND_ADDRESS}:${HOMEPAGE_PORT}
- HOMEPAGE_ALLOWED_HOSTS=${BIND_ADDRESS}:${HOMEPAGE_PORT},localhost:${HOMEPAGE_PORT}
volumes:
- ${HOMEPAGE_CONFIG_PATH}:/app/config
- ${DOCKER_SOCKET_PROXY_SOCKET_PATH}:${DOCKER_SOCKET_PROXY_SOCKET_PATH}:ro # For Docker integration
mem_limit: ${HOMEPAGE_MEM_LIMIT}
mem_reservation: ${HOMEPAGE_MEM_LIMIT}
deploy:
resources:
limits:
cpus: '${HOMEPAGE_CPU_LIMIT}'
memory: ${HOMEPAGE_MEM_LIMIT}
reservations:
cpus: '${HOMEPAGE_CPU_LIMIT}'
memory: ${HOMEPAGE_MEM_LIMIT}
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/api/health"]
interval: ${HEALTH_CHECK_INTERVAL}
timeout: ${HEALTH_CHECK_TIMEOUT}
start_period: ${HOMEPAGE_STARTUP_TIMEOUT} # Longer start period for homepage
retries: ${HEALTH_CHECK_RETRIES}
# Homepage integration labels for automatic discovery
labels:
homepage.group: "Support Stack"
homepage.name: "Homepage Dashboard"
homepage.icon: "homepage.png"
homepage.href: "http://${BIND_ADDRESS}:${HOMEPAGE_PORT}"
homepage.description: "Homepage dashboard for Support Stack"
homepage.type: "homepage"
user: "${TSYSDEVSTACK_UID}:${TSYSDEVSTACK_DOCKER_GID}" # Direct access to Docker socket for discovery
networks:
tsysdevstack_supportstack_network:
external: true
name: ${TSYSDEVSTACK_NETWORK_NAME}

View File

@@ -0,0 +1,53 @@
services:
wakaapi:
image: ${WAKAAPI_IMAGE}
container_name: ${WAKAAPI_NAME}
restart: unless-stopped
networks:
- tsysdevstack_supportstack_network
ports:
- "${BIND_ADDRESS}:${WAKAAPI_PORT}:3000"
environment:
- WAKAPI_PASSWORD_SALT=TSYSDevStackSupportStackDemoSalt12345678
- WAKAPI_DB_TYPE=sqlite3
- WAKAPI_DB_NAME=/data/wakapi.db
- WAKAPI_PORT=3000
- WAKAPI_PUBLIC_URL=http://${BIND_ADDRESS}:${WAKAAPI_PORT}
- WAKAPI_ALLOW_SIGNUP=true
- WAKAPI_WAKATIME_API_KEY=${WAKAAPI_WAKATIME_API_KEY:-""}
volumes:
- wakaapi_data:/data
mem_limit: ${WAKAAPI_MEM_LIMIT}
mem_reservation: ${WAKAAPI_MEM_LIMIT}
deploy:
resources:
limits:
cpus: '${WAKAAPI_CPU_LIMIT}'
memory: ${WAKAAPI_MEM_LIMIT}
reservations:
cpus: '${WAKAAPI_CPU_LIMIT}'
memory: ${WAKAAPI_MEM_LIMIT}
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/api"]
interval: ${HEALTH_CHECK_INTERVAL}
timeout: ${HEALTH_CHECK_TIMEOUT}
start_period: ${WAKAAPI_INITIALIZATION_TIMEOUT} # Longer start period for wakaapi
retries: ${HEALTH_CHECK_RETRIES}
# Homepage integration labels for automatic discovery
labels:
homepage.group: "Development Tools"
homepage.name: "WakaAPI"
homepage.icon: "wakapi.png"
homepage.href: "http://${BIND_ADDRESS}:${WAKAAPI_PORT}"
homepage.description: "WakaTime API for coding metrics"
homepage.type: "wakapi"
user: "${TSYSDEVSTACK_UID}" # Regular user access for non-Docker containers
networks:
tsysdevstack_supportstack_network:
external: true
name: ${TSYSDEVSTACK_NETWORK_NAME}
volumes:
wakaapi_data:
name: ${WAKAAPI_NAME}_data
external: true

View File

@@ -7,8 +7,7 @@ set -e
# Load environment settings
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CONFIG_DIR="${SCRIPT_DIR}/config"
ENV_FILE="${CONFIG_DIR}/TSYSDevStack-SupportStack-Demo-Settings"
ENV_FILE="${SCRIPT_DIR}/TSYSDevStack-SupportStack-Demo-Settings"
if [ ! -f "$ENV_FILE" ]; then
echo "Error: Environment settings file not found at $ENV_FILE"
@@ -22,10 +21,14 @@ test_docker_socket_proxy() {
echo "Testing docker-socket-proxy availability and functionality..."
# Check if the container exists and is running
echo "Looking for container: $DOCKER_SOCKET_PROXY_NAME"
if docker ps | grep -q "$DOCKER_SOCKET_PROXY_NAME"; then
echo "✓ docker-socket-proxy container is running"
else
echo "✗ docker-socket-proxy container is NOT running"
# Check if another container with similar name is running
echo "Checking all containers:"
docker ps | grep -i docker
return 1
fi

View File

@@ -7,8 +7,7 @@ set -e
# Load environment settings
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CONFIG_DIR="${SCRIPT_DIR}/config"
ENV_FILE="${CONFIG_DIR}/TSYSDevStack-SupportStack-Demo-Settings"
ENV_FILE="${SCRIPT_DIR}/TSYSDevStack-SupportStack-Demo-Settings"
if [ ! -f "$ENV_FILE" ]; then
echo "Error: Environment settings file not found at $ENV_FILE"

View File

@@ -7,8 +7,7 @@ set -e
# Load environment settings
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CONFIG_DIR="${SCRIPT_DIR}/config"
ENV_FILE="${CONFIG_DIR}/TSYSDevStack-SupportStack-Demo-Settings"
ENV_FILE="${SCRIPT_DIR}/TSYSDevStack-SupportStack-Demo-Settings"
if [ ! -f "$ENV_FILE" ]; then
echo "Error: Environment settings file not found at $ENV_FILE"

View File

@@ -0,0 +1,37 @@
#!/bin/bash
# Test to verify WakaAPI is discovered and displayed on homepage
# Following TDD: Write test → Execute test → Test fails → Write minimal code to pass test
set -e
echo "Testing WakaAPI discovery on homepage..."
# Check if WakaAPI container is running
if ! docker ps | grep -q "tsysdevstack-wakaapi"; then
echo "❌ WakaAPI container is not running"
exit 1
fi
# Check if homepage container is running
if ! docker ps | grep -q "tsysdevstack-homepage"; then
echo "❌ Homepage container is not running"
exit 1
fi
# Test if we can access WakaAPI directly
if ! curl -f -s "http://127.0.0.1:4001/" > /dev/null 2>&1; then
echo "❌ WakaAPI is not accessible at http://127.0.0.1:4001"
exit 1
fi
# Check if WakaAPI appears on the homepage
content=$(curl -s http://127.0.0.1:4000/)
if [[ "$content" == *"WakaAPI"* ]] || [[ "$content" == *"wakaapi"* ]] || [[ "$content" == *"wakapi"* ]]; then
echo "✅ WakaAPI is displayed on homepage"
exit 0
else
echo "❌ WakaAPI is NOT displayed on homepage"
echo "Test failed: WakaAPI not discovered by homepage"
exit 1
fi

View File

@@ -0,0 +1,14 @@
{
"name": "TSYSDevStack Toolbox Base",
"dockerComposeFile": [
"../docker-compose.yml"
],
"service": "toolbox-base",
"workspaceFolder": "/workspace",
"remoteUser": "toolbox",
"runServices": [
"toolbox-base"
],
"overrideCommand": false,
"postCreateCommand": "zsh -lc 'starship --version >/dev/null'"
}

View File

@@ -0,0 +1,80 @@
FROM ubuntu:24.04
ARG USER_ID=1000
ARG GROUP_ID=1000
ARG USERNAME=toolbox
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
fish \
fzf \
git \
jq \
locales \
openssh-client \
ripgrep \
tmux \
fd-find \
bat \
wget \
zsh \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Provide common aliases for fd and bat binaries
RUN ln -sf /usr/bin/fdfind /usr/local/bin/fd \
&& ln -sf /usr/bin/batcat /usr/local/bin/bat
# Configure locale to ensure consistent tool behavior
RUN locale-gen en_US.UTF-8
ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8
# Install Starship prompt
RUN curl -fsSL https://starship.rs/install.sh | sh -s -- -y -b /usr/local/bin
# Install aqua package manager (manages additional CLI tooling)
RUN curl -sSfL https://raw.githubusercontent.com/aquaproj/aqua-installer/v2.3.1/aqua-installer | AQUA_ROOT_DIR=/usr/local/share/aquaproj-aqua bash \
&& ln -sf /usr/local/share/aquaproj-aqua/bin/aqua /usr/local/bin/aqua
# Create non-root user with matching UID/GID for host mapping
RUN if getent passwd "${USER_ID}" >/dev/null; then \
existing_user="$(getent passwd "${USER_ID}" | cut -d: -f1)"; \
userdel --remove "${existing_user}"; \
fi \
&& if ! getent group "${GROUP_ID}" >/dev/null; then \
groupadd --gid "${GROUP_ID}" "${USERNAME}"; \
fi \
&& useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}"
# Install Oh My Zsh for the unprivileged user
RUN su - "${USERNAME}" -c 'git clone --depth=1 https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zsh' \
&& su - "${USERNAME}" -c 'cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc' \
&& su - "${USERNAME}" -c 'mkdir -p ~/.config' \
&& su - "${USERNAME}" -c 'sed -i "s/^plugins=(git)$/plugins=(git fzf)/" ~/.zshrc' \
&& su - "${USERNAME}" -c 'printf "\nexport PATH=\"\$HOME/.local/share/aquaproj-aqua/bin:\$HOME/.local/bin:\$PATH\"\n" >> ~/.zshrc' \
&& su - "${USERNAME}" -c 'printf "\n# Starship prompt\neval \"\$(starship init zsh)\"\n" >> ~/.zshrc'
COPY aqua.yaml /tmp/aqua.yaml
RUN chown "${USER_ID}:${GROUP_ID}" /tmp/aqua.yaml \
&& su - "${USERNAME}" -c 'mkdir -p ~/.config/aquaproj-aqua' \
&& su - "${USERNAME}" -c 'cp /tmp/aqua.yaml ~/.config/aquaproj-aqua/aqua.yaml' \
&& su - "${USERNAME}" -c 'AQUA_GLOBAL_CONFIG=~/.config/aquaproj-aqua/aqua.yaml aqua install'
# Prepare workspace directory with appropriate ownership
RUN mkdir -p /workspace \
&& chown "${USER_ID}:${GROUP_ID}" /workspace
ENV SHELL=/usr/bin/zsh \
PATH=/home/${USERNAME}/.local/share/aquaproj-aqua/bin:/home/${USERNAME}/.local/bin:${PATH}
WORKDIR /workspace
USER ${USERNAME}
CMD ["/usr/bin/zsh"]

View File

@@ -0,0 +1,8 @@
version: 1.0.0
registries:
- type: standard
ref: v4.200.0
packages:
- name: cli/cli@latest
- name: go-gitea/tea@latest
- name: jesseduffield/lazygit@latest

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail
IMAGE_NAME="tsysdevstack-toolboxstack-toolbox-base"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
USER_ID="${USER_ID_OVERRIDE:-$(id -u)}"
GROUP_ID="${GROUP_ID_OVERRIDE:-$(id -g)}"
USERNAME="${USERNAME_OVERRIDE:-toolbox}"
echo "Building ${IMAGE_NAME} with UID=${USER_ID} GID=${GROUP_ID} USERNAME=${USERNAME}"
docker build \
--build-arg USER_ID="${USER_ID}" \
--build-arg GROUP_ID="${GROUP_ID}" \
--build-arg USERNAME="${USERNAME}" \
--tag "${IMAGE_NAME}" \
"${SCRIPT_DIR}"

View File

@@ -0,0 +1,18 @@
services:
toolbox-base:
container_name: tsysdevstack-toolboxstack-toolbox-base
image: tsysdevstack-toolboxstack-toolbox-base
build:
context: .
args:
USER_ID: ${LOCAL_UID:-1000}
GROUP_ID: ${LOCAL_GID:-1000}
USERNAME: ${LOCAL_USERNAME:-toolbox}
user: "${LOCAL_UID:-1000}:${LOCAL_GID:-1000}"
working_dir: /workspace
command: ["sleep", "infinity"]
init: true
tty: true
stdin_open: true
volumes:
- .:/workspace:rw

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.yml"
export LOCAL_UID="${USER_ID_OVERRIDE:-$(id -u)}"
export LOCAL_GID="${GROUP_ID_OVERRIDE:-$(id -g)}"
export LOCAL_USERNAME="${USERNAME_OVERRIDE:-toolbox}"
if [[ ! -f "${COMPOSE_FILE}" ]]; then
echo "Error: docker-compose.yml not found at ${COMPOSE_FILE}" >&2
exit 1
fi
ACTION="${1:-up}"
shift || true
case "${ACTION}" in
up)
docker compose -f "${COMPOSE_FILE}" up --build --detach "$@"
;;
down)
docker compose -f "${COMPOSE_FILE}" down "$@"
;;
*)
echo "Usage: $0 [up|down] [additional docker compose args]" >&2
exit 1
;;
esac