---
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!