prettifying
This commit is contained in:
353
API.md
Normal file
353
API.md
Normal file
@@ -0,0 +1,353 @@
|
||||
# API with cURL
|
||||
|
||||
Complete guide to tingz API with cURL.
|
||||
|
||||
## Assumptions
|
||||
|
||||
- Running deployer service on http://localhost:8080
|
||||
- Admin token (set in `.env.development` as `ADMIN_TOKEN`) set to `devadmintoken`
|
||||
- API version is `v1`
|
||||
|
||||
## Step 1: Create a User (Admin Only)
|
||||
|
||||
First, an admin needs to create a user account to get a deployment token.
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/api/v1/auth" \
|
||||
-H "Authorization: Bearer devadmintoken" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"alice"}'
|
||||
```
|
||||
|
||||
**Success Response:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"token": "82lz0BVOWtV4uVj9DBZBuKMeyVDwidL2"
|
||||
}
|
||||
```
|
||||
|
||||
**Important:** Save this token! You'll need it for all deployments for that user.
|
||||
|
||||
### Username Requirements
|
||||
- Lowercase letters, numbers, hyphens, underscores only
|
||||
- 1-64 characters
|
||||
- Must start and end with alphanumeric character
|
||||
- Pattern: `^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$`
|
||||
|
||||
## Step 2: Prepare Your Static Site
|
||||
|
||||
Package your static site as a `.tar.gz` file with files at the root level.
|
||||
|
||||
### Correct Way (Files at Root)
|
||||
|
||||
```bash
|
||||
cd /path/to/your/site
|
||||
tar -czf ../site.tar.gz .
|
||||
```
|
||||
|
||||
This creates a tarball where `index.html` is at the root, not nested in a directory.
|
||||
|
||||
### What NOT to Do
|
||||
|
||||
```bash
|
||||
# DON'T: This creates site/index.html (nested)
|
||||
tar -czf site.tar.gz site/
|
||||
|
||||
# DON'T: This creates /path/to/your/site/index.html (nested)
|
||||
tar -czf site.tar.gz /path/to/your/site
|
||||
```
|
||||
|
||||
### Verify Your Tarball
|
||||
|
||||
```bash
|
||||
tar -tzf site.tar.gz | head -5
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
index.html
|
||||
css/
|
||||
css/style.css
|
||||
js/
|
||||
js/app.js
|
||||
```
|
||||
|
||||
NOT:
|
||||
```
|
||||
site/index.html ← Wrong! Nested directory
|
||||
site/css/style.css
|
||||
```
|
||||
|
||||
## Step 3: Deploy Your Site
|
||||
|
||||
Use your user token to deploy the site.
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/api/v1/deploy" \
|
||||
-H "Authorization: Bearer YOUR_USER_TOKEN" \
|
||||
-F "project=myproject" \
|
||||
-F "file=@site.tar.gz"
|
||||
```
|
||||
|
||||
**Success Response:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"project": "myproject",
|
||||
"username": "alice",
|
||||
"url": "https://docs.yigid.dev/alice/myproject/",
|
||||
"release": "20251014T180806"
|
||||
}
|
||||
```
|
||||
|
||||
### Project Name Requirements
|
||||
- Same rules as username
|
||||
- Lowercase, alphanumeric, hyphens, underscores
|
||||
- 1-64 characters
|
||||
- Pattern: `^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$`
|
||||
|
||||
### Important Notes
|
||||
|
||||
- The `@` prefix is required for file uploads: `-F "file=@site.tar.gz"`
|
||||
- Max upload size: 100MB (default, configurable)
|
||||
- Files are deployed to: `/var/www/docs/{username}/{project}/`
|
||||
- Each deployment creates a new release in `/var/www/deploys/{username}/{project}/{release_id}/`
|
||||
- The deploy directory is an atomic symlink to the latest release
|
||||
- Old releases are kept (5 by default) for rollback
|
||||
|
||||
## Step 4: Verify Deployment
|
||||
|
||||
### Check the Symlink
|
||||
|
||||
```bash
|
||||
ls -la docs/alice/myproject
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
lrwxr-xr-x 1 deployer deployer 47 Oct 14 21:08 myproject -> /var/www/deploys/alice/myproject/20251014T180806
|
||||
```
|
||||
|
||||
### Check the Files
|
||||
|
||||
```bash
|
||||
ls -la deploys/alice/myproject/20251014T180806/
|
||||
```
|
||||
|
||||
### Access Your Site
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/alice/myproject/
|
||||
# or
|
||||
curl https://docs.yigid.dev/alice/myproject/
|
||||
```
|
||||
|
||||
## Complete Workflow Example
|
||||
|
||||
```bash
|
||||
# 1. Set your admin token
|
||||
export ADMIN_TOKEN="devadmintoken"
|
||||
|
||||
# 2. Create user and capture token
|
||||
USER_TOKEN=$(curl -s -X POST "http://localhost:8080/api/v1/auth" \
|
||||
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"alice"}' | jq -r '.token')
|
||||
|
||||
echo "User token: ${USER_TOKEN}"
|
||||
|
||||
# 3. Create test site
|
||||
mkdir -p my-site
|
||||
cat > my-site/index.html << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>My Site</title></head>
|
||||
<body><h1>Hello, World!</h1></body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
# 4. Package site
|
||||
tar -czf site.tar.gz -C my-site .
|
||||
|
||||
# 5. Deploy
|
||||
curl -s -X POST "http://localhost:8080/api/v1/deploy" \
|
||||
-H "Authorization: Bearer ${USER_TOKEN}" \
|
||||
-F "project=mysite" \
|
||||
-F "file=@site.tar.gz" | jq
|
||||
|
||||
# 6. Verify
|
||||
curl http://localhost:8080/alice/mysite/
|
||||
```
|
||||
|
||||
## Health Check
|
||||
|
||||
Test if the service is running:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/api/v1/status
|
||||
```
|
||||
|
||||
Expected response:
|
||||
```json
|
||||
{
|
||||
"status": "ok"
|
||||
}
|
||||
```
|
||||
|
||||
## Error Responses
|
||||
|
||||
### Invalid Token
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"error": "unauthorized"
|
||||
}
|
||||
```
|
||||
|
||||
### Invalid Project Name
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"error": "invalid project name format"
|
||||
}
|
||||
```
|
||||
|
||||
### Missing File
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"error": "missing or invalid file"
|
||||
}
|
||||
```
|
||||
|
||||
### Upload Too Large
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"error": "request body too large"
|
||||
}
|
||||
```
|
||||
|
||||
### Path Traversal in Tarball
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"error": "failed to extract tarball: path contains '..' component which is not allowed: ../../etc/passwd"
|
||||
}
|
||||
```
|
||||
|
||||
## User Management (Admin Only)
|
||||
|
||||
### Reroll User Token
|
||||
|
||||
Create a new token for an existing user (invalidates old token):
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/api/v1/auth" \
|
||||
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"alice"}'
|
||||
```
|
||||
|
||||
### Delete User (Keep Files)
|
||||
|
||||
```bash
|
||||
curl -X DELETE "http://localhost:8080/api/v1/auth" \
|
||||
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"alice","files":"persist"}'
|
||||
```
|
||||
|
||||
### Delete User and All Files
|
||||
|
||||
```bash
|
||||
curl -X DELETE "http://localhost:8080/api/v1/auth" \
|
||||
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"alice","files":"delete"}'
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
name: Deploy Documentation
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build site
|
||||
run: |
|
||||
# Your build steps here
|
||||
npm run build
|
||||
|
||||
- name: Package and deploy
|
||||
env:
|
||||
DEPLOYER_TOKEN: ${{ secrets.DEPLOYER_TOKEN }}
|
||||
run: |
|
||||
tar -czf site.tar.gz -C dist .
|
||||
curl -f -X POST "https://deployer.example.com/api/v1/deploy" \
|
||||
-H "Authorization: Bearer ${DEPLOYER_TOKEN}" \
|
||||
-F "project=docs" \
|
||||
-F "file=@site.tar.gz"
|
||||
```
|
||||
|
||||
### GitLab CI
|
||||
|
||||
```yaml
|
||||
deploy:
|
||||
stage: deploy
|
||||
only:
|
||||
- main
|
||||
script:
|
||||
- tar -czf site.tar.gz -C public .
|
||||
- |
|
||||
curl -f -X POST "https://deployer.example.com/api/v1/deploy" \
|
||||
-H "Authorization: Bearer ${DEPLOYER_TOKEN}" \
|
||||
-F "project=docs" \
|
||||
-F "file=@site.tar.gz"
|
||||
variables:
|
||||
DEPLOYER_TOKEN: $DEPLOYER_TOKEN
|
||||
```
|
||||
|
||||
## Tips & Best Practices
|
||||
|
||||
1. **Always use `@` for file uploads**: `-F "file=@your-file.tar.gz"`
|
||||
|
||||
2. **Verify tarball contents** before deploying:
|
||||
```bash
|
||||
tar -tzf site.tar.gz | head -20
|
||||
```
|
||||
|
||||
3. **Use `-f` flag in CI/CD** to fail on HTTP errors:
|
||||
```bash
|
||||
curl -f -X POST ...
|
||||
```
|
||||
|
||||
4. **Pretty-print JSON responses** with `jq`:
|
||||
```bash
|
||||
curl ... | jq
|
||||
```
|
||||
|
||||
5. **Avoid macOS resource forks** in tarballs:
|
||||
```bash
|
||||
COPYFILE_DISABLE=1 tar -czf site.tar.gz -C dist .
|
||||
```
|
||||
|
||||
6. **Check release history**:
|
||||
```bash
|
||||
ls -lt deploys/alice/myproject/
|
||||
```
|
||||
|
||||
7. **Atomic deployments**: The symlink swap is atomic, so no downtime during deployment
|
||||
|
||||
8. **Release retention**: Old releases are kept (5 by default) for manual rollback if needed
|
||||
|
||||
Reference in New Issue
Block a user