@@ -0,0 +1,55 @@
|
||||
name: "Render stack"
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
TZ: UTC
|
||||
DOCKER_HOST: "tcp://docker:2375"
|
||||
DOCKER_TLS_VERIFY: ""
|
||||
|
||||
jobs:
|
||||
stack-test:
|
||||
runs-on: general
|
||||
container:
|
||||
image: ubuntu:24.04
|
||||
services:
|
||||
docker:
|
||||
image: docker:dind
|
||||
cmd:
|
||||
- "dockerd"
|
||||
- "-H" # we need this one to offer a docker socket to the job
|
||||
- "tcp://0.0.0.0:2375"
|
||||
- "-H" # we need this one to offer a docker socket on disk
|
||||
- "unix:///var/run/docker.sock"
|
||||
- "--tls=false"
|
||||
steps:
|
||||
# need to setup node and git
|
||||
- run: |
|
||||
apt-get update
|
||||
apt-get install -y nodejs git curl jq sops age
|
||||
# check out code
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false
|
||||
# setup docker
|
||||
- name: set up docker cli
|
||||
run: |
|
||||
apt-get install -y ca-certificates curl dnsutils
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||
chmod a+r /etc/apt/keyrings/docker.asc
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
|
||||
tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
apt-get update
|
||||
apt-get install docker-ce-cli docker-buildx-plugin docker-compose-plugin
|
||||
# render stack
|
||||
- name: Render stack
|
||||
run: |
|
||||
./render-stack.sh
|
||||
|
||||
- name: Cat
|
||||
run: |
|
||||
cat compose.prod.yaml
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
compose.prod.yaml
|
||||
@@ -1,3 +1,19 @@
|
||||
# deployment-source
|
||||
|
||||
Demo repo for deployment. This one is the source repo that contains the dynamic templates.
|
||||
Demo repo for deployment, for clevermicro repos and swarm-cd. This repo will demo how to render the stack file with encrypted secrects and how to commit to the target repo and make PR. This is all down by the pipeline.
|
||||
|
||||
The encrypted file is `prod-config.enc.yaml`. Currently it is encrypted by SOPS with AGE, here is the recipient list:
|
||||
|
||||
+ age1kj66pvftzmz7t7klnghacleymtmj2szckkc50dvq8yldqp2gavpsegrfvl (Rui Hu)
|
||||
+ age18rl4xxj6m55u44k82vwleurx5d5xhf5vj84n3ewg9rj5nh69rsjsjzqw66 (test key, the private key is `AGE-SECRET-KEY-1DEACUTGUPQWVPR29MVM3LV8JMW8RXS8A4UC2QGERN3VAQ225Z6XQN36C5D`, this is only for testing!!!)
|
||||
+ age18ust9l2rx59n9t6h9chpqvhm3j5kc9p75rpxefm83w95s7fqq59qxjzfuj (pipeline runner)
|
||||
|
||||
For VSC, use extension: https://marketplace.visualstudio.com/items/?itemName=signageos.signageos-vscode-sops to automatically
|
||||
decrypt the sops file, by placing your private age key in `~/.config/sops/age/keys.txt` (one private key per line, with `#` for comments).
|
||||
This is similar to `sops prod-config.enc.yaml` but instead of vm, you got vsc.
|
||||
|
||||
The script to render the stack file: `render-stack.sh`, it will call gomplate and renders the final stack file to `compose.prod.yaml`
|
||||
|
||||
Runner env var:
|
||||
|
||||
+ `SOPS_AGE_KEY`: The private key for container
|
||||
@@ -0,0 +1,7 @@
|
||||
inputDir: ./templates/
|
||||
outputDir: ./
|
||||
leftDelim: ((
|
||||
rightDelim: ))
|
||||
# allow others to read and write, workaround for docker permission
|
||||
chmod: 666
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
inputDir: /data/templates/
|
||||
outputDir: /data/
|
||||
leftDelim: ((
|
||||
rightDelim: ))
|
||||
# allow others to read and write, workaround for docker permission
|
||||
chmod: 666
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
whoami:
|
||||
port:
|
||||
http: ENC[AES256_GCM,data:0ac7Wg==,iv:auZwIXo9vvoLEtLGZYwyA/7xAaswdqIX8E/NYnFa3xQ=,tag:jke5bY+XLAxhjJwo0yr78A==,type:int]
|
||||
deployReplica: ENC[AES256_GCM,data:Nw==,iv:a2rBG4vu7ikoXLfWrVLk27leX9RIb4DhWR5HrbHQO5w=,tag:viN9V+fFnS18UpjdHA7Wkg==,type:int]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age1kj66pvftzmz7t7klnghacleymtmj2szckkc50dvq8yldqp2gavpsegrfvl
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkRjVyaitIZGlGU3QrMFdy
|
||||
Mm8zQ3JORVZ0anNsZDJWZkh3WWVFSy94ZkRjCkRoaGtXSmd6UEFvMEFMRW1BbVBz
|
||||
dW5iY1RNVmZNVnNNdFR4UHBwcDNOUUkKLS0tIE9ZTGJUUWMxT0NhZGdkbk83Rnd3
|
||||
UlhqYmdwV0dJcG92aTZ1SmovT2cveVUKgHGFMXTzan0dgfPo95388lrH1hMCbkos
|
||||
jKG8JZ22qZCWEWR3a6tiN1/aQZ6UJMfoFXQN0dcuwZ7gV4LmEQpW7Q==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age18rl4xxj6m55u44k82vwleurx5d5xhf5vj84n3ewg9rj5nh69rsjsjzqw66
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqK2YzQ2xHbmViblNlT2JF
|
||||
RDdrTVkyQzYwSlZVOXRmeVNzOXBoc2QyWmhjClhaWUxac3NqRUtwMFR3K0tiQjZV
|
||||
RnVmcVY0RG1iRFJ5SHU4NmtHc1dzQVkKLS0tIHozK2ZURmM1SEdveFQzYUtoRDVv
|
||||
SCtUbTFxWEVFbno4MldHaTNOUHdYRzQKz5lYkbOMNmKxIao0Kcx1s3xd6zJ4s+Kf
|
||||
xm5hzijlg78arsIGOJxmmrP/lkeQWLysWaF8IauAh0goZKymOjTh7A==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age18ust9l2rx59n9t6h9chpqvhm3j5kc9p75rpxefm83w95s7fqq59qxjzfuj
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOeWtDcDdIS3NvMDN3Q2li
|
||||
ZFF5Z3BoUG9TemFGWGlleCs4ZUVIUzVnL1hnCnFacitvQkhPZEVwOFM1Mml2TmxH
|
||||
YVV1RkZQSGRmV05qelMza0MwUTZyTG8KLS0tIFRUc3RSZmFOY2V1NHBVR2p4bFBm
|
||||
ZTFsTFpwcjBIaEp5UmJqYWdKNTlyVncK88IrSaBnVz34oiWpeyvYHLFDJ11wH31Y
|
||||
gf3nlORVIe1MhMMkBgukOVJ8P1aiKN5ZUgdXz+dD2Ze5hG0q5HF/LQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-09T06:56:22Z"
|
||||
mac: ENC[AES256_GCM,data:njQcK5UjACvRac8oUezgK2v4FtSNL0JgBmqMmvNuYTnPsv5oZItURfXI+6AByFjyquLr25u9rW6zaCtSSecJhz1BSKTRnw5gRGleI75RDV4eCu9CCTR5u/Vpd/bbbAhagzAxzuXDCuCp1aMo6kUqb7EIHaM5QSb6f7HALb85MZw=,iv:bsu/yEfAr0ZTEZRYD3tymkx61JPg8mKXTRKL1HeW1+o=,tag:tP89H0eBK2hbWEtRYFhVRA==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
RENDER_PROFILE=prod
|
||||
|
||||
sops decrypt $RENDER_PROFILE-config.enc.yaml > $RENDER_PROFILE-config.yaml
|
||||
|
||||
dockerContext=$(docker context inspect default | jq -r .[0].Endpoints.docker.Host)
|
||||
if [[ $dockerContext == unix://* ]]; then # docker daemon runs on the same machine
|
||||
# use gomplate to render profiles
|
||||
docker run --rm -v .:/data hairyhenderson/gomplate:v4.3.1 --config /data/gomplate.yaml -c config=/data/$RENDER_PROFILE-config.yaml
|
||||
# invoke twice to fix file permission issue
|
||||
docker run --rm -v .:/data hairyhenderson/gomplate:v4.3.1 --config /data/gomplate.yaml -c config=/data/$RENDER_PROFILE-config.yaml
|
||||
else # docker won't work, possibly in ci
|
||||
curl -o /usr/local/bin/gomplate -sSL https://github.com/hairyhenderson/gomplate/releases/download/v4.3.1/gomplate_linux-amd64
|
||||
chmod 755 /usr/local/bin/gomplate
|
||||
/usr/local/bin/gomplate --config gomplate-ci.yaml -c config=$RENDER_PROFILE-config.yaml
|
||||
fi
|
||||
|
||||
rm -f $RENDER_PROFILE-config.yaml
|
||||
|
||||
# check each profile to make sure they exists
|
||||
# and convert to the cli
|
||||
CONFIG_FILES=("-c" "docker-stack.base.yml")
|
||||
# preview the full stack
|
||||
echo "Stack config preview:"
|
||||
cmd=(docker stack config "${CONFIG_FILES[@]}")
|
||||
if "${cmd[@]}"; then
|
||||
echo "The above config will be used"
|
||||
else
|
||||
echo "Command failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"${cmd[@]}" > compose.$RENDER_PROFILE.yaml
|
||||
rm -f docker-stack.*.yml
|
||||
@@ -0,0 +1,10 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
whoami:
|
||||
image: traefik/whoami
|
||||
ports:
|
||||
- "((.config.whoami.port.http)):80"
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: ((.config.whoami.deployReplica))
|
||||
Reference in New Issue
Block a user