KehittäjätTypeScript SDK

Hostwolf Apps SDK JavaScriptille ja TypeScriptille

@hostwolf/apps-sdk on Hostwolf Apps -rajapinnan virallinen tyypitetty asiakaskirjasto. Sillä julkaiset ja ajat sovelluksiasi koodista: projektit, sovellukset, julkaisut ja lokit, ympäristömuuttujat, hallinnoidut tietokannat, automaattinen skaalaus, taltiot ja paljon muuta.

npm install https://app.hostwolf.net/dl/hostwolf-apps-sdk-0.2.1.tgz

SDK jaetaan osoitteesta app.hostwolf.net eikä npm-rekisteristä. Yllä oleva komento lisää sen package.json-tiedostoosi muodossa "@hostwolf/apps-sdk": "https://app.hostwolf.net/dl/hostwolf-apps-sdk-0.2.1.tgz", ja tuot sen nimellä @hostwolf/apps-sdk. pnpm, yarn ja bun hyväksyvät saman URL-osoitteen. Jokaisella versiolla on oma URL; katso Versiot.

Se toimii Node 18+:ssa, Bunissa ja Denossa, eikä sillä ole ajonaikaisia riippuvuuksia.

Pikaopas#

Luo API-tunnus konsolissa kohdassa Avaimet ja tunnukset → API-tunnukset, ja sitten:

import { HostwolfApps } from '@hostwolf/apps-sdk';

const hw = new HostwolfApps({ token: process.env.HOSTWOLF_APPS_TOKEN! });

const server = (await hw.servers.purchased()).find((s) => s.kind === 'app' && s.status === 'ready')!;
const { uuid: project } = await hw.projects.create({ name: 'shop' });

const app = await hw.applications.createFromGit({
    project_uuid: project,
    environment_name: 'production',
    server_uuid: server.server_uuid!,
    git_repository: 'https://github.com/acme/shop',
    git_branch: 'main',
    build_pack: 'nixpacks',
    ports_exposes: '3000',
});
await hw.applications.setEnvs(app.uuid, { NODE_ENV: 'production' });

const deployment = await hw.deployAndWait(app.uuid);
console.log(deployment.status, await hw.applications.logs(app.uuid, { lines: 20 }));

Resursseihin viitataan niiden uuid:llä. Vastausobjektit käyttävät rajapinnan omia kenttänimiä (snake_case), ja niiden TypeScript-tyypit viedään, esim. Application, Deployment ja ManagedDatabase.

Asetukset#

new HostwolfApps({
    token: '12|abc...',                              // required
    baseUrl: 'https://console.app.hostwolf.net',     // default
    timeoutMs: 30_000,                               // per request
    maxRetries: 2,                                   // 429s, and 502/503/504 on GET
    maxRetryWaitMs: 10_000,                          // longer Retry-After waits fail fast instead
    language: 'de',                                  // error messages in en, de, fr, es or fi
    fetch: customFetch,                              // optional
});

Projektit ja ympäristöt#

MetodiMitä se tekee
projects.list() / get(uuid)Projektit; get sisältää ympäristöt
projects.create({ name })Uusi projekti, jossa on production-ympäristö
projects.update / deleteNimeä uudelleen tai poista tyhjä projekti
projects.environments(uuid)Projektin ympäristöt
projects.environment(uuid, 'staging')Yksi ympäristö (nimen tai uuid:n perusteella) resursseineen
projects.createEnvironment / updateEnvironment / deleteEnvironmentHallitse ympäristöjä
projects.sharedEnvs / environmentSharedEnvsMuuttujat, jotka jaetaan projektin tai ympäristön kaikille sovelluksille

Sovellukset#

