Opinionated YAML-driven Jenkins.
For a local development workflow, see below
-
Edit
setup.yml
to point to a seed job, if one is desired, or remove the contents of theseed_jobdsl
block. Change:properties { githubProjectUrl('https://github.com/controlplaneio/jenkins-dsl') }
and
remote { url('git@github.com:controlplaneio/jenkins-dsl.git') credentials('ssh-key-jenkins-bot') }
-
Update the secrets and admin configuration for the deployment:
$ cp setup-secret-example.yml setup-secret.yml
Edit
setup-secret.yml
and fill in the configuration values. Update:org_name: github organisation name admin_user: github username admin_emai: email of github user client_id/client_secret: OAuth secrets from Github for login
Client secrets for github/github_test are used for make run/test-run respectively
-
Build the Docker image:
$ make build
-
Once built, launch locally:
Make sure
JENKINS_HOME_MOUNT_DIR
exists, and is an absolute path. If you don't specify it, it will default to/mnt/jenkins_home
.$ JENKINS_HOME_MOUNT_DIR=${HOME}/jenkins_home make run-local
Navigate go to
http://localhost:8080
in your browser.For a local development workflow, see below
-
If you don't care about persisting that data then you can use the
test-run
command, which uses a new/tmp/foo
directory each invocation, and runs onTEST_PORT
in the Makefile (default is8090
).$ make test-run
Once Jenkins is up:
- Credentials for the
ssh-key-jenkins-bot
user need to be added to clone repositories via SSH - In-process script approval is required to allow the initial DSL scripts
Building in a local Jenkins instance avoids the long feedback loop associated with remote Jenkins builds. It's particuarly useful for Jenkinsfile and Job DSL development.
- checkout a git repo to your host machine (laptop, etc)
- mount the git repo from your host to the local Jenkins container at startup
- make a commit to your local git repo (Jenkins will alway build from the last commit)
- trigger a build job in the local Jenkins
- Invoke the container:
JENKINS_HOME_MOUNT_DIR=${HOME}/jenkins_home \ JENKINS_TESTING_REPO_MOUNT_DIR=${HOME}/test-repo \ CONTAINER_TAG=latest \ make run-local
- add the directories you want to mount for the Jenkins home directory and the repository you are building to the environment variables
JENKINS_HOME_MOUNT_DIR
andJENKINS_TESTING_REPO_MOUNT_DIR
. - this mounts the
JENKINS_TESTING_REPO_MOUNT_DIR
to/mnt/test-repo
- add the directories you want to mount for the Jenkins home directory and the repository you are building to the environment variables
- Log in at http://localhost:8080 (or
TEST_PORT
if runningmake test-run
, default8090
) - Exec into the running container and disable security in the config file in order to access all the settings. (you should ONLY DO THIS LOCALLY):
$ docker exec -it CONTAINER_ID su jenkins -c bash
jenkins@CONTAINER_ID:/$ sed -i 's/<useSecurity>true<\/useSecurity>/<useSecurity>false<\/useSecurity>/' /var/jenkins_home/config.xml
jenkins@CONTAINER_ID:/$ exit
$ docker container restart CONTAINER_ID
You will need to restart the container for the new config to take effect.
-
create a new pipeline job (or whatever you're testing)
- set the path to
file:///mnt/test-repo
(or a subdirectory thereof). If you are building a pipeline job, you will need to setPipeline > Definition
to "Pipeline script from SCM" and specify the path in "Repository URL", e.g file:///mnt/test-repo/my-repo/ - untick "Lightweight checkout"
- set the path to
-
trigger a build of the new job. In the repo under test, switch to a new branch to commit small chunks to test in Jenkins. These commits should be squashed or rebased onto another branch when complete:
-
git branch local-jenkins-dev && git checkout local-jenkins-dev
-
Make changes to the code in the repo
-
git add . && git commit -m "Auto commit $(date)"
-
Trigger a Jenkins build (see next section, or do manually through UI)
-
Iterate
-
When complete, rebase changes onto another branch for commit or PR
Jenkins checks out the local git repo to build the job, so changes must be committed locally for Jenkins to build them.
Secrets can be injected into a Jenkins instance via the API:
- Ensure a YAML file of secrets exists of the format demonstrated here
- Generate an API key for your admin user via Jenkins' UI (People > Desired User > Configure)
- Run the populate secrets script, either via
make secrets
, or the script it calls:script/populate-secrets.sh --server <i.e. http://localhost:8080> --username <admin username> --secrets-dir <relative path from populate-secrets.sh to secrets directory>
- Once the API key has been used, delete it from the Jenkins UI to prevent reuse
- Stop the Jenkins container
- Compress the data directories
tar czvf mount-jenkins.tar.gz /mnt/jenkins_home/ /mnt/certs/
- Copy the file to the new host (either via ssh ForwardAgent [which should only be enabled when required or bounced through a secure intermediate host/workstation)
- Un-tar the tarball into the same directories on the new host
- Run the Makefile from this repo on the new host
make run-prod \
CONTAINER_TAG=latest \
VIRTUAL_HOST=myhost.example.com \
LETSENCRYPT_EMAIL=my@example.com
To run the image by itself (without nginx or letencrypt), use
make run
instead ofmake run-prod