使用 Docker 搭建 Jenkins CI/CD
2024-09-29
使用 Docker 快速搭建 Jenkins 持续集成服务,支持 Docker in Docker 和 WebSocket。
Docker 部署
docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| version: '3' services: jenkins: image: jenkins/jenkins:lts user: root restart: always container_name: jenkins extra_hosts: - "git.example.com:192.168.1.100" ports: - "127.0.0.1:8080:8080" - "127.0.0.1:50000:50000" volumes: - ${HOME}/jenkins/jenkins_home:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock - ${HOME}/.docker:/root/.docker - ${HOME}/.ssh:/root/.ssh environment: - JENKINS_OPTS=--sessionTimeout=43200 --sessionEviction=604800
|
启动
1 2 3 4
| docker-compose up -d
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
|
Nginx 反向代理
WebSocket 支持配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| map $http_upgrade $connection_upgrade { default upgrade; '' close; }
upstream jenkins { keepalive 32; server 127.0.0.1:8080; }
server { listen 80; server_name jenkins.example.com; return 301 https://$host$request_uri; }
server { listen 443 ssl; server_name jenkins.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
access_log /var/log/nginx/jenkins.access.log; error_log /var/log/nginx/jenkins.error.log;
ignore_invalid_headers off;
location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" { rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last; }
location /userContent { root /var/jenkins_home/; if (!-f $request_filename) { rewrite (.*) /$1 last; break; } sendfile on; }
location / { sendfile off; proxy_pass http://jenkins; proxy_redirect default; proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m; client_body_buffer_size 128k;
proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90;
proxy_buffering off; proxy_request_buffering off; proxy_max_temp_file_size 0;
proxy_set_header Connection ""; } }
|
Docker in Docker 配置
安装 Docker 客户端
进入 Jenkins 容器安装 Docker CLI:
1 2 3 4 5 6 7 8
| docker exec -it jenkins bash
apt-get update apt-get install -y docker.io
docker ps
|
或使用自定义镜像
Dockerfile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| FROM jenkins/jenkins:lts
USER root
RUN apt-get update && \ apt-get install -y docker.io && \ rm -rf /var/lib/apt/lists/*
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" \ -o /usr/local/bin/docker-compose && \ chmod +x /usr/local/bin/docker-compose
USER jenkins
|
构建:
1
| docker build -t my-jenkins .
|
Pipeline 示例
Jenkinsfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| pipeline { agent any
environment { DOCKER_REGISTRY = 'docker.example.com' IMAGE_NAME = 'myapp' }
stages { stage('Checkout') { steps { git 'https://github.com/example/repo.git' } }
stage('Build') { steps { sh 'docker build -t ${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER} .' } }
stage('Push') { steps { script { docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-credentials') { sh 'docker push ${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}' } } } }
stage('Deploy') { steps { sh ''' docker stop myapp || true docker rm myapp || true docker run -d --name myapp -p 8080:8080 \ ${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER} ''' } } }
post { always { cleanWs() } } }
|
常用插件
1 2 3 4 5 6
| - Blue Ocean - Docker Plugin - Git Plugin - Pipeline - Kubernetes Plugin
|
注意事项
- WebSocket 配置对 Agent 连接至关重要
- 定期备份
/var/jenkins_home 目录
user: root 是为了访问 Docker socket,生产环境建议使用 Docker 组
- Session 超时设置避免频繁登录
- 建议配置 HTTPS 和 CSRF 保护
参考资料