# Multi-stage build for ShareJS library
# Builder stage: install dependencies and build dist assets
FROM node:slim AS builder
WORKDIR /usr/src/sharejs
# Install dependencies first for caching
COPY package.json ./
RUN npm install
# Copy the rest of the repository and build
COPY . .
RUN npm run build
# Runtime stage: only include built assets
FROM node:slim
WORKDIR /usr/src/sharejs
# Copy built artifacts from builder
COPY --from=builder /usr/src/sharejs/dist ./dist
# Default command: indicate build is complete and exit
CMD ["node", "-e", "console.log('ShareJS dist ready');"]
FROM node:slim AS builder
WORKDIR /usr/src/sharejs
# Install system dependencies needed for building (make)
COPY package.json ./
RUN apt-get update && apt-get install -y make
RUN npm install
# Copy the rest of the repository and build
COPY . .
RUN npm run build
FROM node:slim
WORKDIR /usr/src/sharejs
# Copy built artifacts from builder
COPY --from=builder /usr/src/sharejs/dist ./dist
# Create a tiny HTTP server to serve the built assets
RUN bash -lc 'cat > server.js << "EOF"
const http = require("http");
const fs = require("fs");
const path = require("path");
const distDir = path.resolve(__dirname, "dist");
const server = http.createServer((req, res) => {
// Serve dist files relative to root. If root is requested, serve share.js by default.
let reqPath = req.url;
if (reqPath === "/" || reqPath === "") reqPath = "/share.js";
const absPath = path.join(distDir, reqPath);
fs.stat(absPath, (err, stat) => {
if (err || !stat.isFile()) {
res.statusCode = 404;
res.end("Not Found");
return;
}
const stream = fs.createReadStream(absPath);
stream.on("error", () => {
res.statusCode = 500;
res.end("Server error");
});
stream.pipe(res);
});
});
const port = process.env.PORT || 8080;
server.listen(port, () => {
console.log("ShareJS dist server listening on port " + port);
});
EOF'
CMD ["node", "server.js"]
FROM node:slim AS builder
WORKDIR /usr/src/sharejs
# Install system dependencies needed for building (make)
COPY package.json ./
RUN apt-get update && apt-get install -y make
RUN npm install
# Copy the rest of the repository and build
COPY . .
RUN npm run build
FROM node:slim
WORKDIR /usr/src/sharejs
# Copy built artifacts from builder
COPY --from=builder /usr/src/sharejs/dist ./dist
# Expose a tiny static server to serve the built assets
CMD ["node", "-e", "const http=require('http'); const fs=require('fs'); const path=require('path'); const dist=path.resolve(__dirname,'dist'); const server=http.createServer((req,res)=>{ let p=req.url; if(p==='/'||p==='') p='/share.js'; const abs=path.join(dist,p); fs.stat(abs,(err,stat)=>{ if(err||!stat.isFile()){ res.statusCode=404; res.end('Not Found'); return; } const rs=fs.createReadStream(abs); rs.on('error',()=>{ res.statusCode=500; res.end('Server error');}); rs.pipe(res); }); }); const port=process.env.PORT||8080; server.listen(port,()=>{ console.log('ShareJS dist server listening on',port); });"]
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
FROM node:slim AS builder WORKDIR /usr/src/sharejs # Install system dependencies needed for building (make) COPY package.json ./ RUN apt-get update && apt-get install -y make RUN npm install # Copy the rest of the repository and build COPY . . RUN npm run build FROM node:slim WORKDIR /usr/src/sharejs # Copy built artifacts from builder COPY --from=builder /usr/src/sharejs/dist ./dist # Install a tiny static file server to serve the built assets RUN npm install -g http-server EXPOSE 8080 CMD ["http-server", "dist", "-p", "8080"]
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
# Ignore source and test artifacts to keep the build context small .git node_modules test examples coverage *.log npm-debug.log .DS_Store README.md LICENSE Makefile # Dist is produced by the build, ignore any pre-existing copies dist
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
# Multi-stage build for ShareJS dist assets
FROM node:slim AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
make \
python3 \
g++ \
gcc && \
rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/sharejs
# Install dependencies first (best for caching)
COPY package.json .
RUN npm install
# Copy the rest of the source and build
COPY . .
RUN npm run build
# Runtime stage
FROM node:slim
WORKDIR /usr/src/sharejs
# Copy built artifacts from builder stage
COPY --from=builder /usr/src/sharejs/dist /usr/src/sharejs/dist
# Add a tiny static server to serve the dist files
RUN printf 'const http=require("http");\nconst fs=require("fs");\nconst path=require("path");\nconst root=path.resolve(__dirname,"dist");\nconst port=process.env.PORT || 8080;\nconst mime={"js":"application/javascript","min.js":"application/javascript","html":"text/html","css":"text/css","png":"image/png","svg":"image/svg+xml"};\nhttp.createServer((req,res)=>{\n let file=req.url==='/'? '/index.html': req.url;\n let filePath=path.join(root,file);\n fs.exists(filePath,(exists)=>{\n if(!exists){ res.statusCode=404; res.end("Not Found"); return;}\n fs.readFile(filePath,(err,data)=>{\n if(err){ res.statusCode=500; res.end("Server Error"); return;}\n const ext=path.extname(filePath).slice(1);\n res.setHeader("Content-Type", mime[ext]||"application/octet-stream");\n res.end(data);\n });\n });\n}).listen(port, ()=>{ console.log("Serving on", port); });' > server.js && \
chmod +x server.js
EXPOSE 8080
CMD ["node","server.js"]
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
# Docker build context ignore file .git node_modules dist examples/** test/** *.log coverage .DS_Store *.md *.coffee **/*.swp **/*.tmp Dockerfile
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
# Multi-stage build for ShareJS dist assets
FROM node:slim AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
make \
python3 \
g++ \
gcc && \
rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/sharejs
# Install dependencies first (best for caching)
COPY package.json .
RUN npm install
# Copy the rest of the source and build
COPY . .
RUN npm run build
# Runtime stage
FROM node:slim
WORKDIR /usr/src/sharejs
# Copy built artifacts from builder stage
COPY --from=builder /usr/src/sharejs/dist /usr/src/sharejs/dist
# Add a tiny static server to serve the dist files
RUN bash -lc 'cat > server.js <<"JS"
const http=require("http");
const fs=require("fs");
const path=require("path");
const root=path.resolve(__dirname,"dist");
const port=process.env.PORT || 8080;
function serve(res, file){
fs.readFile(file, (err, data)=>{
if(err){ res.statusCode=404; res.end("Not Found"); return; }
res.setHeader("Content-Type","application/javascript");
res.end(data);
});
}
http.createServer((req,res)=>{
const url = req.url;
if (url === '/' || url === '/share.js') {
serve(res, path.join(root, 'share.js'));
} else if (url === '/share.min.js') {
serve(res, path.join(root, 'share.min.js'));
} else {
res.statusCode = 404; res.end('Not Found');
}
}).listen(port, ()=>{ console.log("Serving on", port); });
JS'
RUN node -e "require('fs').chmodSync('server.js','755')" || true
EXPOSE 8080
CMD ["node","server.js"]
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
FROM node:slim AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends make \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
# Install dependencies first (lockfile optional)
COPY package.json package.json
COPY package.json package-lock.json* ./
RUN npm install
# Copy the rest of the source and build
COPY . .
RUN npm run build
# Runtime stage: lightweight image that serves the built assets
FROM node:slim
WORKDIR /usr/src/app
# Copy built assets from builder
COPY --from=builder /usr/src/app/dist ./dist
# Create a tiny static server to serve the dist assets
RUN mkdir -p /usr/src/app && \
cat > /usr/src/app/server.js << 'JS'
const http = require('http');
const fs = require('fs');
const path = require('path');
const distDir = path.resolve(__dirname, 'dist');
function mime(ext) {
switch (ext) {
case '.js': return 'application/javascript';
case '.min.js': return 'application/javascript';
case '.css': return 'text/css';
case '.html': return 'text/html';
case '.json': return 'application/json';
default: return 'application/octet-stream';
}
}
const server = http.createServer((req, res) => {
let filePath = req.url;
if (filePath === '/' || filePath === '') {
filePath = '/index.html';
}
if (filePath.includes('..')) {
res.statusCode = 400;
return res.end('Bad request');
}
const fullPath = path.join(distDir, filePath);
fs.readFile(fullPath, (err, data) => {
if (err) {
res.statusCode = 404;
return res.end('Not found');
}
res.setHeader('Content-Type', mime(path.extname(fullPath)));
res.end(data);
});
});
server.listen(8080, () => {
console.log('Dist server listening on port 8080');
});
JS
EXPOSE 8080
CMD ["node", "/usr/src/app/server.js"]
# Ignore version control .git .gitignore # Node modules (will be installed in build stage) node_modules/ # Source / tests / docs not needed in final image test/ examples/ README.md CHANGELOG.md metadata.md Makefile **/*.coffee # Logs / coverage *.log coverage/ # Environment files .env # Docker related Dockerfile
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
FROM node:slim AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends make \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
# Install dependencies first (lockfile optional)
COPY package*.json ./
RUN npm install
# Copy the rest of the source and build
COPY . .
RUN npm run build
# Runtime stage: lightweight image that serves the built assets
FROM node:slim
WORKDIR /usr/src/app
# Copy built assets from builder
COPY --from=builder /usr/src/app/dist ./dist
# Create a tiny static server to serve the dist assets
RUN mkdir -p /usr/src/app && \
cat > /usr/src/app/server.js << 'JS'
const http = require('http');
const fs = require('fs');
const path = require('path');
const distDir = path.resolve(__dirname, 'dist');
function mime(ext) {
switch (ext) {
case '.js': return 'application/javascript';
case '.min.js': return 'application/javascript';
case '.css': return 'text/css';
case '.html': return 'text/html';
case '.json': return 'application/json';
default: return 'application/octet-stream';
}
}
const server = http.createServer((req, res) => {
let filePath = req.url;
if (filePath === '/' || filePath === '') {
filePath = '/index.html';
}
if (filePath.includes('..')) {
res.statusCode = 400;
return res.end('Bad request');
}
const fullPath = path.join(distDir, filePath);
fs.readFile(fullPath, (err, data) => {
if (err) {
res.statusCode = 404;
return res.end('Not found');
}
res.setHeader('Content-Type', mime(path.extname(fullPath)));
res.end(data);
});
});
server.listen(8080, () => {
console.log('Dist server listening on port 8080');
});
JS
EXPOSE 8080
CMD ["node", "/usr/src/app/server.js"]
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
FROM node:slim AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends make \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
# Install dependencies first (lockfile optional)
COPY package*.json ./
RUN npm install
# Copy the rest of the source and build
COPY . .
RUN npm run build
# Runtime stage: lightweight image that serves the built assets
FROM node:slim
WORKDIR /usr/src/app
# Copy built assets from builder
COPY --from=builder /usr/src/app/dist ./dist
# Create a tiny static server to serve the dist assets
RUN mkdir -p /usr/src/app && \
cat > /usr/src/app/server.js << 'JS'
const http = require('http');
const fs = require('fs');
const path = require('path');
const distDir = path.resolve(__dirname, 'dist');
function mime(ext) {
switch (ext) {
case '.js': return 'application/javascript';
case '.min.js': return 'application/javascript';
case '.css': return 'text/css';
case '.html': return 'text/html';
case '.json': return 'application/json';
default: return 'application/octet-stream';
}
}
const server = http.createServer((req, res) => {
let filePath = req.url;
if (filePath === '/' || filePath === '') {
filePath = '/index.html';
}
// Normalize and prevent directory traversal
if (filePath.includes('..')) {
res.statusCode = 400;
return res.end('Bad request');
}
// Remove leading slash to form a proper path inside dist
if (filePath.startsWith('/')) {
filePath = filePath.slice(1);
}
const fullPath = path.join(distDir, filePath);
fs.readFile(fullPath, (err, data) => {
if (err) {
res.statusCode = 404;
return res.end('Not found');
}
res.setHeader('Content-Type', mime(path.extname(fullPath)));
res.end(data);
});
});
server.listen(8080, () => {
console.log('Dist server listening on port 8080');
});
JS
EXPOSE 8080
CMD ["node", "/usr/src/app/server.js"]
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock