setting up continuous delivery with drone
Long, long time ago, i started to manage my spare time projects with git, to make life a bit easier there were tools like gitosis and later gitolite - you managed repositories and public keys in plain text files and git hooks on the server. Last year i decided to join the shiny new world of modern self-hosting git services. I choose Gitea - copied it on the server, started one 40 mb binary, and it was just working - and it was fast.
Really impressed about the performance and simple deployments, i wanted to learn that sorcery.
Spoiler: The secret is go…
the old way
Similar to the repository management, my continouse delivery “pipeline” was a git hook (created by hand) and a bash script. That was working well enough for code, not delivered as a binary, like octobercms, playframework projects or hugo sites where you only have to check out the code and run something - the server has to be prepared for that of course.
I searched for something more intuitive.
starting the drone
The quickstart is really quick, ~20 lines of yaml and
docker-compose up is everything needed:
version: '2' services: drone-server: image: drone/drone:0.8 ports: - 8080:8000 - 9000 volumes: - ./.drone:/var/lib/drone/ restart: always environment: - DRONE_OPEN=false - DRONE_HOST=https://mydroneurl.net - DRONE_SECRET=123456 - DRONE_GITEA=true - DRONE_GITEA_URL=https://mygiteaurl.net drone-agent: image: drone/agent:0.8 command: agent restart: always depends_on: - drone-server volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - DRONE_SERVER=drone-server:9000 - DRONE_SECRET=123456
You can now login to drone with your gitea account and activate the drone webhook per simple click.
Hint: at first i forgot a field in the gitea config. For working webhooks, make sure your server config, especially the
ROOT_URLis set correctly.
Alright, let’s deliver some code!
My pipeline should:
- test and build a react frontend to a bundle.js
- take that bundle and embed it in a go binary
- upload the go binary to a server
- start the binary
Drone is loooking for a
.drone.yml file in the repository root. Everything is pretty straight forward. I love that i can just use every docker image for my build step, no need to manually install nodejs or go or any other environment by hand.
workspace: base: /go path: src/drailing.net/go-project pipeline: frontend: image: node commands: - cd frontend - npm install - npm test - npm run build build: image: cdreier:packr commands: - go get - packr build copyToServer: image: appleboy/drone-scp host: drailing.net username: ssh_username secrets: [ ssh_key ] target: ~/apps/go-project source: go-project startServer: image: appleboy/drone-ssh host: drailing.net username: ssh_username secrets: [ ssh_key ] port: 22 script: - pkill go-project - cd ~/apps/go-project - nohup ./go-project -port 3033 > /dev/null & branches: master
In the second step, I use packr to embed static files in the go binary. For a small speed boost, i created a custom docker image with packr preinstalled.
With the secrets (in the 3rd and 4th step), i can place the password or the private key in the drone server, so i don’t have to check in plaintext passwords or something.
Thanks to go and packr, i do not have any requirements to the server. For simplicity, i just run the binary - no need to dockerize one simple binary in that case.
In conclusion: really good CI/CD solution, easy to setup and everything is just working!