Deployment Locks
How HostFn prevents concurrent deployments from conflicting with each other.
HostFn uses a file-based locking mechanism to prevent concurrent deployments to the same environment. This ensures that two developers (or CI/CD pipelines) cannot deploy to the same server at the same time, which could cause corrupted builds or unpredictable state.
How Locks Work
When a deployment starts, HostFn creates a lock file on the remote server. If a lock file already exists and is not stale, the deployment is rejected with an error. When the deployment finishes (whether it succeeds or fails), the lock is released.
Lock Lifecycle
1. Deploy starts → Lock acquired
2. Sync, build, etc. → Lock held
3. Deploy completes → Lock released
OR
3. Deploy fails → Lock released (auto-rollback runs first)Lock File Location
The lock file is stored on the remote server at:
/var/www/{name}-{env}/.hostfn-deploy.lockFor example:
/var/www/my-api-production/.hostfn-deploy.lockLock File Contents
The lock file contains a JSON object with information about the deployment that created it:
{
"pid": 12345,
"user": "developer",
"timestamp": 1741700000000,
"hostname": "dev-laptop"
}| Field | Description |
|---|---|
pid | Process ID of the deploying CLI instance |
user | Username of the person running the deployment (from $USER) |
timestamp | Unix timestamp (milliseconds) when the lock was acquired |
hostname | Hostname of the machine running the deployment (from $HOSTNAME) |
This information helps you identify who started the deployment and when, which is useful for debugging lock conflicts.
Stale Lock Detection
Locks automatically expire after 5 minutes (300 seconds). If HostFn encounters an existing lock file that is older than 5 minutes, it treats it as stale, removes it, and proceeds with the deployment.
This handles cases where a deployment process was killed without releasing the lock (e.g., the developer's machine lost network connectivity or the process was terminated with kill -9).
⠋ Acquiring deployment lock...
⚠ Found stale lock file, removing...
✔ Deployment lock acquiredLock Conflict
When a valid (non-stale) lock is in place, HostFn displays information about the existing deployment and exits:
✗ Could not acquire deployment lock
✗ Deployment is already in progress
ℹ Started by: developer
ℹ Started at: 3/11/2026, 2:30:00 PM
ℹ Age: 2 minute(s)
⚠ Wait for the current deployment to finish or:
1. Wait for lock to expire (5 minutes)
2. Manually remove: ssh <host> rm /var/www/my-api-production/.hostfn-deploy.lockManual Lock Removal
If you know that no deployment is actually running (e.g., the deploying machine crashed), you can manually remove the lock file:
ssh ubuntu@your-server.com "rm /var/www/my-api-production/.hostfn-deploy.lock"After removing the lock, you can deploy normally.
Lock Behavior in Error Scenarios
HostFn always releases the lock in its finally block, regardless of what happens during deployment:
| Scenario | Lock Released |
|---|---|
| Successful deployment | Yes |
| Build failure (with auto-rollback) | Yes |
| Health check failure (with auto-rollback) | Yes |
| SSH connection lost | No (expires after 5 minutes) |
| CLI process killed (SIGKILL) | No (expires after 5 minutes) |
| Lock file manually deleted during deploy | Deployment continues normally |
CI/CD Considerations
In CI/CD pipelines, lock conflicts are more common because multiple pipelines might try to deploy the same environment simultaneously. Consider the following approaches:
Serialize Deployments
Most CI/CD systems support concurrency limits. For example, in GitHub Actions:
concurrency:
group: deploy-production
cancel-in-progress: falseThis ensures only one deployment workflow runs at a time for the production group.
Retry on Lock Conflict
If your CI/CD pipeline encounters a lock conflict, you can retry the deployment after a delay:
- name: Deploy
run: hostfn deploy production --ci
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_KEY }}
timeout-minutes: 10The 5-minute stale lock timeout means any lock conflict will resolve itself within that window.