Prepare the infrastructure
Requirements
-
CI system;
-
Linux host to run the CI jobs, featuring:
-
Docker Runner of your CI system of choice;
-
Setting up the build environment with Buildah
(For Ubuntu 23.10 and later) on the GitLab Runner host run:
{ echo "kernel.apparmor_restrict_unprivileged_userns = 0" && echo "kernel.apparmor_restrict_unprivileged_unconfined = 0";} | sudo tee -a /etc/sysctl.d/20-apparmor-donotrestrict.conf && sudo sysctl -p /etc/sysctl.d/20-apparmor-donotrestrict.conf
Configuring the Runner
Create the werf
volume on the host where CI jobs are run:
docker volume create werf
Configure your CI system’s Runner so that the containers you create have the following parameters:
-
--security-opt seccomp:unconfined
; -
--security-opt apparmor:unconfined
; -
--volume werf:/home/build/.werf
.
If the host to run CI jobs has Linux kernel version 5.12 or lower, install fuse
on the host and configure Runner so that the containers you create have the optional parameter --device /dev/fuse
.
Configuring the container registry
Enable garbage collection for your container registry.
Preparing the system for cross-platform building (optional)
This step only needed to build images for platforms other than host platform running werf.
Register emulators on your system using qemu-user-static:
docker run --restart=always --name=qemu-user-static -d --privileged --entrypoint=/bin/sh multiarch/qemu-user-static -c "/register --reset -p yes && tail -f /dev/null"
Configure the project
Configuring CI/CD of the project
This is how the repository that uses werf for build and deploy might look:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: {{ .Values.werf.image.app }}
apiVersion: v1
kind: Service
metadata:
name: app
spec:
selector:
app: app
ports:
- name: app
port: 80
FROM node
WORKDIR /app
COPY . .
RUN npm ci
CMD ["node", "server.js"]
{
"name": "app",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "app",
"version": "1.0.0"
}
}
}
{
"name": "app",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"start": "node server.js"
}
}
const http = require('http');
const hostname = '127.0.0.1';
const port = 80;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
image: "registry.werf.io/werf/werf:2-stable"
image_pull_policy: always
environment_variables:
WERF_REPO: registry.example.org/myrepo
WERF_ENV: "${CI_ENVIRONMENT}"
WERF_ENABLE_PROCESS_EXTERMINATOR: "1"
before_every_job:
- werf cr login -u "${REGISTRY_USER:?}" -p "${REGISTRY_PASSWORD:?}" "${WERF_REPO:?}"
jobs:
prod:
commands:
- werf converge
environment: prod
on: master
how: manually
images:cleanup:
commands:
- werf cleanup
on: master
how: daily
configVersion: 1
project: myproject
---
image: app
dockerfile: Dockerfile
context: ./app
Extras:
- Add authorization options for
werf cleanup
in the container registry by following instructions.