One script to setup for push to deploy.
Zero-friction code deployment. Full control. No dashboards. No configs. One script.
- Prefer console over clicks
- Expect production-ready servers in seconds
- Trust GitHub as source of truth
- Want to run everything in Containers
- Love tools they can read in one screen
- Believe SSL Certificate handling should require no work
Harp00n is a bash script it set up your fresh new Linux host (Ubuntu 24.10 or later) in such a way that when you commit to github, your code is automatically pulled and deployed. Harp00n also automatically obtains an SSL certificate and sets up a GitHub webhook for you.
Your deplyment can be a simple web server or a more complex set of containers.
Below we provide examples of how to deploy containers using Harp00n.
-
You create a github repo containing the code you want to deploy (including the harp00n-run.sh as explained below)
-
You obtain a github token with permission to clone the repo and setup webhooks
-
You provision a new Linux host (we only support Ubuntu 24.10 or later at this time). For example on DigitalOcean:
-
Setup a DNS record for your host.
-
You download and run once harp00n on the host (this is the only command)
curl https://raw.githubusercontent.com/unofficialtools/harp00n/refs/heads/main/harp00n.sh | bash -s -- --domain={yourdomain} --repository={username}/{reponame} --github_token={yourtoken} -
Done!
-
Try push something the "production" branch of your repo. Every time you push to branch "production", harp00n will grab it and run "harp00n-run.sh" from within your repo. This script should run (not start, run!) the service. If a web service listen to port 8000.
-
Check your webhook page after deployments:
The source is here but no need to clone it to use it.
harp00n-run.sh is a file that must be at the root of the repo you want to deploy. It could be as simple as:
mkdir -p static
echo "hello world" > static/index.html
uv run python -m http.server 8000 -d static
After commit to the production branch, your page will be available at https://{yourdmain}/index.html
Here are some requirements:
- It must block while the service runs
- It shoud not prompt the user
- It could run a container using podman or podman-compose (without -d option)
- If you start a web server, use port 8000, and harp00n will proxy from https automatically
- You can count on uv, podman, and podman-compose installed by harp00n
- If you use podman or podman compose make sure to use "network-mode: pasta" or your service will be blocked by the firewall.
Ideally everything you want to run on the server will be in containers (run via podman) and init.sh should contain the commands to start/restart the containers.
git push origin production
Yes. That's it.
https://github.com/unofficialtools/harp00n-examples/
- A simple python server for static files python-http-server
- A Flask service flask-simple
- A py4web service py4web-simple
- A py4web service using a Dockerfile with Podman docker-podman-py4web-simple
- A py4web service using a docker-compose.yaml with Podman docker-podman-py4web-compose
To test the examples:
-
Fork and clone git@github.com:unofficialtools/harp00n-examples.git
-
Configure your server as explained above and make it point to your new forked repo.
-
Run locally:
git checkout production git reset --hard python-http-server git push --force origin production
- The deplyed code will be under /user/share/harp00n/checkout
- harp00n-run.sh will run as user harp00n which does not have sudo access
- We use Podman instead of Docker to avoid running as root
- The deployment logs are stored in github under the webhooks for your repo.
- Harp00n will logs its own service (which uses localhost:8111) to /var/log/harp00n/8111/current
- Harp00n will logs the output of harp00n-run.sh (which uses localhost:8000) to /var/log/harp00n/8000/current
- For both logs it performs automatic rotation.
This tool is new and constantly improving, so check this page before using it. Nevertheless, you are only supposed to setup the script once to setup your system. So even we change harp00n, we do not break your workflow.
