I am working on dockerizing my POS system, but I've encountered a challenge. In my setup, I usually store the printer's IP address in the product table of the database, as some products need to be printed on specific thermal printers.
However, after dockerizing the system, the printers are not working. While the data is successfully created in the database, the printers no longer print anything, even though they used to work fine before dockerization.
Here is my Dockerfile:
# Base image
FROM node:21-slim
# Set working directory
WORKDIR /app
# Copy package.json and install dependencies
COPY package*.json ./
RUN npm uninstall bcrypt
RUN npm install pm2 -g && npm install bcrypt && npm install
# Copy application files
COPY . .
# Copy Prisma schema directory
COPY prisma ./prisma
# Install required dependencies
RUN apt-get update -y && apt-get install -y openssl
# Generate Prisma client
RUN npx prisma generate
# Expose the app's port
EXPOSE 4000
# Start the app with PM2
CMD ["pm2-runtime", "ecosystem.config.js"]
docker-compose.yml:
build:
context: .
dockerfile: Dockerfile
container_name: pos
ports:
- "4000:4000"
env_file:
- .env
environment:
DATABASE_URL: "mysql://root:${DATABASE_PASSWORD}@${IP_ADDRESS}:3306/${DATABASE_NAME}?connection_limit=150&pool_timeout=20"
ACCESS_TOKEN: "37eb2d015162e05553cae95588485f3b18de5eb95182c97fc0df8293222010028d797515afefbb72b861c637c1288987e3628ed8103641eb53d439e630a90a6d"
ADMIN_PORT: 4500
PORT: 4000
REDIS_URL: "redis://redis:6379"
depends_on:
- redis
redis:
image: redis:alpine
container_name: redis ```
Im using tcpIp technique to send orders to printers (node-thermal-printer package): ```
let printer = new ThermalPrinter({
type: PrinterTypes.TANCA,
interface: "tcp://" + printerIp,
width: 40,
options: { timeout: 5000 }
});
I have successfully pinged the printer's IP from the Docker container. I also tried setting the network_mode
to host
in the app's configuration, but this caused a conflict between the app and Redis, as both are on the same network. When I changed the app to use the host network mode, I had to modify the Redis configuration, which I do not want to do.
This one doesn't work as well:
network_mode: "host"
environment:
REDIS_URL: "redis://172.18.0.2:6379" //CONTAINER'S IP
I managed to fix the issue by following these steps:
1- Modified the docker-compose.yml file to this one:
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: pos
ports:
- "4000:4000"
env_file:
- .env
environment:
DATABASE_URL: "mysql://root:${DATABASE_PASSWORD}@host.docker.internal:3306/${DATABASE_NAME}?connection_limit=150&pool_timeout=20"
ACCESS_TOKEN: "37eb2d015162e05553cae95588485f3b18de5eb95182c97fc0df8293222010028d797515afefbb72b861c637c1288987e3628ed8103641eb53d439e630a90a6d"
ADMIN_PORT: 4500
PORT: 4000
REDIS_URL: "redis://redis:6379" # Use service name "redis" for inter-container communication
depends_on:
- redis # Ensure Redis starts before the app
networks:
- app-network
volumes:
- pos:/app
redis:
image: redis:alpine
container_name: redis
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
pos:
2- And then pinged to the printer from the docker container through these steps:
Access the container:
docker exec -it <container_name_or_id> /bin/bash
Determine OS:
cat /etc/os-release
In my case it's debian, so I just installed necessary packages to ping the printer's IP address:
apt-get update && apt-get install -y iputils-ping
Then pinged the IP:
ping 192.168.1.100
All requests reached successfully.
exit the container
exit
3- Then modified the Dockerfile, installed some required libraries and packages to my container in order to be able to run Puppeteer and headless browser (I used in the vouchers):
# Base image
FROM node:21-slim
RUN apt-get update && apt-get install -y \
libglib2.0-0 \
libnss3 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcups2 \
libdrm2 \
libxkbcommon0 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxrandr2 \
libgbm1 \
libgtk-3-0 \
libasound2 \
libxshmfence1 \
chromium \
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy package.json and install dependencies
COPY package*.json ./
RUN npm install pm2 -g && npm install bcrypt && npm install
# Copy application files
COPY . .
# Copy Prisma schema directory
COPY prisma ./prisma
# Install required dependencies
RUN apt-get update -y && apt-get install -y openssl
# Generate Prisma client
RUN npx prisma generate
# Expose the app's port
EXPOSE 4000
# Start the app with PM2
CMD ["pm2-runtime", "ecosystem.config.js"]