sha256:4fa8a0eb8c09235b0aa027588a3a28451290bd3a013327a79622cf0b36a92744
Last pushed
4 months by ams0
Type
Compose
Manifest digest
sha256:4fa8a0eb8c09235b0aa027588a3a28451290bd3a013327a79622cf0b36a92744
##################################################################################################
# This Compose file is intended to run a Labspace. It can be run with the following:
#
# CONTENT_REPO_URL=https://github.com/username/labspace-content-repo docker compose -f compose.run.yaml up
##################################################################################################
services:
configurator:
image: dockersamples/labspace-configurator:v0.26.0
use_api_socket: true
volumes:
- labspace-content:/project
- labspace-instructions:/instructions
- docker-creds:/docker-creds
- labspace-support:/etc/labspace-support
interface:
image: dockersamples/labspace-interface:v0.26.0
ports:
- "3030:3030"
volumes:
- labspace-instructions:/labspace/instructions:ro
- type: volume
source: labspace-support
target: /etc/labspace-support/private-key
volume:
subpath: private-key
- type: volume
source: labspace-support
target: /etc/labspace-support/socket
volume:
subpath: socket
- type: volume
source: labspace-support
target: /etc/labspace-support/metadata
volume:
subpath: metadata
depends_on:
workspace:
condition: service_started
configurator:
condition: service_completed_successfully
restart: unless-stopped
workspace:
image: dockersamples/labspace-workspace-node:v0.26.0
depends_on:
configurator:
condition: service_completed_successfully
socket-proxy:
condition: service_started
ports:
- 8085:8085 # For the IDE itself
- 3000:3000 # For the Node application running in the IDE
volumes:
- socket-proxy:/var/run
- labspace-content:/home/coder/project
- docker-creds:/docker-creds
- type: volume
source: labspace-support
target: /etc/labspace-support/public-key
volume:
subpath: public-key
- type: volume
source: labspace-support
target: /etc/labspace-support/socket
volume:
subpath: socket
host-republisher:
image: dockersamples/labspace-host-port-republisher:v0.26.0
pull_policy: always
restart: always
volumes:
- socket-proxy:/var/run
network_mode: service:workspace
environment:
LABEL_FILTER: labspace-resource=true
depends_on:
- workspace
- socket-proxy
workspace-cleaner:
image: dockersamples/labspace-cleaner:v0.26.0
pull_policy: always
volumes:
- socket-proxy:/var/run
environment:
LABEL_FILTER: labspace-resource=true
depends_on:
- socket-proxy
socket-proxy:
image: mikesir87/docker-socket-proxy:v1.3.1
volumes:
- socket-proxy:/tmp/proxy
- /var/run/docker.sock:/var/run/docker.sock
configs:
- source: docker-proxy-config-labels
target: /etc/docker-socket-proxy/config.d/add-and-require-labels.yaml
- source: docker-proxy-mount-remap
target: /etc/docker-socket-proxy/config.d/mount-path-remap.yaml
- source: docker-proxy-mount-allowlist
target: /etc/docker-socket-proxy/config.d/mount-path-allowlist.yaml
- source: docker-proxy-forward-proxied-socket
target: /etc/docker-socket-proxy/config.d/forward-proxied-socket.yaml
- source: docker-proxy-add-to-labspace-network
target: /etc/docker-socket-proxy/config.d/add-to-labspace-network.yaml
environment:
DEBUG_LOGS: "true"
LISTEN_SOCKET_PATH: /tmp/proxy/docker.sock
volumes:
socket-proxy:
name: labspace-socket-proxy
labspace-content:
name: labspace-content
labspace-instructions:
docker-creds:
labspace-support:
networks:
default:
name: labspace
configs:
docker-proxy-config-labels:
content: |
mutators:
# Add labels to all newly created objects
- type: addLabels
labels:
labspace-resource: "true"
responseFilters:
# Only return objects with the labels we mutated on
- type: labelFilter
objectsToFilter:
- containers
- volumes
- networks
requiredLabels:
labspace-resource: "true"
docker-proxy-mount-remap:
content: |
# Remap the project directory to the labspace content volume, since the project
# is running out of a volume.
mutators:
- type: mountPath
from: /home/coder/project
to: labspace-content
docker-proxy-mount-allowlist:
content: |
gates:
- type: mountSource
allowedSources:
- labspace-content
- labspace-socket-proxy
- buildx_buildkit_default_state
- label:labspace-resource=true
docker-proxy-forward-proxied-socket:
content: |
# If requests to use the Docker Socket are used (such as Testcontainers),
# use the proxied one to ensure permissions, remappings, etc. are applied
mutators:
- type: mountPath
from: /var/run/docker.sock
to: labspace-socket-proxy/docker.sock
docker-proxy-add-to-labspace-network:
content: |
mutators:
- type: addToNetwork
networks:
- labspace
---
#########################################################################
# This Compose file extends the default Labspace setup by adding the following elements:
#
# - A Traefik reverse proxy to route traffic to Gitea and k3s
# - A Gitea server for Git hosting and CI/CD
# - A Gitea self-hosted runner for executing CI jobs
# - A k3s Kubernetes cluster
#
# This provides a "SDLC-in-a-box" environment for end-to-end labs.
#
# Additional documentation is found in the docs/sdlc-labspace.md file.
#########################################################################
services:
############################################################
# Overrides to Labspace default services
############################################################
workspace:
environment:
SKIP_CI_SECRET_SETUP: ${SKIP_CI_SECRET_SETUP:-false}
volumes:
- gitea-outputs:/gitea-outputs:ro
- k3s-output:/kubeconfig:ro
- type: volume
source: labspace-support
target: /etc/labspace-support/k8s-setup
volume:
subpath: k8s-setup
configs:
- source: workspace-entrypoint-script
target: /entrypoint.d/50-entrypoint-script.sh
mode: 0755
- source: workspace-wait-for-bootstrap
target: /startup-scripts/00-wait-for-bootstrap.sh
mode: 0755
- source: workspace-ci-secrets
target: /startup-scripts/10-ci-secrets.sh
mode: 0755
- source: workspace-kubeconfig-setup
target: /startup-scripts/10-kubeconfig-setup.sh
mode: 0755
- source: workspace-git-setup
target: /startup-scripts/20-git-setup.sh
mode: 0755
- source: workspace-configure-k3s-coredns
target: /startup-scripts/15-configure-k3s-coredns.sh
mode: 0755
depends_on:
git:
condition: service_healthy
k3s:
condition: service_healthy
zone-file-creator:
condition: service_completed_successfully
interface:
labels:
- "traefik.enable=true"
- "traefik.http.routers.interface.rule=Host(`dockerlabs.xyz`)"
- "traefik.http.routers.interface.entrypoints=web"
- "traefik.http.routers.interface.service=interface"
- "traefik.http.services.interface.loadbalancer.server.port=3030"
############################################################
# New services
############################################################
cert-creator:
image: alpine
command: /generate-certs.sh
configs:
- source: generate-traefik-certs
target: /generate-certs.sh
mode: 0755
volumes:
- labspace-traefik-certs:/certs
zone-file-creator:
image: dhi.io/wbitt-network-multitool:3-alpine3.23-dev
command: /create-zone-file.sh
configs:
- source: create-zone-file
target: /create-zone-file.sh
mode: 0755
volumes:
- labspace-support:/labspace-support
depends_on:
traefik:
condition: service_started
traefik:
image: traefik:3.6.13
command:
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.ssh.address=:22
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls=true
- --providers.file.filename=/etc/traefik/cert-config.yaml
ports:
- "22:22"
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- labspace-traefik-certs:/certs:ro
configs:
- source: traefik-cert-config
target: /etc/traefik/cert-config.yaml
networks:
default:
aliases:
- git.dockerlabs.xyz
- registry.dockerlabs.xyz
- app.dockerlabs.xyz
depends_on:
cert-creator:
condition: service_completed_successfully
registry:
image: ghcr.io/project-zot/zot:v2.1.15
labels:
traefik.enable: true
traefik.http.routers.registry.rule: Host(`registry.dockerlabs.xyz`)
traefik.http.services.registry.loadbalancer.server.port: "5000"
traefik.http.middlewares.remove-frame-headers.headers.customresponseheaders.X-Frame-Options: ""
traefik.http.routers.registry.middlewares: remove-frame-headers
git:
image: gitea/gitea:1.25.5
volumes:
- gitea-data:/data
- gitea-outputs:/gitea-outputs
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
configs:
- source: gitea-bootstrap
target: /etc/gitea/bootstrap.sh
mode: 0755
environment:
GITEA__server__ROOT_URL: http://git.dockerlabs.xyz/
GITEA__server__SSH_DOMAIN: git.dockerlabs.xyz
GITEA__server__SSH_LISTEN_PORT: 22
GITEA__database__DB_TYPE: sqlite3
# This prevents the first-time install page from showing (setup is done via script/env vars)
GITEA__security__INSTALL_LOCK: "true"
labels:
traefik.enable: "true"
traefik.http.routers.git.rule: Host(`git.dockerlabs.xyz`)
traefik.http.routers.git.entrypoints: web
traefik.http.routers.git.service: git
traefik.http.services.git.loadbalancer.server.port: "3000"
traefik.http.middlewares.remove-frame-headers.headers.customresponseheaders.X-Frame-Options: ""
traefik.http.routers.git.middlewares: remove-frame-headers
traefik.http.routers.git-secure.rule: Host(`git.dockerlabs.xyz`)
traefik.http.routers.git-secure.entrypoints: websecure
traefik.http.routers.git-secure.service: git
traefik.tcp.routers.git-ssh.rule: HostSNI(`*`)
traefik.tcp.routers.git-ssh.entrypoints: ssh
traefik.tcp.routers.git-ssh.service: git-ssh
traefik.tcp.services.git-ssh.loadbalancer.server.port: "22"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/healthz"]
interval: 10s
timeout: 10s
retries: 3
start_period: 5s
post_start:
- command: bash /etc/gitea/bootstrap.sh
user: root
gitea-runner:
image: gitea/act_runner:0.3.1
entrypoint: []
command: bash -c "GITEA_RUNNER_REGISTRATION_TOKEN=$(cat /gitea-outputs/runner_token.txt) /sbin/tini -- run.sh"
volumes:
- type: volume
source: socket-proxy
target: /var/run/docker.sock
volume:
subpath: docker.sock
- gitea-outputs:/gitea-outputs
environment:
GITEA_INSTANCE_URL: http://git.dockerlabs.xyz
GITEA_RUNNER_NAME: labspace-runner
# The runner uses 1.41 Docker API by default, but we need 1.45+ when using the socket proxy
# due to volume rewrites using volume subpaths
DOCKER_API_VERSION: "1.45"
depends_on:
git:
condition: service_healthy
k3s:
# When updating the k8s version, ensure the kubectl version in the base workspace image is updated
image: rancher/k3s:v1.35.3-k3s1
command: server --tls-san k8s.dockerlabs.xyz
privileged: true
volumes:
- k3s-server:/var/lib/rancher/k3s
- k3s-output:/output
environment:
- K3S_TOKEN=labspace-k3s-token
- K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml
- K3S_KUBECONFIG_MODE=666
tmpfs:
- /run
- /var/run
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
networks:
default:
aliases:
- k8s.dockerlabs.xyz
configs:
- source: k3s-registry-config
target: /etc/rancher/k3s/registries.yaml
labels:
- "traefik.enable=true"
- "traefik.http.routers.prod-app.rule=Host(`app.dockerlabs.xyz`)"
- "traefik.http.routers.prod-app.entrypoints=web"
- "traefik.http.routers.prod-app.service=prod-app"
- "traefik.http.services.prod-app.loadbalancer.server.port=80"
healthcheck:
test: ["CMD", "kubectl", "get", "--raw", "/readyz"]
interval: 10s
timeout: 10s
retries: 10
start_period: 20s
volumes:
gitea-data:
gitea-outputs:
k3s-server:
k3s-output:
labspace-traefik-certs:
configs:
# Generate the certs for Traefik to use
generate-traefik-certs:
content: |
#!/bin/sh
apk add --no-cache openssl >/dev/null 2>&1 || true;
mkdir -p /certs/ca
if [ -f /certs/dockerlabs.crt ] && [ -f /certs/dockerlabs.key ]; then
echo 'Certs already exist, skipping generation';
return
fi
# Create CA (one-time)
if [ ! -f /certs/ca/ca.crt ] || [ ! -f /certs/ca/ca.key ]; then
openssl genrsa -out /certs/ca/ca.key 4096
openssl req -x509 -new -nodes -key /certs/ca/ca.key -sha256 -days 3650 \
-subj "/CN=dockerlabs-local-ca" \
-out /certs/ca/ca.crt
fi
# Create leaf key + CSR
openssl genrsa -out /certs/dockerlabs.key 4096
cat > /tmp/leaf.cnf <<'CNF'
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
CN = dockerlabs.xyz
[v3_req]
subjectAltName = @alt_names
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[alt_names]
DNS.1 = dockerlabs.xyz
DNS.2 = *.dockerlabs.xyz
CNF
openssl req -new -key /certs/dockerlabs.key -out /tmp/dockerlabs.csr -config /tmp/leaf.cnf
# Sign leaf cert with CA
openssl x509 -req -in /tmp/dockerlabs.csr \
-CA /certs/ca/ca.crt -CAkey /certs/ca/ca.key -CAcreateserial \
-out /certs/dockerlabs.crt -days 825 -sha256 \
-extfile /tmp/leaf.cnf -extensions v3_req
# combine cert & key into a PEM (optional)
cat /certs/dockerlabs.crt /certs/dockerlabs.key > /certs/dockerlabs.pem || true;
echo 'Generated CA and certificates';
find /certs -type f
# Traefik configuration to use the generated certs
traefik-cert-config:
content: |
tls:
certificates:
- certFile: /certs/dockerlabs.crt
keyFile: /certs/dockerlabs.key
stores:
default:
defaultCertificate:
certFile: /certs/dockerlabs.crt
keyFile: /certs/dockerlabs.key
# Override the default allow list to add buildkit builders and the gitea volumes
docker-proxy-mount-allowlist:
content: |
gates:
- type: mountSource
allowedSources:
- labspace-content
- labspace-socket-proxy
- buildx_buildkit_default_state
- buildx_buildkit_builder-*
- label:labspace-resource=true
- act-toolcache
- GITEA*
# The /entrypoint.d hook in code-server does not guarantee order of execution, as it simply uses `find` to get files in the
# directory. To ensure our scripts run in the correct order, we prefix them with numbers and use a custom entrypoint script
# to sort and execute the scripts in order.
workspace-entrypoint-script:
content: |
#!/bin/sh
set -eu
CUSTOM_DIR="/startup-scripts"
# Nothing to do if the directory doesn't exist
[ -d "$$CUSTOM_DIR" ] || exit 0
# Find executable regular files, sort them, and run one by one
find "$$CUSTOM_DIR" -type f -executable -print \
| sort \
| while IFS= read -r script; do
echo "→ Running $$script"
"$$script"
done
# Waits for the Gitea bootstrap to complete before allowing other startup scripts to proceed.
# Validates that the moby user exists and the SSH key is registered, which are the last steps
# of the bootstrap and gate everything the workspace startup scripts depend on.
workspace-wait-for-bootstrap:
content: |
#!/bin/bash
echo "Waiting for Gitea bootstrap to complete..."
until curl -sf -u 'moby:moby1234' http://git.dockerlabs.xyz/api/v1/user > /dev/null 2>&1; do
echo "Waiting for moby user to be ready..."
sleep 2
done
echo "moby user is ready."
until curl -s -u 'moby:moby1234' http://git.dockerlabs.xyz/api/v1/user/keys | grep -q '"moby-key"'; do
echo "Waiting for SSH key to be registered..."
sleep 2
done
echo "SSH key is registered. Bootstrap complete."
# Creates all CI secrets in the Gitea repo. Can be skipped by setting SKIP_CI_SECRET_SETUP=true,
# which is useful for labs that guide users through creating the secrets themselves.
workspace-ci-secrets:
content: |
#!/bin/bash
if [ "$$SKIP_CI_SECRET_SETUP" = "true" ]; then
echo "SKIP_CI_SECRET_SETUP is set. Skipping CI secret creation."
exit 0
fi
SECRETS_JSON=$(curl -s -u 'moby:moby1234' http://git.dockerlabs.xyz/api/v1/repos/moby/demo-app/actions/secrets)
# Create Gitea registry secrets
if echo "$$SECRETS_JSON" | grep -q '"DOCKER_USERNAME"'; then
echo "Gitea registry secrets already exist. Skipping."
else
curl -s -u 'moby:moby1234' -X PUT http://git.dockerlabs.xyz/api/v1/repos/moby/demo-app/actions/secrets/DOCKER_USERNAME -H "Content-Type: application/json" -d '{"data":"moby"}'
curl -s -u 'moby:moby1234' -X PUT http://git.dockerlabs.xyz/api/v1/repos/moby/demo-app/actions/secrets/DOCKER_PASSWORD -H "Content-Type: application/json" -d '{"data":"moby1234"}'
curl -s -u 'moby:moby1234' -X PUT http://git.dockerlabs.xyz/api/v1/repos/moby/demo-app/actions/secrets/DOCKER_REGISTRY -H "Content-Type: application/json" -d '{"data":"registry.dockerlabs.xyz"}'
echo "Gitea registry secrets created."
fi
# Create Docker Hub secrets
if echo "$$SECRETS_JSON" | grep -q '"DOCKERHUB_USERNAME"'; then
echo "Docker Hub secrets already exist. Skipping."
else
HUB_AUTH=$(jq '.auths."https://index.docker.io/v1/".auth' -r ~/.docker/config.json | base64 -d -)
USERNAME=$(echo $$HUB_AUTH | cut -d: -f1)
TOKEN=$(echo $$HUB_AUTH | cut -d: -f2)
curl -s -u 'moby:moby1234' -X PUT http://git.dockerlabs.xyz/api/v1/repos/moby/demo-app/actions/secrets/DOCKERHUB_USERNAME -H "Content-Type: application/json" -d '{"data":"'"$$USERNAME"'"}'
curl -s -u 'moby:moby1234' -X PUT http://git.dockerlabs.xyz/api/v1/repos/moby/demo-app/actions/secrets/DOCKERHUB_PASSWORD -H "Content-Type: application/json" -d '{"data":"'"$$TOKEN"'"}'
echo "Docker Hub secrets created."
unset HUB_AUTH
unset USERNAME
unset TOKEN
fi
# Create KUBECONFIG secret
if echo "$$SECRETS_JSON" | grep -q '"KUBECONFIG"'; then
echo "KUBECONFIG secret already exists. Skipping."
else
KUBE_CONFIG=$(cat /kubeconfig/kubeconfig.yaml | sed 's/127.0.0.1/k8s.dockerlabs.xyz/g')
curl -s -u 'moby:moby1234' -X PUT http://git.dockerlabs.xyz/api/v1/repos/moby/demo-app/actions/secrets/KUBECONFIG -H "Content-Type: application/json" -d '{"data":"'"$(echo -n "$$KUBE_CONFIG")"'"}'
echo "KUBECONFIG secret created."
fi
workspace-git-setup:
content: |
#!/bin/bash
# Configure the SSH key for git access
sudo mkdir -p /home/coder/.ssh
sudo cp /gitea-outputs/id_rsa /home/coder/.ssh/id_rsa
sudo cp /gitea-outputs/id_rsa.pub /home/coder/.ssh/id_rsa.pub
sudo chown -R coder:coder /home/coder/.ssh
# Setup git config
ssh-keyscan -H git.dockerlabs.xyz >> /home/coder/.ssh/known_hosts
git config --global init.defaultBranch main
git config --global user.name 'Moby'
git config --global user.email 'moby@local'
# Commit the initial Labspace project to the git repo
cd /home/coder/project
# Ensure .gitignore exists
touch .gitignore
# Function to safely append to gitignore
add_to_gitignore() {
local entry="$$1"
# Skip if entry already exists
if grep -qxF "$$entry" .gitignore 2>/dev/null; then
return
fi
# Ensure file ends with newline before appending (sed adds it if missing)
sed -i -e '$$a\' .gitignore 2>/dev/null || true
# Now append the entry
echo "$$entry" >> .gitignore
}
rm -rf .git
git init
git remote add origin [email protected]:moby/demo-app.git
git add -A
git commit -m 'Initial commit'
git push -u origin main
gitea-bootstrap:
content: |
#!/bin/bash
echo "Running"
while ! curl -sL http://localhost:3000/user/login > /dev/null; do
sleep 2
done
echo "Gitea is up - proceeding with bootstrap"
# Create the 'moby' user if it doesn't exist
users=$(su-exec git /usr/local/bin/gitea admin user list)
if echo "$$users" | grep -q '^moby '; then
echo "User 'moby' already exists. Skipping account creation."
else
su-exec git /usr/local/bin/gitea admin user create --username moby --password 'moby1234' --email admin@local --admin --must-change-password=false
while ! curl -sL -u 'moby:moby1234' http://localhost:3000/api/v1/user > /dev/null; do
echo "Waiting for user to be fully ready to use..."
sleep 2
done
fi
# Check if demo-app repo exists. Create it if it doesn't.
repo_status=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/api/v1/repos/moby/demo-app)
if [ "$$repo_status" = "404" ]; then
echo "Repository 'moby/demo-app' not found. Creating it..."
curl -s -H "Content-type: application/json" -u 'moby:moby1234' -d '{"name":"demo-app","private":false}' http://localhost:3000/api/v1/user/repos
echo "Repository 'moby/demo-app' created."
else
echo "Repository 'moby/demo-app' already exists. Skipping creation."
fi
# Get and store registration token for the runner
TOKEN_JSON=$(curl -s -u 'moby:moby1234' http://localhost:3000/api/v1/repos/moby/demo-app/actions/runners/registration-token)
REGISTRATION_TOKEN=$(echo $$TOKEN_JSON | grep -o '"token":"[^"]*"' | cut -d'"' -f4)
echo -n $$REGISTRATION_TOKEN > /gitea-outputs/runner_token.txt
# Create SSH key for user 'moby' if it doesn't exist
if [ ! -f /gitea-outputs/id_rsa ]; then
ssh-keygen -t rsa -b 4096 -N "" -f /gitea-outputs/id_rsa
echo "SSH key generated for user 'moby'."
fi
# Add the public key to the user's SSH keys via Gitea API if not already added
keys=$(curl -s -u 'moby:moby1234' http://localhost:3000/api/v1/user/keys)
if echo "$$keys" | grep -q "moby-key"; then
echo "SSH key already added to user 'moby'. Skipping key addition."
else
pub_key=$(cat /gitea-outputs/id_rsa.pub)
curl -s -u 'moby:moby1234' http://localhost:3000/api/v1/user/keys -H "Content-Type: application/json" -d "{\"title\":\"moby-key\",\"key\":\"$$pub_key\"}"
echo "SSH key added to user 'moby'."
fi
# Configure k3s with credentials and TLS settings for the Gitea registry
k3s-registry-config:
content: |
configs:
"registry.dockerlabs.xyz":
auth:
username: moby
password: moby1234
tls:
insecure_skip_verify: true
workspace-kubeconfig-setup:
content: |
#!/bin/bash
set -e
# Setup the kubeconfig for the coder user
mkdir -p ~/.kube
cat /kubeconfig/kubeconfig.yaml | sed 's/127.0.0.1/k8s.dockerlabs.xyz/g' > ~/.kube/config
create-zone-file:
content: |
#!/bin/sh
set -e
IP=$$(dig +short git.dockerlabs.xyz A | grep -E '^[0-9.]+$$' | head -n 1)
mkdir -p /labspace-support/k8s-setup
cat << EOF > /labspace-support/k8s-setup/zone-file-config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns-custom
namespace: kube-system
data:
dockerlabs-xyz.server: |
dockerlabs.xyz:53 {
log
errors
file /etc/coredns/custom/dockerlabs.xyz
}
dockerlabs.xyz: |
\$$ORIGIN dockerlabs.xyz.
\$$TTL 3600
@ IN SOA ns1.dockerlabs.xyz. hostmaster.dockerlabs.xyz. (
2026020601 ; serial (YYYYMMDDnn)
3600 ; refresh
900 ; retry
1209600 ; expire
3600 ; minimum
)
IN NS ns1.dockerlabs.xyz.
; A records
@ IN A $$IP
* IN A $$IP
EOF
workspace-configure-k3s-coredns:
content: |
#!/bin/bash
kubectl apply -f /etc/labspace-support/k8s-setup/zone-file-config-map.yaml
if kubectl -n kube-system get deployment coredns > /dev/null 2>&1; then
kubectl -n kube-system rollout restart deployment/coredns
fiservices:
configurator:
environment:
PROJECT_CLONE_URL: https://github.com/ams0/labspace-flux-gitops
configs:
project_source_tar:
content: |
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
services:
configurator:
configs:
- source: project_source_tar
target: /etc/labspace-support/content.tar.base64
environment:
PROJECT_TAR_PATH: /etc/labspace-support/content.tar.base64
docker compose -f oci://ams0/labspace-flux-gitops:latest upUse the above command to pull and run the Compose file. Learn more.
A minimal Docker image based on Alpine Linux with a complete package index and only 5 MB in size!
Pulls
1B+
Stars
11554
Last Updated
3 days
Traefik, The Cloud Native Edge Router
Pulls
1B+
Stars
3665
Last Updated
about 4 hours
Gitea: Git with a cup of tea - A painless self-hosted Git service.
Pulls
100M+
Stars
1057
Last Updated
2 days
Deprecated Gitea runner. Moved to gitea/runner
Pulls
5M+
Stars
34
Last Updated
5 months