Merge pull request #1940 from grouville/particubes-doc
docs: Use Case - Go on Docker Swarm
This commit is contained in:
commit
d8fbbf5055
@ -0,0 +1,20 @@
|
|||||||
|
build: {
|
||||||
|
luaDocs: docker.#Dockerfile & {
|
||||||
|
source: client.filesystem."./lua-docs".read.contents
|
||||||
|
}
|
||||||
|
|
||||||
|
_addGithubSHA: core.#WriteFile & {
|
||||||
|
input: luaDocs.output.rootfs
|
||||||
|
path: "/www/github_sha.yml"
|
||||||
|
contents: #"""
|
||||||
|
keywords: ["particubes", "game", "mobile", "scripting", "cube", "voxel", "world", "docs"]
|
||||||
|
title: "Github SHA"
|
||||||
|
blocks:
|
||||||
|
- text: "\#(client.env.GITHUB_SHA)"
|
||||||
|
"""#
|
||||||
|
}
|
||||||
|
image: docker.#Image & {
|
||||||
|
rootfs: _addGithubSHA.output
|
||||||
|
config: luaDocs.output.config
|
||||||
|
}
|
||||||
|
}
|
20
docs/tests/use-cases/go-docker-swarm/client-api.cue.fragment
Normal file
20
docs/tests/use-cases/go-docker-swarm/client-api.cue.fragment
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package docs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"dagger.io/dagger"
|
||||||
|
)
|
||||||
|
|
||||||
|
dagger.#Plan & {
|
||||||
|
client: {
|
||||||
|
// Locally, manual source of the .env or install https://direnv.net
|
||||||
|
env: {
|
||||||
|
GITHUB_SHA: string
|
||||||
|
SSH_PRIVATE_KEY_DOCKER_SWARM: dagger.#Secret
|
||||||
|
}
|
||||||
|
filesystem: {
|
||||||
|
"./": read: contents: dagger.#FS
|
||||||
|
"./merge.output": write: contents: actions.build.image.rootfs // Creates a build artifact for debug
|
||||||
|
}
|
||||||
|
network: "unix:///var/run/docker.sock": connect: dagger.#Socket // Docker daemon socket
|
||||||
|
}
|
||||||
|
}
|
158
docs/tests/use-cases/go-docker-swarm/full/particubes.docs.cue
Normal file
158
docs/tests/use-cases/go-docker-swarm/full/particubes.docs.cue
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
package docs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"dagger.io/dagger"
|
||||||
|
"dagger.io/dagger/core"
|
||||||
|
|
||||||
|
"universe.dagger.io/alpine"
|
||||||
|
"universe.dagger.io/bash"
|
||||||
|
"universe.dagger.io/docker"
|
||||||
|
"universe.dagger.io/docker/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
dagger.#Plan & {
|
||||||
|
client: {
|
||||||
|
// Locally, manual source of the .env or install https://direnv.net
|
||||||
|
env: {
|
||||||
|
GITHUB_SHA: string
|
||||||
|
SSH_PRIVATE_KEY_DOCKER_SWARM: dagger.#Secret
|
||||||
|
}
|
||||||
|
filesystem: {
|
||||||
|
"./": read: contents: dagger.#FS
|
||||||
|
"./merge.output": write: contents: actions.build.image.rootfs // Creates a build artifact for debug
|
||||||
|
}
|
||||||
|
network: "unix:///var/run/docker.sock": connect: dagger.#Socket // Docker daemon socket
|
||||||
|
}
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
params: image: {
|
||||||
|
ref: "registry.particubes.com/lua-docs"
|
||||||
|
tag: "latest"
|
||||||
|
localTag: "test-particubes" // name of the image when being run locally
|
||||||
|
}
|
||||||
|
|
||||||
|
_dockerCLI: alpine.#Build & {
|
||||||
|
packages: {
|
||||||
|
bash: {}
|
||||||
|
curl: {}
|
||||||
|
"docker-cli": {}
|
||||||
|
"openssh-client": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#_verifyGithubSHA: bash.#Run & {
|
||||||
|
input: _dockerCLI.output
|
||||||
|
env: GITHUB_SHA: client.env.GITHUB_SHA
|
||||||
|
always: true
|
||||||
|
script: contents: #"""
|
||||||
|
TRIMMED_URL="$(echo $URL | cut -d '/' -f 1)"
|
||||||
|
curl --verbose --fail --connect-timeout 5 --location "$URL" >"$TRIMMED_URL.curl.out" 2>&1
|
||||||
|
|
||||||
|
if ! grep "$GITHUB_SHA" "$TRIMMED_URL.curl.out"
|
||||||
|
then
|
||||||
|
echo "$GITHUB_SHA not present in the $TRIMMED_URL response:"
|
||||||
|
cat "$TRIMMED_URL.curl.out"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
"""#
|
||||||
|
}
|
||||||
|
|
||||||
|
build: {
|
||||||
|
luaDocs: docker.#Dockerfile & {
|
||||||
|
source: client.filesystem."./lua-docs".read.contents
|
||||||
|
}
|
||||||
|
|
||||||
|
_addGithubSHA: core.#WriteFile & {
|
||||||
|
input: luaDocs.output.rootfs
|
||||||
|
path: "/www/github_sha.yml"
|
||||||
|
contents: #"""
|
||||||
|
keywords: ["particubes", "game", "mobile", "scripting", "cube", "voxel", "world", "docs"]
|
||||||
|
title: "Github SHA"
|
||||||
|
blocks:
|
||||||
|
- text: "\#(client.env.GITHUB_SHA)"
|
||||||
|
"""#
|
||||||
|
}
|
||||||
|
image: docker.#Image & {
|
||||||
|
rootfs: _addGithubSHA.output
|
||||||
|
config: luaDocs.output.config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clean: cli.#Run & {
|
||||||
|
host: client.network."unix:///var/run/docker.sock".connect
|
||||||
|
always: true
|
||||||
|
env: IMAGE_NAME: params.image.localTag
|
||||||
|
command: {
|
||||||
|
name: "sh"
|
||||||
|
flags: "-c": #"""
|
||||||
|
docker rm --force "$IMAGE_NAME"
|
||||||
|
"""#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test: {
|
||||||
|
preLoad: clean
|
||||||
|
|
||||||
|
load: cli.#Load & {
|
||||||
|
image: build.image
|
||||||
|
host: client.network."unix:///var/run/docker.sock".connect
|
||||||
|
tag: params.image.localTag
|
||||||
|
env: DEP: "\(preLoad.success)" // DEP created wth preLoad
|
||||||
|
}
|
||||||
|
|
||||||
|
run: cli.#Run & {
|
||||||
|
host: client.network."unix:///var/run/docker.sock".connect
|
||||||
|
always: true
|
||||||
|
env: {
|
||||||
|
IMAGE_NAME: params.image.localTag
|
||||||
|
PORTS: "80:80"
|
||||||
|
DEP: "\(load.success)" // DEP created wth load
|
||||||
|
}
|
||||||
|
command: {
|
||||||
|
name: "sh"
|
||||||
|
flags: "-c": #"""
|
||||||
|
docker run -d --rm --name "$IMAGE_NAME" -p "$PORTS" "$IMAGE_NAME"
|
||||||
|
"""#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verify: #_verifyGithubSHA & {
|
||||||
|
env: {
|
||||||
|
URL: "localhost/github_sha"
|
||||||
|
DEP: "\(run.success)" // DEP created wth run
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
postVerify: clean & {
|
||||||
|
env: DEP: "\(verify.success)" // DEP created wth verify
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deploy: {
|
||||||
|
publish: docker.#Push & {
|
||||||
|
dest: "\(params.image.ref):\(params.image.tag)"
|
||||||
|
image: build.image
|
||||||
|
}
|
||||||
|
|
||||||
|
update: cli.#Run & {
|
||||||
|
host: "ssh://ubuntu@3.139.83.217"
|
||||||
|
always: true
|
||||||
|
ssh: key: client.env.SSH_PRIVATE_KEY_DOCKER_SWARM
|
||||||
|
env: DEP: "\(publish.result)" // DEP created wth publish
|
||||||
|
command: {
|
||||||
|
name: "sh"
|
||||||
|
flags: "-c": #"""
|
||||||
|
docker service update --image registry.particubes.com/lua-docs:latest lua-docs
|
||||||
|
"""#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verify: #_verifyGithubSHA & {
|
||||||
|
env: {
|
||||||
|
URL: "https://docs.particubes.com/github_sha"
|
||||||
|
DEP: "\(update.success)" // DEP created wth run
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,78 +13,54 @@ They write primarily Go & Lua, push to GitHub and use GitHub Actions for automat
|
|||||||
The production setup is a multi-node Docker Swarm cluster running on AWS.
|
The production setup is a multi-node Docker Swarm cluster running on AWS.
|
||||||
|
|
||||||
The Particubes team chose Dagger for continuous deployment because it was the easiest way of integrating GitHub with Docker Swarm.
|
The Particubes team chose Dagger for continuous deployment because it was the easiest way of integrating GitHub with Docker Swarm.
|
||||||
Every commit to the main branch goes straight to [docs.particubes.com](https://docs.particubes.com) via a Dagger pipeline that runs in GitHub Actions.
|
Every commit to the main branch goes straight to [docs.particubes.com](https://docs.particubes.com) via a Dagger pipeline that runs in GitHub Actions. Let us see how the Particubes Dagger plan fits together.
|
||||||
`universe.dagger.io/docker` made building this pipeline trivial:
|
|
||||||
|
|
||||||
:::danger
|
### Actions API
|
||||||
TODO: this config is meta Europa, meaning that it was not tested. Next steps:
|
|
||||||
|
|
||||||
- implement it in GitHub Actions and ensure that it all works as expected
|
This is a high level overview of all actions in the Particubes docs Dagger plan:
|
||||||
- update this meta config to the final version that we know works
|
|
||||||
:::
|
|
||||||
|
|
||||||
```cue
|
![particubes flat plan](/img/use-cases/particubes-actions.png)
|
||||||
package particubes
|
|
||||||
|
|
||||||
import (
|
We can see all available actions in a Plan by running the following command:
|
||||||
"dagger.io/dagger"
|
|
||||||
"dagger.io/dagger/core"
|
|
||||||
"universe.dagger.io/docker"
|
|
||||||
)
|
|
||||||
|
|
||||||
dagger.#Plan & {
|
```bash
|
||||||
inputs: {
|
$ dagger do
|
||||||
directories: src: path: "./lua-docs"
|
Execute a dagger action.
|
||||||
secrets: docs: command: {
|
|
||||||
name: "sops"
|
|
||||||
args: ["-d", "../../lua-docs/sops_secrets.yaml"]
|
|
||||||
}
|
|
||||||
params: {
|
|
||||||
image: ref: docker.#Ref | *"registry.particubes.com/lua-docs:latest"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actions: {
|
Available Actions:
|
||||||
docs: {
|
build Create a container image
|
||||||
// TODO: write GITHUB_SHA into a static /github_sha.txt
|
clean Remove a container image
|
||||||
build: docker.#Dockerfile & {
|
test Locally test a container image
|
||||||
source: inputs.directories.src.contents
|
deploy Deploy a container image
|
||||||
}
|
|
||||||
|
|
||||||
test: {
|
|
||||||
// TODO:
|
|
||||||
// - run container
|
|
||||||
// - check http response code
|
|
||||||
// - verify /github_sha.txt value matches GITHUB_SHA
|
|
||||||
// - stop container
|
|
||||||
}
|
|
||||||
|
|
||||||
push: docker.#Push & {
|
|
||||||
dest: inputs.params.image.ref
|
|
||||||
image: build.output
|
|
||||||
}
|
|
||||||
|
|
||||||
docsSecrets: core.#DecodeSecret & {
|
|
||||||
input: inputs.secrets.docs.contents
|
|
||||||
format: "yaml"
|
|
||||||
}
|
|
||||||
deploy: {
|
|
||||||
// TODO:
|
|
||||||
// - run this command in the remote Docker Swarm
|
|
||||||
// - secrests are ready in docsSecrets, e.g. docsSecrets.output.swarmKey.contents
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyDeploy: {
|
|
||||||
// TODO:
|
|
||||||
// - check http response code
|
|
||||||
// - verify /github_sha.txt value matches GITHUB_SHA
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This is the GitHub Actions workflow config that invokes `dagger`, which in turn runs the above pipeline:
|
### Client API
|
||||||
|
|
||||||
|
Dagger actions usually need to interact with the host environment where the Dagger client runs. The Particubes' plan uses environment variables and the filesystem.
|
||||||
|
|
||||||
|
This is an overview of all client interactions for this plan:
|
||||||
|
|
||||||
|
![Client API](/img/use-cases/client-api.png)
|
||||||
|
|
||||||
|
This is what the above looks like in the Dagger plan config:
|
||||||
|
|
||||||
|
```cue file=../tests/use-cases/go-docker-swarm/client-api.cue.fragment
|
||||||
|
```
|
||||||
|
|
||||||
|
### The *build* Action
|
||||||
|
|
||||||
|
This is a more in-depth overview of the *build* action and how it interacts with the client in the Particubes docs Dagger plan:
|
||||||
|
|
||||||
|
![build action](/img/use-cases/build-action.png)
|
||||||
|
|
||||||
|
This is what the above looks like in the Dagger plan config:
|
||||||
|
|
||||||
|
```cue file=../tests/use-cases/go-docker-swarm/build-action.cue.fragment
|
||||||
|
```
|
||||||
|
|
||||||
|
### Github Action integration
|
||||||
|
|
||||||
|
This is the GitHub Actions workflow config that invokes `dagger`, which in turn runs the full plan:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
name: Dagger/docs.particubes.com
|
name: Dagger/docs.particubes.com
|
||||||
@ -96,33 +72,47 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GITHUB_SHA: ${{ github.sha }}
|
||||||
|
SSH_PRIVATE_KEY_DOCKER_SWARM: ${{ secrets.SSH_PRIVATE_KEY_DOCKER_SWARM }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install Dagger
|
||||||
|
uses: dagger/dagger-action@v2
|
||||||
with:
|
with:
|
||||||
lfs: true
|
install-only: true
|
||||||
// TODO: install sops
|
|
||||||
- name: Dagger
|
- name: Dagger poject update
|
||||||
uses: dagger/dagger-action@v1
|
run: dagger project update
|
||||||
with:
|
|
||||||
age-key: ${{ secrets.DAGGER_AGE_KEY }}
|
- name: Dagger do test
|
||||||
args: up
|
run: dagger do test --log-format plain
|
||||||
|
|
||||||
|
- name: Dagger do deploy
|
||||||
|
run: dagger do deploy --log-format plain
|
||||||
```
|
```
|
||||||
|
|
||||||
Since this is a Dagger pipeline, anyone on the team can run it locally with a single command:
|
Since this is a Dagger pipeline, anyone on the team can run it locally with a single command:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
dagger up
|
dagger do
|
||||||
```
|
```
|
||||||
|
|
||||||
This is the first step that enabled the Particubes team to have the same CI/CD experience everywhere.
|
This is the first step that enabled the Particubes team to have the same CI/CD experience everywhere.
|
||||||
|
|
||||||
We don't know what comes next for particubes.com, but we would like find out. Some ideas:
|
### Full Particubes docs Dagger plan
|
||||||
|
|
||||||
- deploy particubes.com with Dagger
|
This is the entire plan running on Particubes' CI:
|
||||||
- manage the Docker Swarm cluster with Dagger
|
|
||||||
- contribute `universe.dagger.io/particubes` package
|
```cue file=../tests/use-cases/go-docker-swarm/full/particubes.docs.cue
|
||||||
|
```
|
||||||
|
|
||||||
|
### What comes next ?
|
||||||
|
|
||||||
|
Particubes' team suggested that we create a `dev` action with *hot reload*, that way Dagger would even asbtract away the ramp-up experience when developing the doc
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
The latest version of this pipeline can be found at [github.com/voxowl/particubes/lua-docs/docs.cue](https://github.com/voxowl/particubes/blob/b698777465c02462296de37087dd3c341c29df92/lua-docs/docs.cue)
|
The latest version of this pipeline can be found at [github.com/voxowl/particubes/pull/144](https://github.com/voxowl/particubes/blob/2af173596729929cfb7a7a1f78f1ec0d8b685e5e/lua-docs/docs.cue)
|
||||||
:::
|
:::
|
||||||
|
BIN
website/static/img/use-cases/build-action.png
Normal file
BIN
website/static/img/use-cases/build-action.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 442 KiB |
BIN
website/static/img/use-cases/client-api.png
Normal file
BIN
website/static/img/use-cases/client-api.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 254 KiB |
BIN
website/static/img/use-cases/particubes-actions.png
Normal file
BIN
website/static/img/use-cases/particubes-actions.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 188 KiB |
Reference in New Issue
Block a user