Deploy from Forgejo
3 min read
Teploy works with any Git remote. Forgejo is the recommended self-hosted option because its webhooks, Actions runner, container registry, and issue workflows cover the full path from source to deployment without adding a hosted dependency.
There are two ways to deploy from Forgejo:
| Path | Best for | Trade-off |
|---|---|---|
| Webhook auto-deploy | The fastest setup | Builds on the server without a CI test gate |
| Forgejo Actions | Teams that require tests before deploy | Requires a Forgejo Actions runner and CI credentials |
Fastest: webhook auto-deploy
From the project directory containing teploy.yml, run:
teploy autodeploy setup --branch mainTeploy uploads the CLI to the target server, installs a systemd-managed webhook listener, and adds a Caddy route. It then prints a webhook URL and a generated secret:
Auto-deploy configured for myapp
Webhook URL: https://myapp.com/teploy-webhook/myapp
Branch: main
Secret (generated — add this to your Git provider's webhook):
<generated-secret>In Forgejo:
- Open the repository's Settings → Webhooks.
- Add a Forgejo webhook using the printed URL.
- Paste the printed secret.
- Enable push events.
Every push to the selected branch now runs the same deployment path as teploy deploy. The application is built on the server, health-checked, and switched over without downtime.
For a private repository, the server user must already have permission to clone and fetch it, normally through an SSH deploy key.
Check or remove the listener with:
teploy autodeploy status
teploy autodeploy removeTest-gated: Forgejo Actions
Teploy does not install or operate a Forgejo Actions runner. If you already have a runner, add this workflow at .forgejo/workflows/deploy.yml:
name: deploy
on:
push:
branches: [main]
env:
IMAGE: ${{ secrets.REGISTRY }}/myapp
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Test
run: make test
- name: Build and push
run: |
TAG="${IMAGE}:${GITHUB_SHA::12}"
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "${{ secrets.REGISTRY }}" -u "${{ secrets.REGISTRY_USER }}" --password-stdin
docker build -t "$TAG" .
docker push "$TAG"
echo "TAG=$TAG" >> "$GITHUB_ENV"
- name: Install Teploy
run: |
curl -fsSLO https://github.com/useteploy/teploy-cli/releases/latest/download/teploy_linux_amd64.tar.gz
curl -fsSLO https://github.com/useteploy/teploy-cli/releases/latest/download/checksums.txt
grep " teploy_linux_amd64.tar.gz$" checksums.txt > checksum.txt
sha256sum -c checksum.txt
tar xzf teploy_linux_amd64.tar.gz
sudo mv teploy /usr/local/bin/
- name: Deploy
run: |
install -m600 /dev/stdin deploy_key <<< "${{ secrets.TEPLOY_SSH_KEY }}"
teploy deploy \
--host "${{ secrets.DEPLOY_HOST }}" \
--user "${{ secrets.DEPLOY_USER }}" \
--key deploy_key \
--image "$TAG"Add these repository secrets under Settings → Actions → Secrets:
| Secret | Purpose |
|---|---|
REGISTRY |
Registry and image namespace, such as forgejo.example.com/team |
REGISTRY_USER |
Registry username |
REGISTRY_PASSWORD |
Registry push credential |
DEPLOY_HOST |
Target server IP or hostname |
DEPLOY_USER |
SSH user on the target server |
TEPLOY_SSH_KEY |
Dedicated private deploy key authorized on the server |
If the image is private, authenticate the target server once so it can pull releases:
teploy registry login forgejo.example.comThe workflow deliberately installs Teploy from its checksummed release archive instead of piping an unverified binary into the runner.