Zero-config application builder that automatically analyzes your code and turns it into a container image. It's built on BuildKit with support for Node, Python, Go, PHP, and more.
- Core: Analyzes apps and generates JSON build plans using language providers
- BuildKit: Converts build plans to BuildKit LLB (Low-Level Builder) format for efficient image construction
- CLI: Main entry point that coordinates core analysis and BuildKit execution
- Providers: Language-specific modules that detect project types (e.g. Node detects package.json) and generate appropriate build steps
- Runtime: The built images are based on @images/debian/runtime/Dockerfile
- Follow Go conventions and existing patterns in the codebase
- Use appropriate error handling with proper error wrapping
- Do not write comments that are obvious from the code itself; focus on explaining why something is done, not what it does
- Seriously, do not write comments that are obvious from the code itself.
- Do not write one-line functions
- Always use the App abstraction for file system operations.
- When configuring Mise settings, prefer environment variables (e.g.
MISE_PIPX_UVX) over TOML settings to maintain consistency with existing patterns in the codebase. - Never manually update lockfiles (yarn.lock, package-lock.json, pnpm-lock.yaml, etc.). Always use the respective package manager to generate or update lockfiles. Manual edits can result in invalid checksums and broken builds.
If mise is not available in your environment, install it using the instructions at https://mise.jdx.dev/installing-mise.html.
- Take a careful look at @mise.toml to understand what commands should be run at different points in the project lifecycle
- Do not worry about docker cache, etc. Never run
docker system pruneor any other similar commands. - Do not run
godirectly. Instead, inspect @mise.toml and usemise run <task>to run various dev lifecycle commands. For instance, you should not rungo vet,go fmt,go test, etc directly. - After making code changes, first run
mise run check - Then, run unit tests and a couple of relevant integration tests to verify your changes
- Don't run tests manually using
go testunless instructed to do so - If tests are failing that are unrelated to your changes, let me know and stop working.
- Don't run tests manually using
- Use the
climise task to test your changes on a specific example project, i.e.mise run cli -- --verbose build --show-plan examples/node-vite-react-router-spa/ - Do not run any write operations with
git - Do not use
bin/railpackinstead usemise run cli(which is the development build ofrailpack)- Therefore do not run
mise build, we don't need arailpackbinary for local testing
- Therefore do not run
- Use a local
tmp/directory for temporary files instead of the global/tmp/directory. Don't worry about cleaning up tmp directories. - You can clone the mise repo (https://github.com/jdx/mise) into
tmp/to inspect it when needed.
There are normal unit tests, snapshot tests, and integration tests. The integration tests are most unique to this project:
- They represent example projects that would be built using the
railpackCLI - On CI, they are built and run to make sure
railpackproperly builds and runs the project test.jsonanddocker-compose.ymlare used to help determine what assertions should be made and what services should be run for the test
- Run
mise run test-integration-cwdfrom within anexamples/directory to run the integration test for that example. test.jsonfiles are JSONC format and support comments. Use comments to explain temporary workarounds or special test conditions.- In
test.jsonwe should avoid usingjustBuildfor all but the most simple projects.justBuilddoes not testexpectedOutputor any other assertions. - If the project has a server component, we should use a
httpChecktest. Read the @docs/src/content/docs/guides/developing-locally.md guide, specifically the### HTTP Checkssection for more information. httpCheckassertions assume that$PORTis respected.- You can use
"env": { "SECRET": "123"}to add a required environment variable to a test case.
- Markdown files in @docs/src/content/docs/ should be limited to 80 columns
- Do not fix indentation or formatting manually. This is corrected automatically using
mise run check - NEVER commit language-specific cache or build artifacts (e.g. Python
__pycache__/,*.pyc,*.pyofiles). If you encounter build artifacts that are not excluded by .gitignore, add appropriate patterns to .gitignore to exclude them