Overview
The project includes two Dockerfile configurations for different deployment scenarios:
- Main Dockerfile - Full web app with built-in proxy server
- Dockerfile.proxy - Standalone proxy server only
Using Docker eliminates the need for manual Node.js, pnpm, and dependency installation steps from CONTRIBUTING.md.
Main Dockerfile (Full Application)
The main Dockerfile builds the complete Minecraft Web Client with proxy support for production deployment.
Build Arguments
The Dockerfile accepts several build arguments for customization:
ARG DOWNLOAD_SOUNDS=false
ARG DISABLE_SERVICE_WORKER=false
ARG CONFIG_JSON_SOURCE=REMOTE
Available Arguments:
DOWNLOAD_SOUNDS - Download sound files during build (default: false)
DISABLE_SERVICE_WORKER - Disable service worker for offline support (default: false)
CONFIG_JSON_SOURCE - Configuration source: REMOTE or LOCAL (default: REMOTE)
Building the Image
Basic Build
Build with default settings:docker build -t minecraft-web-client .
Build with Sounds
Include sound files in the image:docker build \
--build-arg DOWNLOAD_SOUNDS=true \
-t minecraft-web-client .
Custom Configuration
Use local configuration:docker build \
--build-arg CONFIG_JSON_SOURCE=LOCAL \
--build-arg DISABLE_SERVICE_WORKER=true \
-t minecraft-web-client .
Running the Container
docker run -p 8080:8080 minecraft-web-client
With custom configuration volume:
docker run -p 8080:8080 \
-v $(pwd)/public:/app/public \
minecraft-web-client
Access the application at http://localhost:8080
Dockerfile Structure
The main Dockerfile uses a multi-stage build for optimization:
# ---- Build Stage ----
FROM node:18-alpine AS build
RUN apk add git
WORKDIR /app
COPY . /app
RUN corepack enable
# Prepare and install
RUN node ./scripts/dockerPrepare.mjs
RUN pnpm i
# Download sounds if enabled
RUN if [ "$DOWNLOAD_SOUNDS" = "true" ] ; then \
node scripts/downloadSoundsMap.mjs ; fi
# Build for production
RUN DISABLE_SERVICE_WORKER=$DISABLE_SERVICE_WORKER \
CONFIG_JSON_SOURCE=$CONFIG_JSON_SOURCE \
pnpm run build
# ---- Run Stage ----
FROM node:18-alpine
RUN apk add git
WORKDIR /app
# Copy build artifacts
COPY --from=build /app/dist /app/dist
COPY server.js /app/server.js
# Install runtime dependencies
RUN npm i -g [email protected]
RUN npm init -yp
RUN pnpm i express \
github:zardoy/prismarinejs-net-browserify \
compression cors
EXPOSE 8080
VOLUME /app/public
ENTRYPOINT ["node", "server.js", "--prod"]
Environment Variables
Pass environment variables at runtime:
docker run -p 8080:8080 \
-e NODE_ENV=production \
-e TIMEOUT=15000 \
-e LOG=true \
minecraft-web-client
Available Variables:
| Variable | Description | Default |
|---|
NODE_ENV | Environment mode | production (with —prod flag) |
TIMEOUT | Connection timeout (ms) | 10000 |
LOG | Enable connection logging | false |
Proxy Dockerfile (Standalone Proxy)
For deploying only the proxy server without the full web application.
Building the Proxy Image
docker build . -f Dockerfile.proxy -t minecraft-web-proxy
Running the Proxy Container
docker run -p 8080:8080 minecraft-web-proxy
Proxy Dockerfile Structure
# ---- Run Stage ----
FROM node:18-alpine
RUN apk add git
WORKDIR /app
COPY server.js /app/server.js
# Install server dependencies
RUN npm i -g [email protected]
RUN npm init -yp
RUN pnpm i express \
github:zardoy/prismarinejs-net-browserify \
compression cors
EXPOSE 8080
ENTRYPOINT ["node", "server.js"]
The proxy Dockerfile is much smaller since it doesn’t include the build stage or web application files.
Docker Compose
For easier orchestration, use Docker Compose:
Full Application
version: '3.8'
services:
minecraft-web-client:
build:
context: .
args:
DOWNLOAD_SOUNDS: "false"
DISABLE_SERVICE_WORKER: "false"
CONFIG_JSON_SOURCE: "REMOTE"
ports:
- "8080:8080"
volumes:
- ./public:/app/public
environment:
- NODE_ENV=production
- TIMEOUT=10000
- LOG=false
restart: unless-stopped
Proxy Only
version: '3.8'
services:
minecraft-proxy:
build:
context: .
dockerfile: Dockerfile.proxy
ports:
- "8080:8080"
environment:
- LOG=true
- TIMEOUT=15000
restart: unless-stopped
Start with Docker Compose
# Start in detached mode
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down
Production Best Practices
The server includes CORS support by default:const cors = require('cors')
app.use(cors())
For production, consider restricting origins:app.use(cors({
origin: 'https://yourdomain.com'
}))
Use Volume Mounts for Configuration
Mount a local directory for runtime configuration:docker run -p 8080:8080 \
-v $(pwd)/public:/app/public:ro \
minecraft-web-client
Place custom config.json in the public directory.
The server uses compression middleware by default:const compression = require('compression')
app.use(compression())
This reduces bandwidth usage significantly. Set SharedArrayBuffer Headers
Reverse Proxy Configuration
Nginx
server {
listen 80;
server_name play.example.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Caddy
play.example.com {
reverse_proxy localhost:8080
}
Health Checks
Add health check to your Docker configuration:
services:
minecraft-web-client:
# ... other config
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Resource Limits
Set memory and CPU limits:
services:
minecraft-web-client:
# ... other config
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
Debugging Containers
View Container Logs
# Follow logs
docker logs -f <container_id>
# Last 100 lines
docker logs --tail 100 <container_id>
Execute Commands in Running Container
# Open shell
docker exec -it <container_id> sh
# Check running processes
docker exec <container_id> ps aux
Inspect Container
docker inspect <container_id>
Troubleshooting
Build Fails: Git Not Found
The Dockerfile installs git in the Alpine image:Ensure this line is present in your Dockerfile. Container Exits Immediately
Use a different host port:docker run -p 3000:8080 minecraft-web-client
Ensure the path exists and has correct permissions:mkdir -p public
chmod 755 public
docker run -v $(pwd)/public:/app/public minecraft-web-client
Next Steps