365 lines
7.8 KiB
Markdown
365 lines
7.8 KiB
Markdown
# 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`
|
|
- **Note:** The deployer service only handles API requests (`/api/v1/*`). For serving deployed static sites, you need a separate web server (Caddy, nginx, etc.) configured to serve files from `/var/www/docs`
|
|
|
|
## 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
|
|
|
|
**Note:** The deployer service only handles API requests. Deployed sites are served by a separate web server (like Caddy or nginx) that reads from `/var/www/docs`.
|
|
|
|
```bash
|
|
# If you have a web server configured to serve from /var/www/docs:
|
|
curl https://docs.yigid.dev/alice/myproject/
|
|
```
|
|
|
|
**For local development:** You'll need to set up a web server to serve files from the `docs/` directory, or use a simple HTTP server:
|
|
|
|
```bash
|
|
# Example: serve files from docs directory
|
|
cd docs && python3 -m http.server 3000
|
|
# Then access: http://localhost:3000/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 (requires web server setup)
|
|
# If you have a web server serving from docs/ directory:
|
|
curl http://localhost:3000/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
|
|
|