Add Drone CI server with sqlite-on-s3 thing
This commit is contained in:
parent
7d7efab9ee
commit
8cd804a8c0
13 changed files with 264 additions and 1 deletions
10
app/drone-ci/config/litestream.yml
Normal file
10
app/drone-ci/config/litestream.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
dbs:
|
||||||
|
- path: /ephemeral/drone.db
|
||||||
|
replicas:
|
||||||
|
- url: s3://{{ key "secrets/drone-ci/s3_db_bucket" | trimSpace }}/drone.db
|
||||||
|
region: garage
|
||||||
|
endpoint: https://garage.deuxfleurs.fr
|
||||||
|
access-key-id: {{ key "secrets/drone-ci/s3_ak" | trimSpace }}
|
||||||
|
secret-access-key: {{ key "secrets/drone-ci/s3_sk" | trimSpace }}
|
||||||
|
force-path-style: true
|
||||||
|
sync-interval: 60s
|
139
app/drone-ci/deploy/server.hcl
Normal file
139
app/drone-ci/deploy/server.hcl
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
job "drone-ci" {
|
||||||
|
datacenters = ["neptune"]
|
||||||
|
type = "service"
|
||||||
|
|
||||||
|
group "server" {
|
||||||
|
count = 1
|
||||||
|
|
||||||
|
network {
|
||||||
|
port "web_port" {
|
||||||
|
to = 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "restore-db" {
|
||||||
|
lifecycle {
|
||||||
|
hook = "prestart"
|
||||||
|
sidecar = false
|
||||||
|
}
|
||||||
|
|
||||||
|
driver = "docker"
|
||||||
|
config {
|
||||||
|
image = "litestream/litestream:0.3.9"
|
||||||
|
args = [
|
||||||
|
"restore", "-config", "/etc/litestream.yml", "/ephemeral/drone.db"
|
||||||
|
]
|
||||||
|
volumes = [
|
||||||
|
"../alloc/data:/ephemeral",
|
||||||
|
"secrets/litestream.yml:/etc/litestream.yml"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
template {
|
||||||
|
data = file("../config/litestream.yml")
|
||||||
|
destination = "secrets/litestream.yml"
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
memory = 200
|
||||||
|
cpu = 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "drone_server" {
|
||||||
|
driver = "docker"
|
||||||
|
config {
|
||||||
|
image = "drone/drone:2.12.0"
|
||||||
|
ports = [ "web_port" ]
|
||||||
|
|
||||||
|
volumes = [
|
||||||
|
"../alloc/data:/ephemeral",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
template {
|
||||||
|
data = <<EOH
|
||||||
|
DRONE_GITEA_SERVER=https://git.deuxfleurs.fr
|
||||||
|
DRONE_GITEA_CLIENT_ID={{ key "secrets/drone-ci/oauth_client_id" }}
|
||||||
|
DRONE_GITEA_CLIENT_SECRET={{ key "secrets/drone-ci/oauth_client_secret" }}
|
||||||
|
DRONE_RPC_SECRET={{ key "secrets/drone-ci/rpc_secret" }}
|
||||||
|
DRONE_SERVER_HOST=drone.deuxfleurs.fr
|
||||||
|
DRONE_SERVER_PROTO=https
|
||||||
|
DRONE_DATABASE_SECRET={{ key "secrets/drone-ci/db_enc_secret" }}
|
||||||
|
DRONE_COOKIE_SECRET={{ key "secrets/drone-ci/cookie_secret" }}
|
||||||
|
AWS_ACCESS_KEY_ID={{ key "secrets/drone-ci/s3_ak" }}
|
||||||
|
AWS_SECRET_ACCESS_KEY={{ key "secrets/drone-ci/s3_sk" }}
|
||||||
|
AWS_DEFAULT_REGION=garage
|
||||||
|
AWS_REGION=garage
|
||||||
|
DRONE_S3_BUCKET={{ key "secrets/drone-ci/s3_storage_bucket" }}
|
||||||
|
DRONE_S3_ENDPOINT=https://garage.deuxfleurs.fr
|
||||||
|
DRONE_S3_PATH_STYLE=true
|
||||||
|
DRONE_DATABASE_DRIVER=sqlite3
|
||||||
|
DRONE_DATABASE_DATASOURCE=/ephemeral/drone.db
|
||||||
|
DRONE_USER_CREATE=username:lx-admin,admin:true
|
||||||
|
__DRONE_REGISTRATION_CLOSED=true
|
||||||
|
DRONE_LOGS_TEXT=true
|
||||||
|
DRONE_LOGS_PRETTY=true
|
||||||
|
DRONE_LOGS_DEBUG=true
|
||||||
|
DOCKER_API_VERSION=1.39
|
||||||
|
EOH
|
||||||
|
destination = "secrets/env"
|
||||||
|
env = true
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 100
|
||||||
|
memory = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
service {
|
||||||
|
name = "drone"
|
||||||
|
tags = [
|
||||||
|
"drone",
|
||||||
|
"tricot drone.deuxfleurs.fr",
|
||||||
|
]
|
||||||
|
port = "web_port"
|
||||||
|
address_mode = "host"
|
||||||
|
check {
|
||||||
|
type = "http"
|
||||||
|
protocol = "http"
|
||||||
|
port = "web_port"
|
||||||
|
path = "/"
|
||||||
|
interval = "60s"
|
||||||
|
timeout = "5s"
|
||||||
|
check_restart {
|
||||||
|
limit = 3
|
||||||
|
grace = "600s"
|
||||||
|
ignore_warnings = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "replicate-db" {
|
||||||
|
driver = "docker"
|
||||||
|
config {
|
||||||
|
image = "litestream/litestream:0.3.9"
|
||||||
|
entrypoint = [ "/bin/sh" ]
|
||||||
|
args = [
|
||||||
|
"-c",
|
||||||
|
"echo sleeping; sleep 60; echo launching; litestream replicate -config /etc/litestream.yml"
|
||||||
|
]
|
||||||
|
volumes = [
|
||||||
|
"../alloc/data:/ephemeral",
|
||||||
|
"secrets/litestream.yml:/etc/litestream.yml"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
template {
|
||||||
|
data = file("../config/litestream.yml")
|
||||||
|
destination = "secrets/litestream.yml"
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
memory = 250
|
||||||
|
cpu = 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
74
app/drone-ci/integration/README.md
Normal file
74
app/drone-ci/integration/README.md
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
## Install Debian
|
||||||
|
|
||||||
|
We recommend Debian Bullseye
|
||||||
|
|
||||||
|
## Install Docker CE from docker.io
|
||||||
|
|
||||||
|
Do not use the docker engine shipped by Debian
|
||||||
|
|
||||||
|
Doc:
|
||||||
|
|
||||||
|
- https://docs.docker.com/engine/install/debian/
|
||||||
|
- https://docs.docker.com/compose/install/
|
||||||
|
|
||||||
|
On a fresh install, as root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt-get remove -y docker docker-engine docker.io containerd runc
|
||||||
|
apt-get update
|
||||||
|
apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
|
||||||
|
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||||
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y docker-ce docker-ce-cli containerd.io
|
||||||
|
|
||||||
|
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
|
chmod +x /usr/local/bin/docker-compose
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prepare the runner
|
||||||
|
|
||||||
|
Nix folder must be populated before launching any build.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -it -v /var/lib/drone/nix:/mnt nixpkgs/nix:nixos-21.05 cp -r /nix/{store,var} /mnt/
|
||||||
|
```
|
||||||
|
|
||||||
|
This folder will grow over time and might need to be garbage collected.
|
||||||
|
As a rule of thumb, after running a full release of Garage, this folder will require 10GB.
|
||||||
|
Consider provisioning it with at least 20GB.
|
||||||
|
|
||||||
|
## Launch the runner
|
||||||
|
|
||||||
|
Because we use a shared nix folder, we set the number of concurrent builds to 1.
|
||||||
|
For more details and customizations, see `docker-compose.yml`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DRONE_NAME=lheureduthe DRONE_OWNER=quentin DRONE_SECRET=xxx docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
That's all folks.
|
||||||
|
|
||||||
|
## Check if a given job is built by your runner
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export URL=https://drone.deuxfleurs.fr
|
||||||
|
export REPO=Deuxfleurs/garage
|
||||||
|
export BUILD=1312
|
||||||
|
curl ${URL}/api/repos/${REPO}/builds/${BUILD} \
|
||||||
|
| jq -c '[.stages[] | { name: .name, machine: .machine }]'
|
||||||
|
```
|
||||||
|
|
||||||
|
It will give you the following result:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[{"name":"default","machine":"1686a"},{"name":"release-linux-x86_64","machine":"vimaire"},{"name":"release-linux-i686","machine":"carcajou"},{"name":"release-linux-aarch64","machine":"caribou"},{"name":"release-linux-armv6l","machine":"cariacou"},{"name":"refresh-release-page","machine":null}]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Random note
|
||||||
|
|
||||||
|
This setup is done mainly to allow nix builds with some cache.
|
||||||
|
To use the cache in Drone, you must set your repository as trusted.
|
||||||
|
The command line tool does not work (it says it successfully set your repository as trusted but it did nothing):
|
||||||
|
the only way to set your repository as trusted is to connect on the DB and set the `repo_trusted` field of your repo to true.
|
||||||
|
|
32
app/drone-ci/integration/docker-compose.yml
Normal file
32
app/drone-ci/integration/docker-compose.yml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
version: '3.4'
|
||||||
|
services:
|
||||||
|
drone-runner:
|
||||||
|
image: drone/drone-runner-docker:latest
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- DRONE_RPC_PROTO=https
|
||||||
|
- DRONE_RPC_HOST=drone.deuxfleurs.fr
|
||||||
|
- DRONE_RPC_SECRET=${DRONE_SECRET}
|
||||||
|
- DRONE_RUNNER_CAPACITY=1
|
||||||
|
- DRONE_DEBUG=true
|
||||||
|
- DRONE_LOGS_TRACE=true
|
||||||
|
- DRONE_RPC_DUMP_HTTP=true
|
||||||
|
- DRONE_RPC_DUMP_HTTP_BODY=true
|
||||||
|
- DRONE_RUNNER_NAME=${DRONE_NAME}
|
||||||
|
- DRONE_RUNNER_LABELS=nix:1
|
||||||
|
#- DRONE_RUNNER_VOLUMES=/var/lib/drone/nix:/nix
|
||||||
|
ports:
|
||||||
|
- "3000:3000/tcp"
|
||||||
|
volumes:
|
||||||
|
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||||
|
- "/var/lib/drone/nix:/var/lib/drone/nix"
|
||||||
|
|
||||||
|
drone-gc:
|
||||||
|
image: drone/gc:latest
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- GC_DEBUG=true
|
||||||
|
- GC_CACHE=10gb
|
||||||
|
- GC_INTERVAL=10m
|
||||||
|
volumes:
|
||||||
|
- "/var/run/docker.sock:/var/run/docker.sock"
|
1
app/drone-ci/secrets/drone-ci/cookie_secret
Normal file
1
app/drone-ci/secrets/drone-ci/cookie_secret
Normal file
|
@ -0,0 +1 @@
|
||||||
|
CMD openssl rand -hex 16
|
1
app/drone-ci/secrets/drone-ci/db_enc_secret
Normal file
1
app/drone-ci/secrets/drone-ci/db_enc_secret
Normal file
|
@ -0,0 +1 @@
|
||||||
|
CMD_ONCE openssl rand -hex 16
|
1
app/drone-ci/secrets/drone-ci/oauth_client_id
Normal file
1
app/drone-ci/secrets/drone-ci/oauth_client_id
Normal file
|
@ -0,0 +1 @@
|
||||||
|
USER OAuth client ID (on Gitea)
|
1
app/drone-ci/secrets/drone-ci/oauth_client_secret
Normal file
1
app/drone-ci/secrets/drone-ci/oauth_client_secret
Normal file
|
@ -0,0 +1 @@
|
||||||
|
USER OAuth client secret (for gitea)
|
|
@ -1 +1 @@
|
||||||
USER Drone RPC secret
|
CMD openssl rand -hex 16
|
||||||
|
|
1
app/drone-ci/secrets/drone-ci/s3_ak
Normal file
1
app/drone-ci/secrets/drone-ci/s3_ak
Normal file
|
@ -0,0 +1 @@
|
||||||
|
USER S3 (garage) access key for Drone
|
1
app/drone-ci/secrets/drone-ci/s3_db_bucket
Normal file
1
app/drone-ci/secrets/drone-ci/s3_db_bucket
Normal file
|
@ -0,0 +1 @@
|
||||||
|
CONST drone-db
|
1
app/drone-ci/secrets/drone-ci/s3_sk
Normal file
1
app/drone-ci/secrets/drone-ci/s3_sk
Normal file
|
@ -0,0 +1 @@
|
||||||
|
USER S3 (garage) secret key for Drone
|
1
app/drone-ci/secrets/drone-ci/s3_storage_bucket
Normal file
1
app/drone-ci/secrets/drone-ci/s3_storage_bucket
Normal file
|
@ -0,0 +1 @@
|
||||||
|
CONST drone-storage
|
Loading…
Reference in a new issue