Dockerized application for local development, testing and deployment
Relates to:
Distribution.
Risks
Low. Could potentially cause confusion to those unfamiliar with Docker.
Background
What does this PR do?
This PR aims to improve Eliza ergonomics by providing a one liner for getting up and running via Docker.
What kind of change is this?
Development or infrastructure support.
Why are we doing this? Any context or related work?
Improve Eliza accessibility.
Documentation changes needed?
Updated README.
Testing
Where should a reviewer start?
Detailed testing steps
docker:build
docker:run
docker:bash
Deploy Notes
We could potentially add CI/CD. Or an official Docker image. Thoughts?
Database changes
N/A
Dockerfile Audit and Suggested Improvements
The current Dockerfile implementation has several areas that could be improved to enhance performance, security, and maintainability. Here’s a detailed list of suggested changes:
-
No
.dockerignoreFile- Without a
.dockerignore, unnecessary files and folders (e.g.,.git,node_modules, logs) are included in the Docker build context. This increases image size and build time. -
Suggested Fix: Add a
.dockerignorefile to exclude files not needed in the container.
- Without a
-
Inefficient Layer Caching
- Dependencies are installed multiple times, which prevents effective caching. Additionally, using separate
ADDcommands for configuration files results in multiple layers. -
Suggested Fix: Consolidate the
ADDcommands for configuration files and install dependencies in a single step. Runpnpm ionly once after adding all configuration files.
- Dependencies are installed multiple times, which prevents effective caching. Additionally, using separate
-
Redundant
RUN pnpm iCommands- Dependencies are installed three times throughout the Dockerfile, increasing build time.
- Suggested Fix: Install dependencies once, after copying all necessary configuration files, to streamline the build process.
-
Lack of Multi-Stage Build for Production
- A single-stage build may result in unnecessary development dependencies being included in the final image, which increases image size and introduces security risks.
- Suggested Fix: Use a multi-stage build to separate build dependencies from the final production image, ensuring only essential files are included.
-
Unoptimized
CMDCommand- The
CMD ["tail", "-f", "/dev/null"]keeps the container idle and suggests the container isn’t configured to run the application. -
Suggested Fix: Replace
CMDwith the actual command to start the application, such asCMD ["pnpm", "start"].
- The
-
Direct Inclusion of Environment Variables (
.envFile)- Adding the
.envfile withADDexposes sensitive information in the Docker image. This can pose security risks if the image is pushed to a registry. - Suggested Fix: Use Docker secrets or pass environment variables at runtime to secure sensitive data.
- Adding the
-
Lack of Non-Root User
- The container runs as the root user by default, which can lead to security vulnerabilities if exploited.
-
Suggested Fix: Create a non-root user and run the application under this user. Example:
RUN adduser -D appuser USER appuser
-
Missing Port Exposure
- If the application is meant to run a service (e.g., a web server), the container should expose the relevant port.
-
Suggested Fix: Add an
EXPOSE <port>statement for documentation and networking purposes.
-
Lack of
.npmrcCaching- If
.npmrccontains specific registry or authentication settings, it should be added before dependency installation for caching purposes and authentication consistency. -
Suggested Fix: Add
.npmrcbefore runningpnpm ito leverage caching and reduce unnecessary network requests.
- If
-
Unused
docsDirectory- Adding
docsto the image increases its size without being used by the application. -
Suggested Fix: Remove the
docsdirectory from the Dockerfile unless it’s necessary for runtime.
- Adding
-
Inconsistent Dependency Installation
- Multiple installations of dependencies without clearing caches or pinning versions may lead to conflicts or unexpected updates.
- Suggested Fix: Ensure dependencies are installed consistently in one step, and pin specific versions where possible.
-
Missing Health Checks
- Without a health check, monitoring systems like Kubernetes cannot accurately assess the container’s health.
-
Suggested Fix: Add a health check for better monitoring, e.g.:
HEALTHCHECK CMD curl -f http://localhost:<port> || exit 1
Suggested Refactored Dockerfile
Here’s a refactored Dockerfile with the suggested improvements:
# Stage 1: Build dependencies in a temporary stage
FROM node:22-alpine AS builder
# Install required global dependencies
RUN apk add --no-cache python3 make g++ \
&& npm install -g [email protected]
# Set working directory
WORKDIR /app
# Copy essential config files
COPY pnpm-workspace.yaml package.json .npmrc pnpm-lock.yaml ./
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy source code
COPY tsconfig.json ./
COPY docs ./docs
COPY packages ./packages
COPY scripts ./scripts
COPY characters ./characters
COPY src ./src
# Optional: build step if using TypeScript or other build process
# RUN pnpm build
# Stage 2: Production image
FROM node:22-alpine
# Install dependencies required for the final runtime
RUN apk add --no-cache python3 make g++ \
&& npm install -g [email protected]
# Create a non-root user and switch to it
RUN adduser -D appuser
USER appuser
# Set working directory
WORKDIR /app
# Copy built files from the builder stage
COPY --from=builder /app /app
# Expose application port if running a web server
EXPOSE 3000 # Adjust port as needed
# Add health check to ensure the app is running
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s CMD curl -f http://localhost:3000 || exit 1
# Set environment variables to configure runtime model settings
ENV NODE_ENV=production
# Add more default environment variables if needed, e.g., DISCORD_APPLICATION_ID, etc.
# Default command to run the application
CMD ["pnpm", "start"]
Merging this in would help to reduce exposure of the developers machine to the community developed code. A huge plus for me as a developer.