MetodiMitä se tekee
applications.list({ tag })Tiimin kaikki sovellukset
applications.get(uuid)Yksi sovellus asetuksineen
applications.createFromGit(input)Julkisesta repositoriosta (nixpacks, railpack, dockerfile tai static)
applications.createFromPrivateRepo(input)Yksityisestä repositoriosta deploy-avaimella (private_key_uuid)
applications.createFromGithubApp(input)Yhdistetyn GitHub Appin repositoriosta (github_app_uuid); push-julkaisut toimivat suoraan
applications.createFromDockerfile(input)Dockerfile-tekstistä, repositoriota ei tarvita
applications.createFromImage(input)Valmiista konttikuvasta, kuten ghcr.io/acme/web
applications.update(uuid, changes)Nimi, verkkotunnukset, portit, haara, build- ja käynnistyskomennot, terveystarkistus, rajat
applications.deploy(uuid, { force })Tee build ja käynnistä; palauttaa deployment_uuid:n
applications.restart / stopKäynnistä uudelleen ilman uutta buildia, tai pysäytä
applications.logs(uuid, { lines })Kontin viimeisin tuloste (tunnus tarvitsee read:sensitive-oikeuden)
applications.metrics(uuid, { minutes })Suorittimen ja muistin historia
applications.rollbackImages / rollback(uuid, tag)Julkaise aiempi konttikuva uudelleen
applications.delete(uuid, { deleteVolumes })Poista sovellus (ja oletuksena sen taltiot)

Sovellukset toimivat sovelluspalvelimillasi. server_uuid on servers.purchased()-kutsun server_uuid-kenttä (tai servers.list()-kutsun uuid). Jätä domains pois, niin saat generoidun *.app.hostwolf.net-osoitteen.

Ympäristömuuttujat#

MetodiMitä se tekee
applications.envs(uuid)Muuttujat; arvot ovat null, ellei tunnuksella ole read:sensitive-oikeutta
applications.setEnvs(uuid, { KEY: 'value' })Luo tai päivitä useita kerralla
applications.setEnv(uuid, { key, value, is_shown_once })Luo tai päivitä yksi
applications.createEnv / updateEnvTiukka luonti (409, jos on jo olemassa) ja päivitys
applications.deleteEnv(uuid, envUuid) / deleteEnvByKey(uuid, key)Poista muuttuja
teams.sharedEnvs() ja vastaavatKoko tiimin muuttujat, käytetään muodossa {{team.KEY}}

Käynnissä olevat kontit näkevät muuttuneet muuttujat seuraavan julkaisun jälkeen.

Julkaisut#

const { deployment_uuid } = await hw.applications.deploy(app.uuid);
const done = await hw.deployments.wait(deployment_uuid!, {
    timeoutMs: 10 * 60_000,
    onStatus: (status) => console.log(status), // queued, in_progress, finished
});

wait ja deployAndWait heittävät HostwolfAppsError-virheen koodilla deployment_failed (viestissä lokin viimeiset rivit), deployment_cancelled tai timeout. Anna throwOnFailure: false, jos haluat epäonnistuneen julkaisun takaisin virheen sijaan.

MetodiMitä se tekee
deployments.running()Jonossa olevat tai nyt käynnissä olevat julkaisut koko tiimissä
deployments.get(uuid)Yksi julkaisu, koontiloki kentässä logs
parseDeploymentLogs(deployment)Koontiloki riveinä ({ output, type, timestamp })
deployments.forApplication(uuid, { skip, take })Sivullinen sovelluksen julkaisuja, uusin ensin
deployments.allForApplication(uuid)Asynkroninen iteraattori niiden kaikkien yli
deployments.deploy({ uuid, tag, force })Julkaise useita sovelluksia uuid:n tai tunnisteen perusteella
deployments.cancel(uuid)Peru jonossa oleva tai käynnissä oleva julkaisu

Palvelimet#

