When to Use a Self-hosted Daemon
Use a Self-hosted Daemon when your project requires access to:- Private package registries — NPM, PyPi, or Maven registries hosted behind a VPN or firewall
- Internal APIs or microservices — Services that your application calls during startup or testing
- Private databases — Database instances that are only reachable from your internal network
- On-premise infrastructure — Any resource that cannot reach from its cloud environment
How It Works
The Modelcode Daemon is a lightweight binary (mcode) that runs on a machine within your network. Once started, it:
- Registers with and begins sending periodic heartbeats
- Polls for pending jobs (build, test, validation tasks)
- Executes commands on the host machine’s shell
- Reports results and logs back to
Command Execution Model
The daemon executes each command in a new shell process on the host machine. There is no persistent shell session between commands — each step (install, build, run, test) starts a freshshell -c "command" invocation.
All lifecycle commands are executed in a POSIX shell environment. Windows CMD or PowerShell syntax is not supported.
The Modelcode Daemon executes lifecycle commands in a POSIX-compliant shell environment. Linux and macOS are fully supported.
- Environment variables Use the Modelcode UI setup to configure environment variables and not via the Lifecycle commands.
- Working directory is managed by the daemon and stays consistent across all commands within a single job. You do not need to
cdinto the project directory, unless commands should be executed in a nested directory in the project. - Concatenated Commands In the case multiple commands should be executed in the same step, use ’&&’ to concat commands that share the same shell context.
- Private repositories The daemon executes lifecycle commands exactly as defined. If Composer is configured to require authentication for private repositories, those credentials must be present on the daemon host or supplied via encrypted environment variables.
The daemon runs commands with the same permissions as the user that started the
mcode process. Make sure the user has access to the tools and services your project needs (e.g., language runtimes, network access to private registries).Setting Up the Daemon
Prerequisites
- A machine on your network that can reach your private services
- A Modelcode account with an active project
- Network connectivity from the machine to
*.modelcode.ai - All dependencies of the migration project should be available to the Daemon
- POSIX-compliant operating system (Linux or macOS)
The Modelcode Daemon currently supports POSIX environments only.
Language-Specific Requirements (PHP)
If your project uses PHP and Composer:- PHP must be installed on the daemon host
- Composer must be installed and available in PATH
- Any required PHP extensions must be installed
Supported Operating Systems
- Linux (x86_64, ARM64)
- macOS (Intel & Apple Silicon)
Windows native execution is not supported at this time.
- Generate an API key — Creates credentials for the daemon to authenticate with
- Install the daemon — Download and install the
mcodebinary on your target machine - Set up encryption — Generate a key pair so the daemon can securely handle secrets
- Start the daemon — Run the daemon process and connect it to
- Verify the connection — Confirm the daemon is registered and online
- Configure lifecycle commands — Define the install, build, run, health check, and test commands for your project
- Configure environment variables — Add any variables your application needs at build or runtime, with optional secret encryption
- Validate the setup — Run an end-to-end validation that executes each lifecycle command in sequence
Environment Variables and Registry Access
Private Registry Access (Artifactory)
If your dependencies are hosted in a private Artifactory instance:
- The daemon host must have network access to Artifactory
- Composer must be configured to authenticate against Artifactory
- Required credentials (tokens, username/password, or auth.json) must be available at runtime
- Composer auth.json
- Environment variables
Troubleshooting
Daemon Shows as Offline
The daemon appears offline when has not received a heartbeat within the last 60 seconds. Check if the daemon process is running:mcode run/start.
Check network connectivity:
The daemon must be able to reach Morph server over HTTPS. Verify with:
mcode logs to show the last log lines.
Alternatively the logs are written to the logs/ directory next to the mcode binary. Look for connection errors or authentication failures.
Common causes:
- The
mcode runprocess was killed or the machine rebooted without a service manager configured - A network change (VPN disconnect, firewall rule update) is blocking outbound HTTPS traffic
Command Not Found
The daemon inherits thePATH from the shell that started it. When installed as a system service, it takes a snapshot of the current PATH and stores it in its config file. If you install new tools after the daemon is already running as a service, update the stored path with mcode refresh-path and restart the daemon.
Test Generation Failed
Test generation failures occur when cannot generate tests for your project. This typically relates to the build or run steps. Application failed to build: Check the install and build command output in the validation logs. Common causes:- Missing dependencies that are only available on your private network
- Incorrect build command — verify it works when run manually on the same machine
- Environment variables missing — add them in the Modelcode UI
- Check that the port your application listens on is not already in use
- Verify that required services (databases, APIs) are reachable from the host machine
- Review the run command output for startup errors
- Confirm the health check URL and port match your application’s configuration
- Check that the application is binding to
0.0.0.0orlocalhost, not a specific interface - Increase the health check timeout if your application has a long startup sequence
Functional Testing Failed
Functional test failures mean the test suite ran but one or more tests did not pass. Review the test output: The validation logs show the full test command output, including individual test failures. Read the error messages to determine whether the failure is:- A test that depends on external state (e.g., seeded database records, specific API responses)
- A test environment issue (missing env var, wrong service URL)
- An actual bug surfaced by the generated tests
- Start those services before running
mcode run - Add their connection details as environment variables in the Modelcode UI
- Check the
command_timeoutconfiguration (default is 10 minutes) - If your test suite takes longer, consider splitting it or increasing the timeout
API Key Issues
“Unauthorized” or “Authentication failed”:- Verify the API key in your daemon configuration matches the one shown in the Modelcode UI
Encryption Key Mismatch
Secrets fail to decrypt: If the daemon cannot decrypt secret environment variables:- Re-run
mcode encryption generateand update the public key in the Modelcode UI - Restart the daemon with
mcode run - Re-save your environment variables in the UI to re-encrypt them with the new key
FAQ
Does the Modelcode Daemon support Windows?
The daemon supports POSIX-compliant environments (Linux/macOS).Next Steps
- Define Modernization Goals — Configure what your migration should achieve
- Source Architecture — Understand how your existing codebase is analyzed