Skip to content

abdullahxdev/launchd

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ launchd

A simple, no-nonsense deployment tool for Go applications on Linux servers with systemd

Go Linux License


πŸ“– Overview

launchd is a lightweight CI/CD helper that deploys Go binaries to Linux servers from your laptop. No Docker, no complex pipelinesβ€”just simple, effective deployments using SSH and systemd.

✨ What it does

  • πŸ”¨ Build your Go app locally
  • πŸ“¦ Copy the binary to your server over SSH
  • βš™οΈ Create/refresh a systemd service
  • πŸ—„οΈ Run database migrations (optional)
  • βœ… Verify health before finishing

Perfect for side projects, MVPs, and small-scale deployments where simplicity matters.


πŸ“‹ Prerequisites

Before you start, make sure you have:

πŸ’» On Your Local Machine

  • βœ“ Go installed (1.21+)
  • βœ“ OpenSSH client (ssh, scp)
  • βœ“ A Go project with a main package

πŸ–₯️ On Your Server

  • βœ“ Linux with systemd (Ubuntu, Debian, CentOS, Fedora, etc.)
  • βœ“ SSH access with sudo privileges
  • βœ“ Network port open (e.g., 8080)

πŸ₯ In Your Application

  • βœ“ Health endpoint (e.g., GET /health β†’ 200 OK)
  • βœ“ Configurable port (via flag or environment variable)

πŸ”§ Installation

1. Clone the repository

git clone https://github.com/yourusername/launchd.git
cd launchd

2. Build the CLI

go build -o launchd ./cmd/launchd

3. (Optional) Add to PATH

sudo mv launchd /usr/local/bin/

Verify installation:

launchd --version

🎯 Quick Start

Prepare Your Application

Ensure your app builds locally:

go build -o ./bin/myapp ./path/to/your/cmd

Make sure it:

  • Accepts a port configuration (flag or env var)
  • Exposes a /health endpoint that returns 200 OK

Deploy in One Command

launchd deploy \
  --host your-server.com \
  --user deploy \
  --app ./bin/myapp \
  --port 8080 \
  --timeout 60s

πŸŽ‰ That's it! Your app is now running as a systemd service.


πŸ” How It Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. BUILD    β”‚  Compile Go binary locally
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚
β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚ 2. TRANSFER β”‚  SCP binary to server
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚
β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚ 3. SERVICE  β”‚  Create/update systemd unit
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚
β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚ 4. MIGRATE  β”‚  Run DB migrations (optional)
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚
β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚ 5. VERIFY   β”‚  Health check polling
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Under the Hood

  1. Build: Uses your local Go toolchain to compile the binary
  2. Transfer: Copies via scp to /usr/local/bin/<app>
  3. Service: Generates systemd unit file and runs:
    • systemctl daemon-reload
    • systemctl enable <app>
    • systemctl restart <app>
  4. Migrate: Executes migration tool if configured
  5. Health Check: Polls http://<host>:<port>/health until success

πŸ› οΈ Command Reference

Basic Deployment

launchd deploy --host <server> --user <username> --app <binary> --port <port>

With Migrations

launchd deploy \
  --host server.com \
  --user deploy \
  --app ./bin/myapp \
  --port 8080 \
  --migrate \
  --migration-cmd "migrate -path /path/to/migrations -database postgres://..."

Custom Health Endpoint

launchd deploy \
  --host server.com \
  --user deploy \
  --app ./bin/myapp \
  --port 8080 \
  --health-path /api/health

πŸ› Troubleshooting

SSH Connection Fails

# Test SSH access first
ssh deploy@your-server.com

Solutions:

  • Verify SSH keys are set up: ssh-copy-id deploy@your-server.com
  • Check firewall rules allow SSH (port 22)

Sudo Permission Denied

Problem: User cannot run systemctl without password

Solution: Add sudo permissions for systemctl:

# On the server, edit sudoers
sudo visudo

# Add this line (replace 'deploy' with your username)
deploy ALL=(ALL) NOPASSWD: /bin/systemctl, /usr/bin/install

Port Already in Use

# Check what's using the port
sudo lsof -i :8080

# Stop the conflicting service
sudo systemctl stop conflicting-service

Health Check Fails

Possible causes:

  • App takes too long to start (increase --timeout)
  • Wrong port or health endpoint path
  • App crashes on startup

Check logs:

ssh deploy@server.com 'sudo journalctl -u myapp.service -f'

View Service Status

# Check if service is running
ssh deploy@server.com 'sudo systemctl status myapp.service'

# View recent logs
ssh deploy@server.com 'sudo journalctl -u myapp.service --since "10 minutes ago"'

πŸ”„ Managing Your Service

View Status

ssh user@server 'sudo systemctl status myapp.service'

View Logs

# Follow logs in real-time
ssh user@server 'sudo journalctl -u myapp.service -f'

# Last 100 lines
ssh user@server 'sudo journalctl -u myapp.service -n 100'

Restart Service

ssh user@server 'sudo systemctl restart myapp.service'

Stop Service

ssh user@server 'sudo systemctl stop myapp.service'

Remove Service Completely

ssh user@server << 'EOF'
sudo systemctl stop myapp.service
sudo systemctl disable myapp.service
sudo rm -f /usr/local/bin/myapp
sudo rm -f /etc/systemd/system/myapp.service
sudo systemctl daemon-reload
EOF

πŸ” Re-deploying

Good news: launchd is idempotent! You can run the same deploy command multiple times safely.

# Make changes to your code
# Then deploy again
launchd deploy --host server.com --user deploy --app ./bin/myapp --port 8080

What happens:

  • βœ… Binary is overwritten with new version
  • βœ… Service is restarted with zero-downtime goal
  • βœ… Health check confirms new version is running

❓ FAQ

Do I need Docker?

No! launchd deploys native binaries directly. No containers required.

Do I need Go installed on the server?

No. Building happens locally on your machine. The server only runs the pre-compiled binary.

Do I need root access?

You need a user with sudo privileges to:

  • Copy files to /usr/local/bin
  • Manage systemd services

You don't need to log in as root directly.

Can I deploy to multiple servers?

Yes! Run the deploy command once per server, or write a simple bash loop:

for server in server1.com server2.com server3.com; do
  launchd deploy --host $server --user deploy --app ./bin/myapp --port 8080
done
What about environment variables?

Add them to your systemd service file or use a tool like envdir. Future versions of launchd may support this natively.

Is this production-ready?

launchd works great for:

  • βœ… Side projects
  • βœ… MVPs and prototypes
  • βœ… Internal tools
  • βœ… Small-scale production apps

For large-scale production with complex requirements, consider Kubernetes, Nomad, or managed platforms.


🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ™ Acknowledgments

Built with ❀️ for developers who prefer simplicity over complexity.

Why launchd? Because sometimes you just want to ship code, not configure orchestrators.


Documentation β€’ Installation β€’ Quick Start β€’ Troubleshooting

Made with Go β€’ Deployed with launchd

About

We compress build systems, transport, and orchestration into one command.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 98.2%
  • Makefile 1.8%