Compare commits
4 Commits
9f05776781
...
1952f4de64
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1952f4de64 | ||
|
|
bdf9fad89f | ||
|
|
c97d31afe4 | ||
|
|
7675b6c299 |
@@ -1,59 +0,0 @@
|
||||
name: Deploy docs for Site
|
||||
run-name: ${{ gitea.actor }} is building out Gitea Actions 🚀
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [20.x]
|
||||
steps:
|
||||
- name: Checkout repository code
|
||||
uses: https://gitea.com/actions/checkout@v4
|
||||
with:
|
||||
ref: 'main'
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
# Skip pnpm cache to reduce overhead
|
||||
- name: Install pnpm
|
||||
run: |
|
||||
if ! command -v pnpm &> /dev/null; then
|
||||
npm install -g pnpm@9
|
||||
else
|
||||
echo "pnpm is already installed"
|
||||
fi
|
||||
|
||||
- name: Check Node.js and pnpm versions
|
||||
run: |
|
||||
echo "pnpm version ===>" && pnpm -v
|
||||
echo "node version ===>" && node -v
|
||||
|
||||
# Simplify node_modules handling without caching
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
if [ ! -d "node_modules" ] || [ "$(find package.json -newer node_modules)" ]; then
|
||||
echo "Dependencies are outdated or missing, installing..."
|
||||
pnpm install
|
||||
else
|
||||
echo "Dependencies are up-to-date, skipping installation."
|
||||
fi
|
||||
|
||||
- name: Build site
|
||||
run: pnpm build
|
||||
|
||||
- name: ssh deploy
|
||||
uses: easingthemes/ssh-deploy@v5.1.0
|
||||
with:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_PRIVATE_KEY }}
|
||||
REMOTE_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
REMOTE_USER: ${{ secrets.DEPLOY_USER }}
|
||||
SOURCE: "/dist/"
|
||||
TARGET: "/opt/1panel/apps/openresty/openresty/www/sites/zhaoguiyang.com/index/dist"
|
||||
EXCLUDE: "/node_modules/"
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -24,3 +24,6 @@ pnpm-debug.log*
|
||||
.idea/
|
||||
|
||||
.trae/
|
||||
|
||||
# deploy script
|
||||
deploy.sh
|
||||
@@ -20,7 +20,7 @@ export const translations = {
|
||||
},
|
||||
hero: {
|
||||
greeting: "Hello, I'm",
|
||||
viewProjects: 'View Projects',
|
||||
viewProjects: 'About Me',
|
||||
contactMe: 'Contact Me',
|
||||
lookingForJob: 'Looking for a Frontend/TS Full-stack Engineer (Remote)? Contact me!',
|
||||
digitalNomad: 'Exploring the freelance journey, striving to become a digital nomad',
|
||||
@@ -77,7 +77,7 @@ export const translations = {
|
||||
},
|
||||
hero: {
|
||||
greeting: '你好,我是',
|
||||
viewProjects: '查看项目',
|
||||
viewProjects: '关于我',
|
||||
contactMe: '联系我',
|
||||
lookingForJob: '正在寻找前端/TS 全栈工程师(远程)?联系我!',
|
||||
digitalNomad: '探索自由职业道路,努力成为数字游民',
|
||||
|
||||
127
src/pages/blog/posts/2024060801.md
Normal file
127
src/pages/blog/posts/2024060801.md
Normal file
@@ -0,0 +1,127 @@
|
||||
---
|
||||
layout: "@/layouts/BlogPostLayout.astro"
|
||||
title: "1Panel Automated Deployment Notes: Say Goodbye to Manual Uploads, One-Command Takeoff from Local"
|
||||
description: "Learn how to build a lightweight deployment pipeline using 1Panel with SSH key authentication and ACL permissions. Complete guide for solo developers to automate server deployments."
|
||||
date: "2024-06-08"
|
||||
image: "https://images.unsplash.com/photo-1558494949-ef010cbdcc31?q=80&w=1470&auto=format&fit=crop"
|
||||
tags: ["1Panel", "DevOps", "Automation", "SSH", "Deployment"]
|
||||
tagId: ["1panel", "devops", "automation", "ssh", "deployment"]
|
||||
category: "DevOps"
|
||||
categoryId: "devops"
|
||||
readTime: "5 min read"
|
||||
---
|
||||
|
||||
Updating code used to make me feel like a "human FTP client":
|
||||
|
||||
1. Package everything locally, sweat included
|
||||
2. Open browser, log into 1Panel (forgot password again?)
|
||||
3. Dig through file manager like an archaeologist
|
||||
4. Manual upload, manual overwrite, plus manual cleanup of old files
|
||||
|
||||
This whole ritual took at least 5 minutes each time, and last week I actually brought the site down for 10 minutes because I forgot to upload a new config file. Enough is enough—I built this lightweight deployment pipeline. No heavy Jenkins setup needed, perfect for solo developers or small projects. Fast, reliable, and nobody else to blame.
|
||||
|
||||
## 1. Create a "Deployment Runner" Account
|
||||
|
||||
Running scripts as root? That's like performing surgery with a chainsaw. Let's create a dedicated account just for deployments.
|
||||
|
||||
```bash
|
||||
# Create the deployment account
|
||||
sudo adduser deploy_user
|
||||
|
||||
# Critical: disable password login, SSH keys only
|
||||
# Even if someone guesses the password, they can't get in
|
||||
# -l locks the password account (disabled password login)
|
||||
# -u unlocks the password account (if you need enabled password login)
|
||||
sudo passwd -l deploy_user
|
||||
```
|
||||
|
||||
## 2. The Permission Puzzle: ACL to the Rescue
|
||||
|
||||
Here's the tricky part: 1Panel has its own permission system. If you `chown` everything to your deployment user, websites in the panel might start throwing 500 errors.
|
||||
|
||||
My solution: **ACL** (Access Control Lists). Think of it as giving your deployment user a "VIP backstage pass"—it can read/write files without messing with 1Panel's original file ownership.
|
||||
|
||||
```bash
|
||||
# Install ACL tools first
|
||||
sudo apt install acl -y
|
||||
|
||||
# Grant access to sites directory (make sure this is your web root)
|
||||
# -R means recursive, but be careful if directory has other sites
|
||||
sudo setfacl -R -m u:deploy_user:rwx /opt/1panel/www/sites
|
||||
|
||||
# Set default inheritance: new sites get access automatically
|
||||
sudo setfacl -R -d -m u:deploy_user:rwx /opt/1panel/www/sites
|
||||
```
|
||||
|
||||
## 3. SSH Key Access: No More Password Typing
|
||||
|
||||
Copy your local SSH public key to the server, and never type a password again.
|
||||
|
||||
```bash
|
||||
# Create SSH directory for deployment user
|
||||
sudo -u deploy_user mkdir -p /home/deploy_user/.ssh
|
||||
|
||||
# Append your public key (using >> not > to avoid overwriting)
|
||||
echo "your-ssh-public-key-content" >> /home/deploy_user/.ssh/authorized_keys
|
||||
|
||||
# Permissions must be exact, or SSH will refuse
|
||||
sudo chown -R deploy_user:deploy_user /home/deploy_user/.ssh
|
||||
sudo chmod 700 /home/deploy_user/.ssh
|
||||
sudo chmod 600 /home/deploy_user/.ssh/authorized_keys
|
||||
```
|
||||
|
||||
**Even lazier method**: If you have `ssh-copy-id` locally, just run `ssh-copy-id deploy_user@your-server-ip`.
|
||||
|
||||
## 4. SSH Aliases (For the Truly Lazy)
|
||||
|
||||
Memorize IP addresses? Not in this decade. Add this to your local `~/.ssh/config`:
|
||||
|
||||
```text
|
||||
Host your-server-alias # Nickname for your server
|
||||
HostName your-server-ip-address # Your server IP
|
||||
User deploy_user # Login user
|
||||
IdentityFile ~/.ssh/id_rsa # Private key path
|
||||
```
|
||||
|
||||
Now just type `ssh your-server-alias` and you're in. Magic.
|
||||
|
||||
## 5. The Grand Finale: One-Command Deployment
|
||||
|
||||
Create `deploy.sh` in your project root:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# For frontend projects, build first
|
||||
# echo "📦 Building..."
|
||||
# npm run build
|
||||
|
||||
echo "🚀 Syncing to production..."
|
||||
# rsync for incremental updates
|
||||
# -a: archive mode (preserves everything)
|
||||
# -v: verbose (show me what's happening)
|
||||
# -z: compress during transfer
|
||||
# --delete: ⚠️ Warning: removes files on target that don't exist locally!
|
||||
# Remove this flag for first sync to be safe
|
||||
rsync -avz --delete --progress ./dist/ your-server-alias:/opt/1panel/www/sites/your-project-directory/
|
||||
|
||||
echo "✅ Deployment complete!"
|
||||
echo "⏱️ Next time just run: ./deploy.sh"
|
||||
```
|
||||
|
||||
Make it executable: `chmod +x deploy.sh`. Now deploying is literally one command.
|
||||
|
||||
## 6. Pitfalls I Stepped In (So You Don't Have To)
|
||||
|
||||
1. **Skip `--delete` on first sync**: Do a dry run first. This flag can delete important files if you're not careful.
|
||||
2. **Check ACL permissions**: If files still have permission issues, run `getfacl /opt/1panel/www/sites/your-project` to verify.
|
||||
3. **Verify paths**: 1Panel's default path is `/opt/1panel/www/sites/`, but check if you customized it.
|
||||
4. **Frontend projects**: Don't upload `node_modules`. Your server doesn't need that 200MB baggage.
|
||||
|
||||
## Wrapping Up
|
||||
|
||||
I've been using this setup for weeks, and it just works. What used to be a 5-minute chore is now a 30-second command. The mental load is gone—no more "did I forget that one file?" anxiety.
|
||||
|
||||
For small to medium projects that don't need full CI/CD complexity, this lightweight approach is perfect. A few minutes to set up, a lifetime of easy deployments.
|
||||
|
||||
**Final reminder**: Automation is powerful but dangerous. Test with a dummy directory first, especially before using `--delete`. Happy deploying, and may your uptime be forever!
|
||||
127
src/pages/zh/blog/posts/2024060801.md
Normal file
127
src/pages/zh/blog/posts/2024060801.md
Normal file
@@ -0,0 +1,127 @@
|
||||
---
|
||||
layout: "@/layouts/BlogPostLayout.astro"
|
||||
title: "1Panel 自动化部署笔记:告别\"手动操作\",本地一键起飞"
|
||||
description: "学习如何基于 1Panel 构建轻量级部署流水线,配合 SSH 密钥认证和 ACL 权限管理。本文为单兵作战的开发者提供了完整的自动化部署方案。"
|
||||
date: "2024-06-08"
|
||||
image: "https://images.unsplash.com/photo-1558494949-ef010cbdcc31?q=80&w=1470&auto=format&fit=crop"
|
||||
tags: ["1Panel", "DevOps", "自动化", "SSH", "部署"]
|
||||
tagId: ["1panel", "devops", "automation", "ssh", "deployment"]
|
||||
category: "DevOps"
|
||||
categoryId: "devops"
|
||||
readTime: "5 min read"
|
||||
---
|
||||
|
||||
以前每次更新代码,都感觉自己像个"人肉传输带":
|
||||
|
||||
1. 本地吭哧吭哧打包
|
||||
2. 打开浏览器,输密码登录 1Panel 面板
|
||||
3. 在文件管理器里翻来覆去找目录
|
||||
4. 手动上传、手动覆盖,有时候还得手动删服务器上的旧文件,就怕哪个缓存文件没清干净
|
||||
|
||||
这一套流程下来,没个三五分钟搞不定,关键还特别容易漏文件。上周就因为我忘记上传一个新加的配置文件,线上挂了十分钟才反应过来。痛定思痛,我决定搞一套轻量级部署方案——不用整 Jenkins 那种大炮打蚊子,特别适合我这种单兵作战的小项目,要的就是快、稳、不求人。
|
||||
|
||||
## 1. 先整个"跑腿小弟"账号
|
||||
|
||||
用 root 跑脚本?那太野了,万一脚本写崩了,服务器直接原地升天。得建个专门干这活的"小弟账号"。
|
||||
|
||||
```bash
|
||||
# 创建专门负责部署的账号
|
||||
sudo adduser deploy_user
|
||||
|
||||
# 关键一步:禁用这个账号的密码登录,只认 SSH 密钥
|
||||
# 这样就算有人猜到密码也进不来,安全第一
|
||||
# -l 锁定账号密码(禁用密码登录)
|
||||
# -u 解锁账号密码(如需恢复密码登录)
|
||||
sudo passwd -l deploy_user
|
||||
```
|
||||
|
||||
## 2. 权限难题的"优雅解法":ACL 授权
|
||||
|
||||
这里有个坑:1Panel 管理的文件有自己的一套权限体系,如果你用 `chown` 强行改属主,面板里的网站可能就直接 500 错误了。
|
||||
|
||||
我的解决方案是 **ACL**(访问控制列表)。这玩意就像给文件加了张"访客通行证",让 `deploy_user` 这个账号能读写文件,但又不会破坏 1Panel 原本的文件归属关系。
|
||||
|
||||
```bash
|
||||
# 先安装 ACL 工具
|
||||
sudo apt install acl -y
|
||||
|
||||
# 给 sites 目录开绿灯(注意:确认这是你的网站根目录)
|
||||
# -R 表示递归,但如果目录里已有其他站点,建议先备份或确认操作
|
||||
sudo setfacl -R -m u:deploy_user:rwx /opt/1panel/www/sites
|
||||
|
||||
# 设置默认权限继承:以后在面板里新建的站点,自动给 deploy_user 权限
|
||||
sudo setfacl -R -d -m u:deploy_user:rwx /opt/1panel/www/sites
|
||||
```
|
||||
|
||||
## 3. SSH 免密登录:从此进出如风
|
||||
|
||||
把你本地电脑的 SSH 公钥塞到服务器上,以后就不用输密码了。
|
||||
|
||||
```bash
|
||||
# 切换到部署账号的家目录
|
||||
sudo -u deploy_user mkdir -p /home/deploy_user/.ssh
|
||||
|
||||
# 追加你的公钥(用 >> 而不是 >,避免覆盖别人的密钥)
|
||||
echo "your-ssh-public-key-content" >> /home/deploy_user/.ssh/authorized_keys
|
||||
|
||||
# 权限必须严格设置,否则 SSH 会拒绝连接
|
||||
sudo chown -R deploy_user:deploy_user /home/deploy_user/.ssh
|
||||
sudo chmod 700 /home/deploy_user/.ssh
|
||||
sudo chmod 600 /home/deploy_user/.ssh/authorized_keys
|
||||
```
|
||||
|
||||
**更懒的方法**:如果你本地有 `ssh-copy-id` 命令,直接 `ssh-copy-id deploy_user@your-server-ip-address`。
|
||||
|
||||
## 4. SSH 别名配置(懒癌患者的福音)
|
||||
|
||||
记 IP 地址?不存在的。在本地 `~/.ssh/config` 文件里加一段:
|
||||
|
||||
```text
|
||||
Host your-server-alias # 给你服务器起的外号,随便起,好记就行
|
||||
HostName your-server-ip-address # 你的服务器 IP
|
||||
User deploy_user # 登录用户
|
||||
IdentityFile ~/.ssh/id_rsa # 私钥路径
|
||||
```
|
||||
|
||||
配置完,以后登录就直接 `ssh your-server-alias`,爽!
|
||||
|
||||
## 5. 终极一击:一键部署脚本
|
||||
|
||||
在项目根目录创建 `deploy.sh`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# 如果是前端项目,先打包
|
||||
# echo "📦 正在打包..."
|
||||
# npm run build
|
||||
|
||||
echo "🚀 开始同步到生产环境..."
|
||||
# 使用 rsync 增量同步
|
||||
# -a: 归档模式,保持文件属性
|
||||
# -v: 显示详细过程
|
||||
# -z: 压缩传输
|
||||
# --delete: ⚠️ 注意:这会删除目标端有而源端没有的文件!
|
||||
# 首次同步建议先去掉这个参数,确认无误后再加上
|
||||
rsync -avz --delete --progress ./dist/ your-server-alias:/opt/1panel/www/sites/your-project-directory/
|
||||
|
||||
echo "✅ 部署完成!"
|
||||
echo "⏱️ 下次更新只需: ./deploy.sh"
|
||||
```
|
||||
|
||||
给脚本执行权限:`chmod +x deploy.sh`,以后部署就是一行命令的事儿。
|
||||
|
||||
## 6. 我踩过的坑和注意事项
|
||||
|
||||
1. **首次同步别用 `--delete`**:先完整同步一次,确认文件都对,再加这个参数。不然可能把服务器上的重要文件删了。
|
||||
2. **ACL 权限检查**:如果同步后还是没权限,可以用 `getfacl /opt/1panel/www/sites/your-project-directory` 看看 ACL 设置是否生效。
|
||||
3. **文件路径要对**:1Panel 的默认站点路径是 `/opt/1panel/www/sites/`,但如果你改过,记得调整。
|
||||
4. **前端项目注意**:打包前清理 `node_modules`,这玩意别传到服务器。
|
||||
|
||||
## 总结
|
||||
|
||||
这套方案我从上周用到现在,真香!以前更新一次至少折腾5分钟,现在30秒搞定。关键是心理负担小了——再也不用担心漏传文件,`rsync` 会帮我搞定一切。
|
||||
|
||||
对于还没到需要 CI/CD 的中小型项目,这种轻量级方案简直完美。几分钟配置,一劳永逸。如果你也在用 1Panel,又被手动上传困扰,试试这个方案吧。
|
||||
|
||||
**最后提醒**:任何自动化操作都有风险,尤其是删除操作。第一次在生产环境用的时候,建议先找个测试目录跑一遍,确认无误再上。祝大家部署顺利,永不宕机!
|
||||
Reference in New Issue
Block a user