MetodiMitä se tekee
servers.purchased() / purchasedServer(uuid)Ostamasi sovelluspalvelimet ja VPS:t: koko, kaupunki, tila, hinta ja server_uuid
servers.list() / get(uuid)Sovelluspalvelimet, joilla sovelluksia voi ajaa
servers.resources(uuid) / domains(uuid)Mitä palvelimella ajetaan, ja sen verkkotunnukset
servers.metrics(uuid, { minutes })Suorittimen ja muistin historia
servers.destinations(uuid)Palvelimen Docker-verkot (usean palvelimen käyttöön)
servers.traffic(uuid, { month })Ostetun palvelimen lähtevä liikenne ja sen lasku tähän mennessä (1 Tt kuukaudessa sisältyy)
servers.teamTraffic({ month })Sama tiimin kaikille palvelimille, yhteissummineen
servers.regions({ size })Kaupungit kokokohtaisine kuukausihintoineen ja tieto siitä, mihin automaattinen skaalaus voi lisätä palvelimia

Palvelimia voi ostaa ja perua vain konsolissa, joten API-tunnus ei voi koskaan ostaa palvelinta.

Usea palvelin#

Aja yhden sovelluksen kopioita usealla sovelluspalvelimellasi. Hostwolf tekee konttikuvan kerran, käynnistää kopion jokaisella palvelimella ja tasaa kuorman niiden välillä.

await hw.applications.addServer(app.uuid, otherServer.server_uuid!);
await hw.deployAndWait(app.uuid);
console.log(await hw.applications.destinations(app.uuid)); // primary + copies

removeDestination(appUuid, destinationUuid) lopettaa kopion ajamisen kyseisellä palvelimella.

Hallinnoidut tietokannat#

PostgreSQL, MySQL/MariaDB ja Redis Hostwolfin tietokantapalvelimilla, erillään sovelluspalvelimistasi, TLS:llä, öisillä varmuuskopioilla muualle ja PostgreSQL:lle ajankohtaan palautuksella.

const plans = await hw.databases.catalog();             // engines, plans, pool sizes, regions, prices
const db = await hw.databases.create({ engine: 'postgres', plan: 'small', region: 'vultr:ams' });
await hw.databases.waitUntilReady(db.uuid);
await hw.databases.attach(db.uuid, app.uuid);           // DATABASE_URL (pooled) + DATABASE_DIRECT_URL
await hw.deployAndWait(app.uuid);

Tietokanta laskutetaan tunneittain palvelintilauksellasi siitä hetkestä, kun se luodaan. create lähettää Idempotency-Key-otsakkeen, joten uudelleen yritetty kutsu ei koskaan luo toista tietokantaa; anna oma avaimesi parametrilla { idempotencyKey }.

connection(uuid) palauttaa kaksi URL-osoitetta. url kulkee yhteyspoolerin kautta (PgBouncer portissa 6432, ProxySQL portissa 6033): käytä sitä sovelluksessasi. direct_url yltää suoraan tietokantaan: käytä sitä migraatioihin, LISTEN/NOTIFY-käyttöön, istuntoasetuksiin ja pitkiin transaktioihin. Redisillä on yksi URL.

MetodiMitä se tekee
databases.list() / get(uuid)Tietokantasi moottoreineen, paketteineen, alueineen, tiloineen, hintoineen, rajoineen sekä upgrades- ja advice-tietoineen
databases.connection(uuid)Poolattu ja suora URL salasanoineen (tunnus tarvitsee oikeuden read:sensitive)
databases.attach(uuid, appUuid, { envKey, overwrite })Tallenna poolattu URL muuttujaan DATABASE_URL ja suora muuttujaan DATABASE_DIRECT_URL (Redis: REDIS_URL). Jos sovelluksella on ne jo eri arvolla, kutsu heittää conflict-virheen, jossa on error.conflicts ja error.suggestedEnvKey; anna envKey tai overwrite: true
databases.upgrade(uuid, plan, { confirm: true })Siirry suurempaan pakettiin listasta upgrades; URL pysyy samana
databases.setEvictionPolicy(uuid, policy)Redis: allkeys-lru välimuistille, noeviction jonoille (tulee voimaan heti)
databases.backup(uuid)Aloita ylimääräinen varmuuskopio nyt
databases.delete(uuid)Poista se ja lopeta laskutus; tuki voi palauttaa sen 7 päivän ajan

