---
title: "Deploy an app you already have with erpc worker import"
description: "erpc worker import reads an app's directory and writes its erpc.toml, so a Cargo package or a Linux binary in any language deploys without changing its code."
canonical: "https://erpc.global/en/doc/erpc-cli/worker-import/"
locale: "en"
---

# Deploy an app you already have with erpc worker import

`erpc worker import` takes in an app you already have, as it is. It writes the app's `erpc.toml` and changes none of its code.

This page describes ERPC CLI `v0.1.0-rc.4`, a pre-release.

## Import and deploy

The app can be a bot that runs under systemd or Docker today, or a service in another language. `import` reads the app's directory and writes the `erpc.toml` it describes. Nothing else is written in the app, nothing in it is run, and its code is not changed. erpc adds the app to its own list, as `init` does.

```bash
cd my-bot                                   # a Cargo package
erpc worker import                          # writes erpc.toml from what is there
erpc worker check                           # what it describes, and what is missing
erpc worker deploy                          # your VPS, or a new hourly one

cd my-go-service && make linux              # any other toolchain: build the Linux binary your way
erpc worker import --binary dist/service --port 8080 --health /healthz
erpc worker deploy
```

- **A Cargo package** is built with `cargo build --release`, as an app made by `init` is. The app is named after the package unless `--name` says otherwise, and `--bin` picks the binary when the package has several. A workspace root is refused: point `import` at the package.
- **A Linux binary built anywhere, in any language,** deploys the same way with `--binary <PATH>`, shipped as it is. erpc reads its header and refuses one a server cannot run: a macOS or Windows binary, a script, a shared library, a file cut short, or another architecture than `build.target`. The binary must be static, or linked against glibc with its loader at the usual path. It is a file of the app: a link under that name that leads out of the app's directory is refused. A deploy stops on an unusable binary before a server is bought. Build the binary again before a deploy that should carry a change.

## What import reads

| In the directory | What `import` does with it |
| --- | --- |
| `.env.example` and similar example files | Each name becomes a setting when it can be one: a name that is not capital letters, digits and `_` (starting with no digit), or one erpc or the server sets itself (`ERPC_WORKER_…`, `LD_…`), is left out. A plain one goes into `[vars]` with the example's value. One that looks like a secret by its name, or whose value carries a credential, is named with the command that keeps it, and its value is not copied |
| `.env` | Only the names are read, except a port number |
| `PORT`, `API_PORT`, a Dockerfile's `EXPOSE` | `run.port`, unless `--port` gives it. `--health <PATH>` adds the health check on that port |
| `GRPC_ENDPOINT`, `SHREDS_ENDPOINT` and other settings a data line provides | Left out of `[vars]`: the line's flag on `deploy` sets them |
| `wallet.json`, `id.json`, `*keypair.json` | Named, with `erpc worker key import <FILE> --wipe`, which keeps the key where erpc worker reads it and wipes the file |
| A compose file with Redis or PostgreSQL | `[services]`, so that `deploy` puts them on the server |
| `Dockerfile`, the compose file itself | Not used to run the app: erpc worker runs the binary itself, under a hardened systemd unit |

`import --chain` names the chain the app is for, `solana` by default.

## How import reads a directory

The directory may be one you cloned a minute ago, so `import` reads it with care.

- **`erpc.toml` is made new.** When anything is at that path, `import` refuses: it never writes over a file or through a link.
- **It reads regular files inside the directory, up to 1 MiB each.** A link that leads out of the directory, a pipe, a device, a larger file and a file that is not UTF-8 are not read, and each is said.
- **No value it takes for a secret is copied.** It looks for credentials by their shape, so the check is a net, not a proof: a secret in a shape it does not know is copied like any value. `erpc.toml` is yours to read before you commit it.
- **`erpc worker check` warns of fewer kinds than `import` holds back.** It says nothing of an RPC URL with a key in its path, or of a recovery phrase, under `[vars]`: keep those with `erpc worker secret put`.

## What your app finds on the server

- **Settings arrive as environment variables**, `[vars]` and `[secrets]` alike. There is no `.env` on the server, and an app that reads a `.env` file with a dotenv library keeps working.
- **Its own directory is read-only.** Files it writes go under the directory `ERPC_WORKER_STATE_DIR` names (also its `HOME`), which a deploy keeps and `erpc worker backup` backs up.
- **A trading key arrives on a pipe, not in a file:** 64 bytes on the file descriptor `ERPC_WORKER_KEY_FD` names, once, when the app starts, with the public key in `ERPC_WORKER_PUBKEY`. An app that reads a key file has that one read to change; the pumpfun template's `src/wallet.rs` shows it.
- **It is one binary and the files `run.files` lists.** Anything else it opens at run time has to be in that list.

## Next steps

- [Keys and secrets](https://erpc.global/en/doc/erpc-cli/worker-secrets/): Keep the settings `import` held back, and the trading key.
- [Firewall and WAF](https://erpc.global/en/doc/erpc-cli/worker-firewall-and-waf/): Choose who may reach the app.
- [The worker guide](https://github.com/elsoul/erpc-cli/blob/v0.1.0-rc.4/docs/worker.md): Every file `import` reads, and the credential shapes it looks for.
