npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dumb-deploy

v1.0.2

Published

**Simple application deployment for side projects**

Downloads

5

Readme

dumb-deploy

Simple application deployment for side projects

This is a stupid script I use to deploy applications to a remote web server for my side projects with minimal hassle/setup - on a budget!

Install

$ yarn add dumb-deploy

Usage

Here's an example for deploying a containerized docker app:

const deploy = require("dumb-deploy");

/**
 * downCmd should kill any previous instances of the app.
 * Be agressive. We don't provide any context to the previous deployment.
 * Be careful not to kill other applications running on the server.
 * (Don't worry about cleaning up the directory, we'll do that for you.)
 */
async function downCmd() {
  return `docker ps -a --filter="name=nginx" --format "{{.ID}}" | xargs -I{} docker rm --force "{}"`;
}

/**
 * Start the application. Process should not run in the foreground.
 */
async function upCmd({ deployPath }) {
  // https://docs.docker.com/compose/production/#deploying-changes
  return `cd ${deployPath} && docker-compose up --no-deps -d nginx`;
}

async function main() {
  await deploy({
    // Specify a directory-friendly name for this app
    appName: "nginx",
    // Path to the root of your app
    appDir: path.join(__dirname, ".."),
    downCmd,
    upCmd,
    // user/host of the webserver
    user: "mark",
    host: "1.2.3.4",
    // Where should we deploy applications to on the host?
    prodRoot: "/home/mark/prod",
    // Path to an SSH key that we can SSH into the server with
    sshId: "/Users/mark/.ssh/deploy",
  });
}

main();

Here's another example for a NodeJS app:

deploy/deploy.js:

const deploy = require("dumb-deploy");
const path = require("path");

async function downCmd({ deployPath }) {
  return path.join(deployPath, "deploy", "down.sh");
}

async function upCmd({ deployPath }) {
  return path.join(deployPath, "deploy", "up.sh");
}

async function main() {
  await deploy({
    // Specify a directory-friendly name for this app
    appName: "api_server",
    // Path to the root of your app
    appDir: path.join(__dirname, ".."),
    downCmd,
    upCmd,
    // user/host of the webserver
    user: "mark",
    host: "1.2.3.4",
    // Where should we deploy applications to on the host?
    prodRoot: "/home/mark/prod",
    // Path to an SSH key that we can SSH into the server with
    sshId: "/Users/mark/.ssh/deploy",
  });
}

main();

deploy/down.sh:

#!/bin/bash
set -euo pipefail

# https://stackoverflow.com/a/246128/4396258
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
ROOT="${DIR}/.."

# Brutally clean up all old instances of the app running under forever. Life's too short for gracefulness.
# (Make sure to grep filter for our app specifcially tho, to avoid killing other apps running on this server)
ps aux | grep forever | grep build/index.js | awk '{print $2}' | xargs -I{} kill -9 {} || true
lsof -i :44525 | grep node | awk '{print $2}' | xargs -I{} kill -9 {} || true

deploy/up.sh:

#!/bin/bash
set -euo pipefail

# https://stackoverflow.com/a/246128/4396258
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
ROOT="${DIR}/.."

# run commands from the deploy dir root
pushd "${ROOT}"

make build
NODE_ENV=production yarn start
  • When you want to push a new version of your app to your webserver, run your deploy.js script
  • The application files will be rsync'd to a new directory
  • .gitignore files will not rsync'd
  • I'd suggest calling your deploy script manually instead of putting it in a CI pipeline. Since you're artisanally hand crafting your deploy logic, it's probably going to break sometimes if something gets stuck. You'll want to be able to ssh in and unjam things occasionally.

Motivation: What is this for?

  • Side projects that need a server runtime exposed to the world wide web
  • (For simple static websites, one should probably just use vercel or netlify etc)

Why not use <insert SaaS cloud provider here>?

  • I'm cheap, and I want to deploy my side projects to the web for the least amount of money
  • But I also don't want to compromise on availability (e.g. sleeping Heroku dynos)
  • I don't want to deal with complex networking setups to let the DB talk to the API server etc (sorry AWS)
  • I want an actual relational database that lives close to the API server (sorry Fauna)
  • This lets me deploy a Postgres DB, API Server and Web Server all on the same vultr web server for $2.50/month
  • Once the project graduates beyond "side project" to "serious production", you should probably ditch this and seek out a SaaS/AWS solution to get fancy CI pipelines,

Why not use Lambda Functions for everything?

  • I'll appeal to authority: The Good Parts of AWS :

    A problem we often see is that people sometimes mistake Lambda for a general-purpose application host. Unlike EC2, it is very hard to run a sophisticated piece of software on Lambda without making some very drastic changes to your application and accepting some significant new limitations from the platform.

    Treating Lambda as a general-purpose host for your applications is risky. It might look compelling at first—no servers to manage, no operating system to worry about, and no costs when unused—but Lambda’s limitations are insidious hidden risks that typically reveal themselves once your application evolves into something bigger. Then, things start coming at you one after the other, and before you know it, you are spending most of your time trying to figure out convoluted solutions to Lambda’s numerous limitations.

    (I'll avoid quoting further, you should definitely buy the book if you're doing anything with AWS.)

Non goals

  • Rollbacks (maybe I'll add this in the future if I can get the API simple enough)
  • Fancy blue/green deployments. You're probably going to have a couple of minutes of downtime during deploys.