使用 Jenkins + Docker 在服务器上部署前端项目(指南)
本文档介绍如何在 Linux 服务器上安装 Docker 与 Jenkins,并使用 Jenkins Pipeline 自动构建镜像、替换环境变量并运行前端容器。文中示例与仓库内 Jenkinsfile 思路一致(注意不要把私密 token 直接写入仓库)。
目标
- 在服务器上安装 Docker
- 在服务器上安装并配置 Jenkins(或以容器方式运行 Jenkins)
- 在 Jenkins 中创建参数化 Pipeline,拉取代码、构建镜像并运行容器
先决条件
- 一台 Linux 服务器(本文以 Ubuntu/Debian 为主,另有 CentOS/RHEL 命令注记)
- 有 sudo 权限的用户
使用 WSL 在本地快速验证(替代服务器)
如果你没有或不想使用远程服务器,WSL(Windows Subsystem for Linux)是在本地快速验证 Jenkins + Docker 部署流程的可行方案。作为没接触过后端的前端,只能以这种方式来试错了,以下为快速流程与注意事项:
- 安装 WSL(Windows 10/11):
# 在 PowerShell(管理员)中运行:
wsl --install -d ubuntu
# 安装完成后重启并打开 Ubuntu 终端,直接搜索Ubuntu,如下图
以上我们就已经拥有了一个简单的本地服务器.
- 在 WSL 内安装 Docker:
如果选择在 WSL 内直接安装 Docker Engine,请参考官方文档并确保 systemd/docker 服务可用(某些 WSL 发行版需额外配置)。
1. 在服务器上安装 Docker(Ubuntu 示例)
# 更新并安装依赖
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
# 添加 Docker 官方 GPG 并设置仓库
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 将当前用户加入 docker 组(重登录后生效)
sudo usermod -aG docker $USER
CentOS/RHEL 可参考 Docker 官方文档,基本步骤为添加 yum 源并安装 docker-ce。
验证 Docker:
docker version
docker run --rm hello-world
其他命令:
# 开机自启动并立即启动
sudo systemctl enable --now docker
# 手动启动/停止/查询
sudo systemctl start docker
sudo systemctl stop docker
sudo systemctl status docker
特别要注意docker拉取镜像默认走的官方源,而国内经常访问不过去,只能找一些加速源,本人AI查了也没找到一个可用的源,最后朋友发了一个可用的,这里也贴出如何配置这个镜像源:
#编辑镜像源的config
nano /etc/docker/daemon.json
#查看当前文件内容
cat /etc/docker/daemon.json
使用docker拉取镜像:
#拉取官方源
docker pull node:18-alpine
#拉取指定镜像源
docker pull registry.example.com/library/node:18
2. 安装 Jenkins
方法 A:使用系统包(Ubuntu/Debian)
这里不多说,直接参考jenkins官方文档: www.jenkins.io/doc/book/in…
要注意jdk版本要对应jenkins版本,否则后续启动就会出错,本人在这里踩坑了,最后直接对照官方文档去做就一次性过
# 开机自启动并立即启动
sudo systemctl enable --now jenkins
# 手动启动/停止/查询
sudo systemctl start jenkins
sudo systemctl stop jenkins
sudo systemctl status jenkins
当你按照官方文档进行安装和启动后就可以打开一个jenkins的登录地址,安装指导初始化账号和密码,下图本人设置好了:
3. Jenkins 初始配置与插件
- 打开
http://localhost:8080,按页面提示完成解锁和初始管理员用户创建。 - 推荐安装插件:Git, Pipeline, GitHub, Credentials, Docker Pipeline, SSH Agent, Blue Ocean(可选)
在 Credentials 中添加:
- Git 访问的凭据(推荐使用 Personal Access Token 或 SSH Key),示例
ID:github-key-id。在 Pipeline 的git步骤中通过credentialsId使用它。
4. 在 Jenkins 中创建参数化 Pipeline 作业
在新建 Job 时选择 Pipeline,勾选 This project is parameterized,添加参数:
BranchToBuild(String)默认main或masterSUBMENU_BGCOLOR(String)如果需要在构建时替换 env.js 中的值
在 Pipeline 脚本中可以直接使用 pipeline 或使用仓库中的 Jenkinsfile(推荐把 Jenkinsfile 放在代码仓库里)。本人直接使用了pipeline,我的script如下:
pipeline {
agent any
environment {
DOCKER_IMAGE = 'my-vite-app'
DOCKER_TAG = 'latest'
}
stages {
stage('Delete Workspace') {
steps {
cleanWs()
}
}
stage('Checkout') {
steps {
echo 'Current Branch: '
echo "${params.BranchToBuild}"
#用凭据而非在 URL 中写 token
git branch: params.BranchToBuild, credentialsId: 'github-token-id', url: 'https://example.com/vite-demo-test.git'
}
}
stage('Stop Old Container') {
steps {
sh 'docker stop ${DOCKER_IMAGE} || true'
sh 'docker rm ${DOCKER_IMAGE} || true'
sh 'docker rmi ${DOCKER_IMAGE}:${DOCKER_TAG} || true'
}
}
stage('Replace env variable') {
steps {
echo 'Current SUBMENU_BGCOLOR: '
echo "${params.SUBMENU_BGCOLOR}"
sh '''
#!/bin/bash
sed -i "s/'\\\$SUBMENU_BGCOLOR'/'${SUBMENU_BGCOLOR}'/g" public/env.js
'''
}
}
stage('Docker Build') {
steps {
sh "docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} ."
}
}
stage('Run New Container') {
steps {
sh "docker run -d --name ${DOCKER_IMAGE} -p 80:9080 ${DOCKER_IMAGE}:${DOCKER_TAG}"
}
}
}
}
注意以上script里有两个value:params.BranchToBuild 和params.SUBMENU_BGCOLOR,这两个参数是jenkins配置参数,第一个配置的是拉取的git分支,第二个是前端页面的背景颜色,那是如何config的?如下图,其中背景颜色是通过sh脚本改了前端项目下env.js的参数值,这样就依据不同的场配置不同的参数,当然这种适合小型项目.
说明:把 https://your.git.server/your/repo.git 替换为你的仓库地址,并在 Jenkins 的凭据中添加对应的 credentialsId(例如 github-key-id)。切勿将 Personal Access Token 直接写入 Jenkinsfile 或仓库。
6. 容器化部署与替换环境变量
- 上述 Pipeline 在构建前通过
sed替换public/env.js中的占位符;如果使用其它方式管理运行时配置(例如 nginx 入口替换、运行时读取环境变量或使用配置文件),可按需调整。 - 如果希望端口从 9080 转到 80(宿主机 80),示例中
docker run -p 80:9080会将容器 9080 映射到宿主 80。 从我的script见到有docker build,而这里也需要把Dockerfile文件写好放进前端项目的更目录下,以及都是部署在nginx服务器上,因此也要放nginx config进前端项目里,我的dockerfile如下:
# Stage 1: Build the React application
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install --force
COPY . .
RUN npm run build
# Stage 2: Serve the static files with Nginx
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 9080
nginx config:
server {
listen 9080;
server_name localhost;
client_max_body_size 11M;
location /svc/ {
rewrite ^/svc/(.*)$ /$1 break;
proxy_pass http://xxxxx:8080/;
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;
proxy_connect_timeout 1000;
proxy_read_timeout 1000;
proxy_send_timeout 1000;
proxy_cache_valid any 0;
}
location = /index.html {
root /usr/share/nginx/html;
expires off;
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_log /var/log/nginx/error.log debug;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
而docker的知识就不在这说明了,自行AI吧。
注意:若宿主机上已有服务占用 80 端口,需先停止或选择其它端口。 注意本人在dockerfile构建了多阶段的内容,第二阶段已经把nginx服务build进镜像了,因此服务器上不需要再安装nginx,而jenkins脚本里用到了docker来做集成和部署,因此服务器需要先安装好docker服务,jenkins不会自行安装
7 常见问题排查
- 如果 Jenkins 无法拉取代码:检查
credentialsId是否正确、凭据是否有权限、Webhook/网络是否通畅。 - 如果
docker build报错:在 Jenkins 节点上手动运行docker build验证环境,一般是 Docker 权限或上下文问题。 sed替换无效:确认public/env.js中的占位符格式,与sed的匹配模式一致并注意转义。
8 安全建议
- 永远使用 Jenkins 的 Credentials 管理凭据,避免在 Jenkinsfile 或仓库中写明明文 token。
- 生产环境建议在私有网络或使用 VPN 访问 Jenkins,限制访问来源并开启 HTTPS。