drone Automation
![drone Automation](/images/drone_overview_hu7b8733eeb090722a653fbed652b113ca_92935_900x500_fit_box_3.png)
drone
- Installation Server & Runner
- Use-case: Statische Webseite
- Plugins
- Cron Jobs
- Badges
- Installation drone-cli
Drone ist eine Continuous Integration und Continuous Deployment (CI/CD) Lösung, die es Entwicklern ermöglicht, verschiedene Dinge wie Test und Deployments von Anwendungen in einer benutzerfreundlichen Art und Weise durchzuführen.
Drone verwendet Docker-Container, um eine einheitliche und reproduzierbare “Build”-Umgebung zu gewährleisten, und bietet Plugins, um zahlreiche Integrationspunkte wie Github, Bitbucket, Gitlab und auch gitea zu unterstützen.
Drone ist Open Source und kann auf einem lokalen Rechner oder in der Cloud betrieben werden.
Beispiel: hello-world
---
kind: pipeline
type: docker
name: hello-world
steps:
- name: say-hello
image: busybox
commands:
- echo hello-world
Installation Server & Runner
Ich nutze drone auf einem virtuellen Server. Dort habe ich die beiden erforderlichen docker Container mit Hilfe eines docker-compose.yml Datei erstellt.
HINWEIS Dieses Beispiel benötigt ein konfiguriertes traefik
---
version: '3.8'
services:
drone-server:
container_name: drone
image: drone/drone:${DRONE_VERSION:-2.16}
restart: unless-stopped
environment:
# https://docs.drone.io/server/provider/gitea/
- DRONE_DATABASE_DRIVER=sqlite3
- DRONE_DATABASE_DATASOURCE=/data/database.sqlite
- DRONE_GITEA_SERVER=https://git.bueraner.de/
- DRONE_GIT_ALWAYS_AUTH=false
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
- DRONE_SERVER_PROTO=https
- DRONE_SERVER_HOST=ci.bueraner.de
- DRONE_TLS_AUTOCERT=false
- DRONE_USER_CREATE=${DRONE_USER_CREATE}
- DRONE_GITEA_CLIENT_ID=${DRONE_GITEA_CLIENT_ID}
- DRONE_GITEA_CLIENT_SECRET=${DRONE_GITEA_CLIENT_SECRET}
labels:
- "traefik.enable=true"
- "traefik.http.routers.drone.rule=Host(`ci.bueraner.de`)"
networks:
- traefik_web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./drone:/data
drone-runner:
container_name: drone-runner
image: drone/drone-runner-docker:${DRONE_RUNNER_VERSION:-1}
restart: unless-stopped
depends_on:
drone-server:
condition: service_started
environment:
# https://docs.drone.io/runner/docker/installation/linux/
# https://docs.drone.io/server/metrics/
- DRONE_RPC_PROTO=https
- DRONE_RPC_HOST=ci.bueraner.de
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
- DRONE_RUNNER_NAME="${HOSTNAME}-runner"
- DRONE_RUNNER_CAPACITY=2
- DRONE_RUNNER_NETWORKS=traefik_web
- DRONE_DEBUG=false
- DRONE_TRACE=false
networks:
- traefik_web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
traefik_web:
external: true
Desweiteren müsst ihr noch einen RPC key mittels
openssl rand -hex 24
Kommando erstellen und die Applikation mittels Oauth in gitea registrieren. Details dazu findet ihr unter https://containers.fan/posts/setup-drone-server-and-drone-runner-for-gitea-on-docker/
Use-case: Statische Webseite
Um den Workflow mit meiner statischen Webseite zu vereinfachen, habe ich mir benutzerdefinierte docker image gebaut, welches auf alpine basiert. Auch dieses Image wird durch drone erstellt und in die gitea Package-Registry übertragen.
.drone.yml
Die Pipeline Definition befindet sich standardmäßig im root-Verzeichnis des entsprechenen gitea Repos. Hier mein Beispiel welches ich zum Aktualisieren der kirchhoffs.de Seite verwende.
---
kind: pipeline
name: default
steps:
- name: Build & Deploy
image: git.bueraner.de/murdoc/docker-hugo:latest
environment:
LFTP_PASSWORD:
from_secret: kirchhoffs_password
LFTP_USER:
from_secret: kirchhoffs_username
LFTP_HOST:
from_secret: kirchhoffs_hostname
commands:
- hugo version
- hugo
- LCD="$(pwd)/public"
- chmod -R 755 "$LCD"
- RCD="/hugo"
- lftp --env-password sftp://"$LFTP_USER@$LFTP_HOST" \
-e "set sftp:auto-confirm yes;set ftp:list-options -a; \
mirror --continue --reverse --delete --verbose $LCD $RCD; bye"
- name: notify
group: post
image: drillster/drone-email
settings:
from.address:
from_secret: email_from
host:
from_secret: email_host
username:
from_secret: email_username
password:
from_secret: email_password
recipients:
from_secret: email_recipients
subject: >
[{{ build.status }}]
{{ repo.owner }}/{{ repo.name }}
({{ build.branch }} - {{ truncate build.commit 8 }})
when:
status:
- changed
- failure
Sobald ich nun einen Artikel in das Repo sende, läuft automatisch
die Pipeline los, rendert mittels hugo
Kommando die Seite und
synchronsiert die Seite auf meinem Webspace. Hier sei noch erwähnt
das rsync
auch eine Synchronisation ermöglicht, allerdings habe ich bei
meinem Webspace Provider “nur” einen SFTP Zugang. Das oben genannte Image
enthält aber auch das rsync
Paket.
Das verwendete docker image besteht aus einem Alpine Distro mit ein paar zusätzlichen Programmen. Anbei exemplarisch das dockerfile:
FROM alpine:3.17
LABEL org.opencontainers.image.authors="murdoc@storm-clan.de" \
org.label-schema.name="Hugo image" \
org.label-schema.vendor="murdoc" \
org.label-schema.schema-version="0.1.0"
ENV CURL_VERSION="7.87.0-r1"
ENV GIT_VERSION="2.38.3-r1"
ENV GO_VERSION="1.19.5-r0"
ENV BASH_VERSION="5.2.15-r0"
ENV BASH_COMPLETION_VERSION="2.11-r4"
ENV LFTP_VERSION="4.9.2-r4"
ENV RSYNC_VERSION="3.2.7-r0"
ENV OPENSSH_VERSION="9.1_p1-r2"
RUN apk add --no-cache \
curl="$CURL_VERSION" \
git="$GIT_VERSION" \
go="$GO_VERSION" \
bash="$BASH_VERSION" \
bash-completion="$BASH_COMPLETION_VERSION" \
lftp="$LFTP_VERSION" \
rsync="$RSYNC_VERSION" \
openssh-client="$OPENSSH_VERSION" \
&& rm -rf /var/cache/apk/*
ENV HUGO_VERSION=0.110.0
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN mkdir -p /usr/local/src
WORKDIR /usr/local/src
RUN curl -L https://github.com/gohugoio/hugo/releases/download/\
v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz | tar -xz \
&& mv hugo /usr/local/bin/hugo \
&& addgroup -Sg 1000 hugo \
&& adduser -SG hugo -u 1000 -h /src hugo
WORKDIR /src
EXPOSE 1313
Deployment
Die Pipeline startet automatisch nachdem die Änderungen mittels git push
ins Repo übermittelt werden.
![](/images/drone-deployment.png)
Plugins
Am Beispiel unter .drone.yml zu sehen ist,
kann man mit drone auch eine Vielzahl von Plugins verwerden.
In dem Beispiel nutze ich das drone-email
Plugin um mich informieren zu
lassen, falls beim “deployment” etwas schief geht.
![](/images/drone-failed-pipeline.png)
Cron Jobs
Es können auch regelmäßige Aufgaben geplant und zeitlich automatisch durch drone gestartet werden. Dazu gibt es die folenden Intervalle:
- @hourly
- @daily
- @weekly
- @monthly
- @yearly
Badges
Badges sind kleine Übersichtsgrafiken die über den Zustand der Pipeline Aufschluss geben. In drone ist momentan nur der aktuelle Build Status einzusehen. Weitere Infos könnnen aber mit Zusatzdiensten implemementiert werden.
![](/images/drone-badges.png)
Installation drone-cli
Ein cooles Feature von drone, das man die pipeline auch seinem lokalen Rechner testen kann. Das spart Zeit beim entwickeln, da man nicht immer auf die Remote Pipeline warten muss. Die Installation ist schnell abgeschlossen unter ArchLinux mittels folgendem Kommando:
sudo pacman -S drone-cli
Mittels dem Kommando
drone exec
![](/images/drone-cli.png)
Kann die Pipeline gestartet werden. Sofern die interne “Secrets”-Verwaltung genutzt werden, kann man sich eine lokale Datei mit den Secrets erstellen und es beim Aufruf mit angeben.
drone exec --secret-file=.env