Guides
Quick start
From a token to a running service, a database beside it, a tunnel and a bucket, with nothing but curl.
Guides
From a token to a running service, a database beside it, a tunnel and a bucket, with nothing but curl.
In the dashboard, open Settings → API tokens and create one with the member role. Keep it in your shell for the rest of this page, with your workspace's slug (the name in the dashboard's address).
export INFRAFLOW_TOKEN=ifl_… export ORG=acme export API=https://api.infraflow.app curl $API/v1/orgs -H "Authorization: Bearer $INFRAFLOW_TOKEN"
A service lives in a project. Create one, then a service from an image; the answer comes back at once and the deployment proceeds in the background.
curl -X POST $API/v1/orgs/$ORG/projects \
-H "Authorization: Bearer $INFRAFLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Storefront"}'
curl -X POST $API/v1/orgs/$ORG/services \
-H "Authorization: Bearer $INFRAFLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"project": "storefront",
"name": "web",
"source_kind": "image",
"source": "nginxdemos/hello:latest",
"port": 80
}'The service is served at web.production.infraflow.app once its first deployment is live. Read the service to follow it: status goes from queued to building to live, or to failed with the reason in the deployment's error.
curl $API/v1/orgs/$ORG/services/web \ -H "Authorization: Bearer $INFRAFLOW_TOKEN" # The id of a deployment comes from the service's "deployments". curl $API/v1/orgs/$ORG/services/web/deployments/$DEPLOYMENT_ID \ -H "Authorization: Bearer $INFRAFLOW_TOKEN"
To deploy a repository instead, use "source_kind": "git" with its URL, or "github" with owner/name once a GitHub account is connected. With a Dockerfile, it is used; without one, the language is detected and built for you.
A service created with "public": false gets no public address: only the other services of its environment reach it, by its name, on a private network. Give it a path to keep across deployments.
curl -X POST $API/v1/orgs/$ORG/services \
-H "Authorization: Bearer $INFRAFLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"project": "storefront",
"name": "db",
"source_kind": "image",
"source": "postgres:17",
"port": 5432,
"public": false,
"volume_path": "/var/lib/postgresql/data",
"variables": {
"POSTGRES_PASSWORD": "a-long-random-password",
"DATABASE_URL": "postgres://postgres:a-long-random-password@db:5432/postgres"
}
}'The web service refers to the database's variable rather than copying it. The reference is resolved at each deployment, and the deployment waits for db to be live before it starts.
curl -X PATCH $API/v1/orgs/$ORG/services/web/variables \
-H "Authorization: Bearer $INFRAFLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{"set": {"DATABASE_URL": "${{db.DATABASE_URL}}"}}'
curl -X POST $API/v1/orgs/$ORG/services/web/deployments \
-H "Authorization: Bearer $INFRAFLOW_TOKEN" \
-H "Content-Type: application/json" -d '{}'Add a machine; the answer carries its token, once. On the machine, one command installs the agent and signs it in; after that each tunnel is one command, or one call.
curl -X POST $API/v1/orgs/$ORG/machines \
-H "Authorization: Bearer $INFRAFLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "home-server"}'curl -fsSL https://infraflow.app/install.sh | sh -s -- ifm_… infraflow tunnel http 3000 infraflow tunnel tcp 5432 --name pg
See Agent and CLI for every command.
Create a bucket and a key for it, then use any S3 client at https://s3.infraflow.app with region garage.
curl -X POST $API/v1/orgs/$ORG/buckets \
-H "Authorization: Bearer $INFRAFLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "acme-assets"}'
curl -X POST $API/v1/orgs/$ORG/buckets/acme-assets/keys \
-H "Authorization: Bearer $INFRAFLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "ci"}'export AWS_ACCESS_KEY_ID=GK… # access_key_id from the answer export AWS_SECRET_ACCESS_KEY=… # secret_access_key, shown once aws s3 cp ./logo.png s3://acme-assets/ \ --endpoint-url https://s3.infraflow.app --region garage
Without a key, ask for URLs that are already signed: each works once issued, for the time you choose, from a browser or curl.
curl -X POST $API/v1/orgs/$ORG/buckets/acme-assets/objects/sign \
-H "Authorization: Bearer $INFRAFLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"expires_secs": 3600,
"operations": [
{"op": "put", "key": "reports/q3.csv"},
{"op": "get", "key": "reports/q3.csv", "download": true}
]
}'
# Then, with the two URLs of the answer:
curl -X PUT --data-binary @q3.csv "$PUT_URL"
curl -o q3.csv "$GET_URL"