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_modules
Now, 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-cache
That’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
,Dockerfile
anddocker-compose.staging.yml
files to a Docker-ready project - Configured the project’s
Jenkinsfile
to use the global build and deploy jobs - Committed or forced a build on
master
,develop
or afeature*
branch - Successfully visited the URL for that instance of the project