How to build a staging server with Docker, Jenkins and Traefik
~ Chapter 4 ~Completing the project configuration
This guide is largely outdated at this point. You should instead consider installing Jenkins on Kubernetes with Helm.
All that remains is to configure a project’s docker-compose.staging.yml and Jenkinsfile.
For the sake of example, I will show you the configuration I use when building React applications.
First, create a .dockerignore in your project to prevent undesired files from making it into the final image. It could contain something like :
.git
build
node_modulesNow, add a base Dockerfile to specify how to build the image. I like to copy the generated static files in an alpine version of httpd.
FROM node:9-alpine as builder
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build
FROM httpd:2-alpine
EXPOSE 80
COPY --from=builder build/ /usr/local/apache2/htdocs/Finally, create the project’s Jenkinsfile which will tie everything together:
pipeline {
options {
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '5'))
}
post { always { deleteDir() } }
agent any
stages {
stage('Build') {
steps {
build job: 'image_deploy_job_name/master', parameters: [
string(name: 'SOURCE_DIRECTORY', value: "${WORKSPACE}"),
string(name: 'DEPLOY_JOB_NAME', value: "${env.JOB_NAME}")
]
}
}
stage('Deploy') {
steps {
build job: 'image_build_job_name/master', parameters: [
string(name: 'SOURCE_DIRECTORY', value: "${WORKSPACE}"),
string(name: 'DEPLOY_JOB_NAME', value: "${env.JOB_NAME}"),
string(name: 'REPOSITORY', value: "docker-registry.your_domain"),
string(name: 'ENVIRONMENT', value: "staging")
]
}
}
}
}Replace image_build_job_name and image_deploy_job_name with the keys that were generated by Jenkins when you imported the pipelines as part of the previous step.
Commit a new change or manually launch a new build of that project in a desired branch that follows the supported patterns and Jenkins should have published your project at:
your_branch.your_project.swarm.your_domain
Maintenance
You may need to do house-cleaning once in a while if your server fills up. The make sure our flimsy server doesn’t blow up, I run the following script as a daily cron job:
#!/bin/bash
echo "==> Docker Cleanup"
echo "--> Removing any dangling or unused Docker parts"
docker system prune -af --volumes
echo "--> Removing any older items from the Registry"
docker exec docker-registry registry garbage-collect /etc/docker/registry/config.yml
echo "==> Server Cleanup"
echo "--> Run this as a sudoer if you get permission denied's"
echo "--> Removing builds directories"
rm -rf /opt/data/jenkins/workspace/*
echo "--> Pruning caches"
find /opt/data/jenkins/volume-caches/build-cache/bower/local -type d -ctime +5 | xargs rm -rf
find /opt/data/jenkins/volume-caches/build-cache/composer/ -type d -ctime +5 | xargs rm -rf
find /opt/data/jenkins/volume-caches/build-cache/node/npm -type d -ctime +5 | xargs rm -rf
find /opt/data/jenkins/volume-caches/build-cache/node/gyp -type d -ctime +5 | xargs rm -rf
find /opt/data/jenkins/volume-caches/build-cache/node/cache -type d -ctime +5 | xargs rm -rf
find /opt/data/jenkins/volume-caches/build-cache/node/config -type d -ctime +5 | xargs rm -rf
echo "--> Restoring permisssions"
chmod 777 -R /opt/data/jenkins/volume-caches/build-cache
chown root:root -R /opt/data/jenkins/volume-caches/build-cacheThat’s it!
Assuming this very lengthy guide was clear enough, you now have the same setup as we have. Once you get your head around each of the moving parts, it remains a rather simple approach with many gains over the manual setup of virtual hosts.
I hope you can get through the setup successfully and that you can get good mileage out of my proposed configuration.
Step completion checklist
- Added the
.dockerignore,Dockerfileanddocker-compose.staging.ymlfiles to a Docker-ready project - Configured the project’s
Jenkinsfileto use the global build and deploy jobs - Committed or forced a build on
master,developor afeature*branch - Successfully visited the URL for that instance of the project