FAQ
The most common questions about FoxServer installation, licensing, usage and support. The answers describe the published version, 0.9.38.
What are the system requirements?
Windows 10 or later (32 or 64 bits) and the .NET 10 runtime in its x86 variant. The 64-bit one does not work, even if it is installed: FoxServer is 32-bit because it loads the Visual FoxPro COM, which is. Administrator permissions are needed to install. Visual FoxPro is only needed on the machine you develop on.
Can I run FoxServer on Linux or macOS?
No, and it is not planned. The host loads the Visual FoxPro COM, which is Windows and 32-bit, so this is not a matter of porting the code: the engine being published is VFP itself. What you can do is put FoxServer behind any reverse proxy.
Do I need VFP installed on the production server?
No. The Visual FoxPro IDE is only needed on the machine where you develop the controllers, because init, controller-add and build delegate to a vfp9.exe. On the server, copy the VFP 9 runtime files (vfp9t.dll, vfp9r.dll, vfp9renu.dll and msvcr71.dll) next to your application's DLL and have the 32-bit .NET 10 runtime.
What exactly is a Developer license?
The one sold by seats, and it is for developing only: the server answers 403 to every request that does not come from 127.0.0.1. For another machine to call your API you need a Runtime license, which is the other product in the shop. This is the number one misunderstanding: it looks like a permissions problem and it is the license.
How do I activate my license?
You download the foxserver.lic file from your license detail page in the portal and copy it into the installation's config folder, which by default is C:\Programas\FoxServer\config\foxserver.lic (up to 0.9.34, C:\Program Files (x86)\FoxServer). Restart FoxServer. No internet needed.
What is the difference between buying and maintenance?
Buying gives you a perpetual license: the version you buy works forever, and that does not change. What maintenance bounds is your right to new versions, and the portal enforces it at download time: it offers you the latest version you are entitled to, not the latest there is. If no build falls inside your period, the download answers 403 with the reason.
Does FoxServer need the internet to operate?
No. The license is validated locally against a public key inside the binary. There are no calls to external servers during installation or while running, and there is no telemetry.
Can I run several servers on the same machine?
Yes. Each project has its manifest in config\servers\ and its port. All of them come up when FoxServer starts. Before adding one it is worth checking that no other has the same host:port:prefix key: foxserver deploy checks it and exits with 11 on a clash, because otherwise the host starts one and skips the other with a warning you only see in the log.
How do I set up HTTPS?
With a .pfx certificate and the issecure, certificatename and certificatepassword keys of the manifest. The password is stored encrypted with foxserver middleware-set, like every secret: the manifest does not read environment variables, and a plaintext secret makes the engine answer 500.
How do I protect my endpoints with JWT?
You enable auth in the manifest. Every endpoint without the word public in its HELP is protected. The login endpoint is different: the token is issued by the middleware when your controller answers with the X-Auth-Status header and a data object carrying id, name and role. The full contract is on the Middleware page.
How do I handle errors in my controllers?
With the results ApiController ships: this.BadRequest(message, code), this.NotFound(message), this.Forbidden(...) or this.Fail(status, message, code). They come out as Problem Details (RFC 9457), with application/problem+json, and your message travels in detail. The logging middleware records them by itself; for anything else you have LogWarning, LogError and LogFromException.
How many concurrent requests can it take?
What rules is not the internal semaphore of 50, but the VFP STA thread pool: one thread per core, with a minimum of 2 and a maximum of 8, PER SERVER. And each thread is a whole VFP environment, with its lifecycle and its connections: three manifests on a 16-core machine means 24 VFP environments and as many database connections. The call into VFP is synchronous, so a slow endpoint holds its thread while it lasts, and if it overruns its deadline the watchdog answers 503. It is tuned with FOXSERVER_WORKERS.
I am coming from 0.8: where is the Interop DLL?
It is no longer needed. Up to 0.8 the engine loaded an Interop assembly generated with TlbImp; since 0.9 it activates your code by ProgID straight from the MTDLL, and the manifest's dllpath points at that native MTDLL. If your project still ships its Interop, it stays as a fallback in case the ProgID is not registered: nothing to delete and no hurry to migrate.
Is there hot reload?
Not automatic: FoxServer does not watch the disk. What there is is a switch, and it is enough. After rebuilding with foxserver build, a POST to the status endpoint with /reload and the X-Status-Pin header releases the server's COM objects, and the next request creates them clean with your new DLL.
Can I install FoxServer as a Windows service?
Yes, and the installer already does it for you. By hand: bin\FoxServer.Host.exe --install-service, from an elevated console. In services.msc you can set automatic start and restart on failure. The service serves the manifests in config\servers\ of the installation, not those of a loose project.
How do I send webhooks to external services?
They are not fired from code: they are declared. With foxserver webhook-add-out you register the route, the subscriber URL and the secret, and when that endpoint is served the response body goes out signed. FoxServer implements Standard Webhooks, with a v1,<base64 HMAC-SHA256> signature, configurable retries and a dead-letter queue. You test it with foxserver webhook-test.
Where are the logs?
The request logs go into logging.path, named {fileprefix}_{Type}_{yyyyMMdd}.log. The host log is a different one: logs\FoxServer_<date>.log at the root of the installation, one per day, split at 10 MB and purged after 30. The Windows Event Viewer receives nothing, not even in service mode: an entry is written there only if writing the log itself fails.
What happens when the 30-day trial expires?
You buy a 1, 4 or 8 seat license and copy the new .lic into config\. Your code and your configuration do not change. If you need to serve other machines, what you need is a Runtime license, not one more seat.
Is there a trial or a refund?
There is a free 30-day Trial license for evaluation, issued by the portal itself when you verify your email. And if it does not work out after buying, the refund policy gives you 30 days from the purchase, on top of the 14-day statutory right of withdrawal.
How do I get support?
By writing to soporte@irwinrodriguez.dev. There are no forums and no public issue tracker: you read it and I read it, which is what happens when one person makes the product.
Can I start a long task in the background and answer later?
There is no parallelism inside a request: the endpoint holds its thread until it returns, and past
requesttimeoutseconds (120 s by default) the watchdog answers 503. For tasks that take seconds, wait and answer. For long ones the industry uses the asynchronous request-reply pattern: the endpoint records the job in a tasks table, returns 202 Accepted with an id and a Location header pointing to /tasks/{id}, and the client polls there until the status is done. The work is done by another process, not by FoxServer: a VFP executable watching that table, or FoxCore.Runtime. FoxServer has no place to run code after answering today, and that is recorded as a pending decision.How do I debug a controller that returns 500?
Not inside the host: the MTDLL runs on the VFP runtime, which has no debugger, so
SET STEP ON does nothing there. That is what FoxServerBench is for (FoxForge › Current project › Test bench): it runs your procedure without the MTDLL, without the server and without http.sys, with req and res filled in as the engine would fill them, and the debugger open on your own source. It is a bench, not an emulator: it does not go through middlewares or authentication. It is step 8 of the guide in the package, and JSONFox.fxp must be in build\ for req.json to be filled.Can I create an object once and reuse it in every request?
Yes: that is what the ApplicationLifecycle is for. An
olepublic class derived from ApplicationLifecycle, in a .prg of the project; in OnApplicationStarting you create the connection and keep it with this.SetResource("db", loConnection), and in any endpoint you get it back with this.GetGlobalResource("db"), which returns .NULL. if it is not there. The hook fills the lifecycle block of the manifest at build time. Since 0.9.16 it runs once per pool thread, not per request: with four threads you get four connections, which is the right thing in VFP. The full recipe is in the RECETARIO of the package, §2.Did not find your answer? Write to me