The project includes a multi-stage Dockerfile based on Node.js 20.18.0 slim, making it straightforward to run Buda Lightning Invoice in any environment that supports Docker — whether that is your local machine, a VPS, or a container orchestration platform. This is the same image that Fly.io builds when you runDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/nicosaporiti/buda-lightning-invoice/llms.txt
Use this file to discover all available pages before exploring further.
fly deploy, so the behaviour is identical across environments.
Dockerfile overview
The Dockerfile uses a two-stage build to keep the final image lean by separating the compilation environment from the runtime image.base stage
- Starts from the official
node:20.18.0-slimimage, which omits unnecessary system packages. - Sets the working directory to
/app. - Sets
NODE_ENV=productionpermanently — this affects how Express and other packages behave and also controls some application-level logic.
build stage
- Extends
basewith native build tools (build-essential,node-gyp,pkg-config,python-is-python3) needed to compile any native Node.js addons. - Installs exact dependency versions from
package-lock.jsonusingnpm ci— reproducible and audit-friendly. - Copies all application source files into the image.
Final stage
- Starts fresh from the lean
baseimage (no build tools). - Copies the fully-built application from the
buildstage. - Exposes port
3000in the image metadata (the actual listening port is controlled by thePORTenvironment variable, which defaults to8080). - Starts the server with
npm run start(node index.js).
Full Dockerfile
Build and run
Build the Docker image
From the repository root (where the The build will pull the base image, install build tools, run
Dockerfile lives), build the image and tag it:npm ci, and produce a final slim image. This typically takes 1–3 minutes on first build; subsequent builds use the layer cache and are much faster.Run the container with environment variables
Start the container in detached mode, passing your credentials and domain as environment variables:This maps host port
3001 to container port 8080 (the default PORT). Adjust the host-side port (3001) to any free port on your machine.Verify the container started
Check the container logs to confirm the server is listening:You should see output similar to:You can also confirm the container is running with:
Environment variable injection
Credentials must be provided at runtime — never baked into the image. There are two common approaches: Inline-e flags (shown above) — suitable for quick testing:
--env-file option — recommended for anything beyond a quick test, keeps secrets out of your shell history:
.env file should follow the format from the README:
The
.dockerignore file excludes node_modules, .env, .dockerignore, Dockerfile, fly.toml, and .git from the build context. This means your local .env file is never copied into the image, even if you forget to add a COPY exclusion. Secrets must always be injected at docker run time.Port mapping
The container listens on the port specified by thePORT environment variable. If PORT is not set, the application defaults to 8080.
The -p <host_port>:<container_port> flag in docker run maps a port on your host machine to a port inside the container:
| Flag | Host port | Container port | When to change |
|---|---|---|---|
-p 3001:8080 | 3001 | 8080 | Change host side if 3001 is already in use |
-p 80:8080 | 80 | 8080 | Expose directly on standard HTTP for a reverse proxy |
-p 8080:8080 | 8080 | 8080 | Avoid if host already uses port 8080 |
PORT via -e PORT=3000, update the container-side port in your -p mapping to match:
The
EXPOSE 3000 directive in the Dockerfile is documentation only — it does not publish any port to the host. Port publishing is always controlled by the -p flag at docker run time.