Merge pull request #1940 from grouville/particubes-doc

docs: Use Case - Go on Docker Swarm
This commit is contained in:
Gerhard Lazu 2022-03-30 17:32:15 +01:00 committed by GitHub
commit d8fbbf5055
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 267 additions and 79 deletions

View File

@ -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
}
}

View 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
}
}

View 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
}
}
}
}
}

View File

@ -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)
::: :::

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB