This repo contains all the resources that are required to set up a simple CI/CD lab for educational purposes.
The lab allows a group of participants to initiate one or more projects and establish a full SDLC around them, including:
- project management: Redmine
- source control management: Gitea
- continuous integration facilities: Jenkins
- artifacts storage and management: Nexus
- deployment runtime: Kubernetes
- database and database administration: Postgres and PG Admin
- application monitoring and observability: Prometheus and Grafana
All customised Docker images are published to the Docker Hub.
The lab was developed on a Windows laptop with a quad-core AMD Ryzen 5 and 16GB of RAM, and runs happily in there. You will need Docker in order to run the lab, and at least 8GB FREE of RAM. If you want to deploy to Kubernetes, then you will also need Minikube.
Just run docker compose up -d. If you haven't changed the services' ports in docker-compose.yml, then the services
will be running as follows:
| Service | Browser URL | Admin User |
|---|---|---|
| Artifacts Repo | http://localhost:8081/ | admin |
| CI Server | http://localhost:8080/jenkins | admin |
| Clean Code Server | http://localhost:9000/ | admin |
| Database | use the DB Admin URL | postgres |
| DB Admin | http://localhost:5050/ | admin@cicdlabs.org |
| Project Server | http://localhost:3001/ | admin |
| SCM Server | http://localhost:3000/ | cicdadmin |
The password for every user on every service is just password.
It will take about 20 minutes to start all services from scratch for the first time, so be patient. The first time you start everything, all images will have to be downloaded and that takes a good few minutes on the average home broadband connection. After that, all services will usually start up in under 10 minutes from "cold".
The artifacts repository takes the longest to start up. The first time it starts, it will automatically install and configure a lot of stuff. The first time you login to it, it will ask you to complete a couple of manual setup steps. Just make sure you enable anonymous access and that's it. I haven't found a way to easily turn this into a pre-built fast-loading custom image. If you do, then please let me know how you did it.
The lab also contains a labsetup service. This performs some additional configuration operations on some
services that couldn't be pre-built as custom images. The labsetup service runs fairly quickly and then it stops.
It should not be running continuously, and you don't need to try starting it up again and again.
It only needs to run once to finish setting things up. Just let it be.
The CI server will use the following credentials to connect to other services. All of these are stored in the Credentials management screen:
| Target Service | Credentials ID | Username | Password |
|---|---|---|---|
| SCM Server | GITEA_CREDENTIALS | cicdservice | password |
| Artifacts Repository | NEXUS_CREDENTIALS | cicdservice | password |
There is a predefined user called developer with password password for source control. You can use it to create new
repositories and to push code to source control.
There really is no particular need to persist all data on the host filesystem, apart from the SCM server, for the simple reason that it is very useful for lab users not to lose easily any of the code they produce. Also, there are no predefined repositories in source control. You will have to create them as part of your lab exercises.
The Jenkins user to access all other services is called cicdservice with password password.
The Jenkins token for the admin user is 11d877beb7a5a4e4ea09561047fd4706b0, which is used to perform additional
setup
through the Jenkins API.
The Gitea token for the cicdadmin user is 234bf3a2b99bc52d9f0db2cbe90c0dbb4682a130. The setup service will use
this token to prepare and configure all the lab repos.
The Gitea token for the cicdservice user is 35400151bd4c17cd678ff3d303f5e6500abb55b3. This will be used by the
CI agent to clone the repo before each build.
The Gitea token for the developer user is 149b1f7fe81cdcbcef7782d78dfc5efd229ec033. The setup service will use
this token to push all sample code to the lab repos.
The Sonar token for automated passwordless analysis is squ_0dd6393e80a4bd4ab058ccb649625f34878ee6f3. Jenkins will
use this token to submit all code scans and retrieve the results. NOTE: the Sonar service is work-in-progress and is
not currently deployed as part of the lab. Stay tuned.
The Postgres database contains schemas for the lab's services, with a separate schema for each service.
You can use the public schema for your lab sessions, or you can create a new database, or (even better) you can
just spawn your own DB container.
There are only a few custom Docker images used by this virtual lab. The rest are public Docker images readily available on Docker Hub.
You have to get an NVD API key from the NIST site and
store it in the file NVD_API_KEY.txt, otherwise you won't be able to build the CI Agent image.
You can build all the custom images by invoking make local from the project root. If you want to build only one
image, then just run make <image name> instead. Bear in mind that ciagent can take about 1h to build!
Approximate build times:
| Image Name | Build time |
|---|---|
| ciserver | 10 minutes |
| ciagent | 60 minutes |
| dbserver | 10 minutes |
I have seen Docker Desktop on Windows 10 and Windows 11 spiking to 100% disk usage when running this lab. The following actions can help to fix it:
- Disable Kubernetes integration in Docker Dekstop
- Increase memory limits and swap size in a
%userprofile%\.wslconfigfile. I've added the one I use to this project, but you have to read the docs. - Try compacting the WSL distro's virtual drive.