Automate Docker image builds in GitHub Actions. Learn tagging strategies, build optimization, and how to build images for every commit automatically.
Set up a Node.js app with Dockerfile for CI/CD practice.
mkdir docker-ci-app && cd docker-ci-appnpm init -ynpm install expresscat > app.js << 'EOF'
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.json({
message: 'Hello from Docker CI!',
version: process.env.APP_VERSION || 'dev',
commit: process.env.GIT_COMMIT || 'unknown'
});
});
app.get('/health', (req, res) => {
res.json({ status: 'healthy', timestamp: new Date().toISOString() });
});
app.listen(PORT, '0.0.0.0', () => {
console.log(`Server running on port ${PORT}`);
});
EOFcat > Dockerfile << 'EOF'
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY app.js .
EXPOSE 3000
CMD ["node", "app.js"]
EOFdocker build -t docker-ci-app:local .docker run -d -p 3000:3000 --name test-app docker-ci-app:localcurl http://localhost:3000docker stop test-app && docker rm test-appWe create an Express app that displays version and commit info from environment variables. The Dockerfile uses best practices: Alpine base, npm ci, and proper layer ordering.
App builds and runs successfully. curl returns JSON with message, version, and commit. Container stops cleanly.