upgrade ilman parametria { confirm: true } ei muuta mitään: se heittää HostwolfAppsError-virheen koodilla confirm_required, ja error.quote sisältää uuden kuukausihinnan, joka näytetään ensin.

Automaattinen skaalaus#

const { policy, blocker, status } = await hw.autoscaling.get(app.uuid);
await hw.autoscaling.enable(app.uuid, { min_copies: 1, max_copies: 4, monthly_cap_usd: 40 });

Automaattinen skaalaus lisää sovelluspalvelimia lähelle kävijöitäsi, kun suoritinkuorma pysyy korkeana, ja poistaa ne, kun se laskee. Lisätyt palvelimet laskutetaan tunneittain normaalihintaan, enintään monthly_cap_usd asti. blocker kertoo, miksi sitä ei vielä voi ottaa käyttöön (esimerkiksi aktiivista palvelintilausta ei ole). Pois jättämäsi kentät säilyttävät arvonsa; disable(uuid) poistaa sen käytöstä. cities listaa alueiden tunnisteet, jotka allowed_cities hyväksyy sovellukselle, sekä tuntihinnan siellä; servers.regions() listaa kaikki kaupungit.

Tallennustaltiot#

Lohkotallennustilaa sovelluspalvelimillesi ja VPS:illesi: 10–1000 Gt, liitettynä palvelimella polkuun /mnt/volume-<id>, laskutus tunneittain. Laskua nostavat kutsut vaativat { confirm: true }; ilman sitä ne eivät muuta mitään ja heittävät koodin confirm_required sekä hinnan kentässä error.quote.

const offer = await hw.volumes.offer(server.uuid, { sizeGb: 50 });   // sizes allowed here and the price
const volume = await hw.volumes.create(server.uuid, { size_gb: 50, autogrow_max_gb: 200 }, { confirm: true });
await hw.volumes.waitFor(volume.id);                                  // mounted in about a minute
await hw.volumes.resize(server.uuid, volume.id, 100, { confirm: true });
MetodiMitä se tekee
volumes.list(serverUuid) / listAll({ status }) / get(id)Palvelimen taltiot tai tiimin kaikki taltiot (status: 'detached' irrotetuille)
volumes.offer(serverUuid, { sizeGb })Myydäänkö palvelimen kaupungissa taltioita, koot ja hinta
volumes.create(serverUuid, { size_gb, backups, autogrow_max_gb }, { confirm })Lisää taltio (varmuuskopiot oletuksena käytössä)
volumes.resize / setBackups / setAutogrow / updateSuurenna (ei koskaan pienennä), ota varmuuskopiot käyttöön tai pois käytöstä, aseta automaattisen kasvun raja
volumes.detach(serverUuid, id)Poista liitos ja irrota se; se säilyttää tiedostonsa, ja sitä laskutetaan edelleen
volumes.attach(id, serverUuid, { confirm })Liitä irrotettu taltio palvelimeen samassa kaupungissa
volumes.backups(id) / backupNow(serverUuid, id)Palautettavissa olevat varmuuskopiot tai varmuuskopio heti
volumes.restore(serverUuid, id, backupId, 'same' | 'new', { confirm })Palauta itse taltioon tai uuteen taltioon
volumes.restoreDetached(id, backupId, serverUuid, { confirm })Palauta irrotetun taltion varmuuskopio uuteen taltioon
volumes.delete(id, { confirm: true })Poista se ja sen tiedostot

Kun palvelin poistetaan, sen taltiot irrotetaan ja säilytetään 7 päivää maksutta (kept_until); liitä taltio sillä välin toiseen palvelimeen samassa kaupungissa, tai se poistetaan.

Sovellusten taltiot#

MetodiMitä se tekee
applications.storages(uuid)Pysyvät taltiot ja tiedostoliitokset
applications.createStorage(uuid, { type: 'persistent', name, mount_path })Lisää taltio (julkaise uudelleen liittääksesi sen)
applications.updateStorage / deleteStorageMuuta tai poista yksi
applications.setVolumeBackup(uuid, storageUuid, { frequency: 'daily' })Varmuuskopioi taltio aikataulun mukaan
applications.runVolumeBackup / deleteVolumeBackupVarmuuskopioi nyt tai poista aikataulu

Tiimit#

MetodiMitä se tekee
teams.current() / members()Tunnuksen tiimi ja sen jäsenet
teams.update({ name })Nimeä tiimi uudelleen
teams.auditEvents({ page }) / allAuditEvents()Tiimin tarkastusloki (ylläpitäjät ja omistajat)

Sivutus#

Rajapinnan sivuttamille listoille on kaksi tapaa: yksi metodi palauttaa yhden sivun, ja all…-metodi palauttaa asynkronisen iteraattorin jokaisen kohteen yli. collect muuttaa iteraattorin taulukoksi:

import { collect } from '@hostwolf/apps-sdk';

const deployments = await collect(hw.deployments.allForApplication(app.uuid), 100);
for await (const event of hw.teams.allAuditEvents({ action: 'deploy' })) console.log(event.description);

Virheet#

Epäonnistuneet kutsut heittävät HostwolfAppsError-virheen.

import { HostwolfAppsError } from '@hostwolf/apps-sdk';
try {
    await hw.applications.createFromDockerfile({ project_uuid, server_uuid, dockerfile });
} catch (e) {
    if (e instanceof HostwolfAppsError && e.isValidation) console.log(e.errors); // { field: ['message'] }
    else throw e;
}

Sillä on nämä ominaisuudet:

  • status: HTTP-tila, tai 0 verkkovirheissä, aikakatkaisuissa ja epäonnistuneissa julkaisuissa.
  • code: lyhyt koodi, kuten validation_failed, unauthenticated, forbidden, not_found, rate_limited, confirm_required, deployment_failed tai timeout.
  • quote: confirm_required-virheen yhteydessä rajapinnan ilmoittama hinta (näytä se ja kutsu sitten uudelleen parametrilla { confirm: true }).
  • retryAfter: 429-vastauksessa sekunnit, joiden jälkeen kutsu sallitaan taas. Lyhyet odotukset yritetään uudelleen puolestasi; pidemmät epäonnistuvat heti, ja tämä kenttä on asetettu.
  • message: luettava kuvaus, kenttävirheet mukaan lukien.
  • errors: 422-vastauksen kenttävirheet muodossa { field: ['message'] }.
  • body: vastauksen sisältö. 403-virheessä asiasta, jonka Hostwolf tekee puolestasi (kuten palvelinten lisääminen), on mukana docs-linkki.
  • Pikaliput: isNotFound, isRateLimited, isValidation, isUnauthorized ja isConfirmRequired.

Raa'at pyynnöt#

Jos päätepisteelle ei vielä ole kääremetodia, kutsu sitä suoraan:

await hw.http.get(`/applications/${uuid}/scheduled-tasks`);
await hw.http.post(`/applications/${uuid}/scheduled-tasks`, { name: 'cleanup', command: 'npm run cleanup', frequency: '0 3 * * *' });

Polut ovat suhteessa osoitteeseen /api/v1. Kaikki päätepisteet löydät API-viitteestä.

Versiot#

TiedostoKäyttö
https://app.hostwolf.net/dl/hostwolf-apps-sdk-.tgzKiinteä versio. Käytä tätä package.json-tiedostossa.
https://app.hostwolf.net/dl/hostwolf-apps-sdk.tgzAina uusin versio. Paketinhallinnat välimuistittavat URL-osoitteen mukaan, joten suosi versioituja osoitteita.
https://app.hostwolf.net/dl/index.jsonNykyiset versiot SHA-256- ja npm-eheystarkisteineen.

Päivitä asentamalla uudempi versioitu URL.

Lisenssi#

MIT

Jumissa, tai puuttuuko päätepiste? Kerro meille osoitteessa app.hostwolf.net/contact tai [email protected].