This commit is contained in:
Dennis Postma 2025-02-07 02:01:16 +01:00
parent 8b0746958e
commit b2f7d45a1f
3 changed files with 101 additions and 35 deletions

View File

@ -1,33 +1,46 @@
# Use the official Node.js 22.4.1 image # Build stage
FROM node:23.7.0-alpine FROM node:23.7.0-alpine AS builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Install Redis, MySQL, and tmux # Production stage
RUN apk add --no-cache redis mysql mysql-client tmux && \ FROM node:23.7.0-alpine
mkdir -p /run/mysqld && \ LABEL maintainer="Your Name"
LABEL version="1.0"
LABEL description="NQ Server Application"
# Install dependencies with versions
RUN apk add --no-cache \
redis=7.0.15-r0 \
mysql=10.11.6-r0 \
mysql-client=10.11.6-r0 \
tmux=3.3a-r0
# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Setup MySQL
RUN mkdir -p /run/mysqld && \
chown -R mysql:mysql /run/mysqld && \ chown -R mysql:mysql /run/mysqld && \
mysql_install_db --user=mysql --datadir=/var/lib/mysql mysql_install_db --user=mysql --datadir=/var/lib/mysql
# Set the working directory in the container WORKDIR /usr/src/app
WORKDIR /usr/src/ COPY --from=builder /usr/src/app/dist ./dist
COPY --from=builder /usr/src/app/package*.json ./
COPY docker-start.sh ./dist/start.sh
# Copy package.json and package-lock.json (if available) RUN npm ci --only=production && \
COPY package*.json ./ chmod +x ./dist/start.sh && \
chown -R appuser:appgroup .
# Install application dependencies USER appuser
RUN npm install
# Copy the rest of your application code to the container
COPY . .
# Build the application
RUN npm run build
# Expose the ports your Node.js application, Redis, and MySQL will listen on
EXPOSE 80 6379 3306 EXPOSE 80 6379 3306
# Copy and make the startup script executable HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
COPY docker-start.sh /usr/src/dist/start.sh CMD mysqladmin ping -h localhost || exit 1
RUN chmod +x /usr/src/dist/start.sh
# Use the shell script as the entry point CMD ["./dist/start.sh"]
CMD ["/usr/src/dist/start.sh"]

View File

@ -1,24 +1,73 @@
#!/bin/sh #!/bin/sh
set -e
# Start Redis in the background # Configuration
MAX_MYSQL_WAIT=60
APP_NAME="nodeapp"
# Cleanup function
cleanup() {
echo "Cleaning up..."
tmux kill-session -t $APP_NAME 2>/dev/null || true
redis-cli shutdown || true
mysqladmin -u root shutdown || true
exit 0
}
# Setup cleanup trap
trap cleanup SIGTERM SIGINT
# Start Redis
echo "Starting Redis..."
redis-server --daemonize yes redis-server --daemonize yes
if ! redis-cli ping > /dev/null 2>&1; then
echo "Failed to start Redis"
exit 1
fi
# Start MySQL # Start MySQL
echo "Starting MySQL..."
mysqld --user=mysql --datadir=/var/lib/mysql & mysqld --user=mysql --datadir=/var/lib/mysql &
# Wait for MySQL to be ready # Wait for MySQL with timeout
echo "Waiting for MySQL to be ready..."
COUNTER=0
while ! mysqladmin ping -h localhost --silent; do while ! mysqladmin ping -h localhost --silent; do
echo "Waiting for MySQL to be ready..." if [ $COUNTER -gt $MAX_MYSQL_WAIT ]; then
sleep 2 echo "MySQL failed to start within $MAX_MYSQL_WAIT seconds"
exit 1
fi
echo "Still waiting..."
sleep 2
COUNTER=$((COUNTER+2))
done done
echo "MySQL is ready!" echo "MySQL is ready!"
# Run database migrations # Run migrations with error handling
npx mikro-orm migration:up echo "Running database migrations..."
if ! npx mikro-orm migration:up; then
echo "Migration failed"
exit 1
fi
# Start the Node.js application in a tmux session # Start application in tmux
tmux new-session -d -s nodeapp "npm run start" echo "Starting application..."
echo "App is running in tmux session. Attach with: tmux attach-session -t nodeapp" tmux new-session -d -s $APP_NAME "npm run start"
echo "App is running in tmux session. Attach with: tmux attach-session -t $APP_NAME"
# Keep container running # Monitor key processes
tail -f /dev/null while true; do
if ! redis-cli ping > /dev/null 2>&1; then
echo "Redis died"
exit 1
fi
if ! mysqladmin ping -h localhost --silent; then
echo "MySQL died"
exit 1
fi
if ! tmux has-session -t $APP_NAME 2>/dev/null; then
echo "Application died"
exit 1
fi
sleep 30
done

View File

@ -8,6 +8,10 @@
"moduleDetection": "force", "moduleDetection": "force",
"allowJs": true, "allowJs": true,
"declaration": true, "declaration": true,
"noImplicitAny": true,
"resolveJsonModule": true,
"sourceMap": true,
"isolatedModules": true,
// Best practices // Best practices
"strict": true, "strict": true,
@ -16,7 +20,7 @@
// Output // Output
"outDir": "./dist", "outDir": "./dist",
"rootDir": "./", "rootDir": "./src",
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {