Docker provides a containerized deployment solution for DoctorSoft+, making it easy to deploy to self-hosted environments, cloud providers, or orchestration platforms like Kubernetes.
Prerequisites
Before deploying with Docker, ensure you have:
Docker installed (Download Docker )
Docker Compose (optional, for easier configuration)
Supabase project URL and anon key
All required environment variables
Dockerfile overview
DoctorSoft+ includes a Dockerfile in the repository root:
FROM node:lts-alpine
ENV NODE_ENV=testing
WORKDIR /usr/src/app
COPY [ "package.json" , "package-lock.json*" , "npm-shrinkwrap.json*" , "./" ]
RUN npm install --production --silent && mv node_modules ../
COPY . .
EXPOSE 3000
RUN chown -R node /usr/src/app
USER node
CMD [ "npm" , "start" ]
This Dockerfile uses the lightweight Alpine Linux base image and runs the container as a non-root user for security.
Building the Docker image
Clone the repository
If you haven’t already, clone the DoctorSoft+ repository: git clone https://github.com/your-org/doctorsoft-plus.git
cd doctorsoft-plus
Build the image
Build the Docker image using the provided Dockerfile: docker build -t doctorsoft-plus:latest .
This command:
Uses the Dockerfile in the current directory
Tags the image as doctorsoft-plus:latest
Installs dependencies and copies application files
Verify the build
List your Docker images to verify the build: docker images | grep doctorsoft-plus
You should see: doctorsoft-plus latest abc123def456 2 minutes ago 250MB
Running the container
Basic usage
Run the container with environment variables:
docker run -d \
--name doctorsoft-plus \
-p 3000:3000 \
-e VITE_SUPABASE_URL=https://your-project.supabase.co \
-e VITE_SUPABASE_ANON_KEY=your-anon-key \
-e VITE_MAX_FILE_SIZE_MB= 10 \
-e VITE_BUCKET_NAME=your-bucket-name \
doctorsoft-plus:latest
Parameters:
-d: Run in detached mode (background)
--name: Container name for easy reference
-p 3000:3000: Map port 3000 on host to port 3000 in container
-e: Set environment variables
Using environment file
For easier management, use an environment file:
Create environment file
Create a .env.docker file: # .env.docker
VITE_SUPABASE_URL = https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY = your-anon-key-here
VITE_MAX_FILE_SIZE_MB = 10
VITE_BUCKET_NAME = your-bucket-name
VITE_APP_VERSION = 25.40
Never commit this file to version control. Add .env.docker to your .gitignore.
Run with environment file
docker run -d \
--name doctorsoft-plus \
-p 3000:3000 \
--env-file .env.docker \
doctorsoft-plus:latest
Access the application
Once running, access the application at:
Or on your server’s IP address:
http://your-server-ip:3000
Docker Compose
For a more maintainable setup, use Docker Compose:
Create docker-compose.yml
Create a docker-compose.yml file in your project root: version : '3.8'
services :
app :
build :
context : .
dockerfile : Dockerfile
image : doctorsoft-plus:latest
container_name : doctorsoft-plus
restart : unless-stopped
ports :
- "3000:3000"
environment :
- NODE_ENV=production
- VITE_SUPABASE_URL=${VITE_SUPABASE_URL}
- VITE_SUPABASE_ANON_KEY=${VITE_SUPABASE_ANON_KEY}
- VITE_MAX_FILE_SIZE_MB=${VITE_MAX_FILE_SIZE_MB:-10}
- VITE_BUCKET_NAME=${VITE_BUCKET_NAME:-00000000-default-bucket}
- VITE_APP_VERSION=${VITE_APP_VERSION:-25.40}
env_file :
- .env.docker
healthcheck :
test : [ "CMD" , "wget" , "--quiet" , "--tries=1" , "--spider" , "http://localhost:3000" ]
interval : 30s
timeout : 10s
retries : 3
start_period : 40s
Start with Docker Compose
Start the application: Useful commands:
View logs: docker-compose logs -f
Stop: docker-compose down
Restart: docker-compose restart
Rebuild: docker-compose up -d --build
Production Dockerfile
For production deployments, consider this optimized multi-stage Dockerfile:
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production && \
npm cache clean --force
# Copy source code
COPY . .
# Build application
RUN npm run build
# Production stage
FROM nginx:alpine AS production
# Copy built assets from builder
COPY --from=builder /app/dist /usr/share/nginx/html
# Copy nginx configuration for SPA routing
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Expose port 80
EXPOSE 80
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost/health || exit 1
# Start nginx
CMD [ "nginx" , "-g" , "daemon off;" ]
Nginx configuration
Create an nginx.conf file for SPA routing:
server {
listen 80 ;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Gzip compression
gzip on ;
gzip_vary on ;
gzip_min_length 1024 ;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;
# Security headers
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Cache static assets
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable" ;
}
# SPA routing - serve index.html for all routes
location / {
try_files $ uri $ uri / /index.html;
}
# Health check endpoint
location /health {
access_log off ;
return 200 "healthy \n " ;
add_header Content-Type text/plain;
}
}
Build production image
docker build -f Dockerfile.production -t doctorsoft-plus:production .
Run the production container:
docker run -d \
--name doctorsoft-plus-prod \
-p 80:80 \
doctorsoft-plus:production
The production Dockerfile uses Nginx to serve static files, resulting in a much smaller image (~50MB vs ~250MB) and better performance.
Container management
View logs
# Follow logs in real-time
docker logs -f doctorsoft-plus
# View last 100 lines
docker logs --tail 100 doctorsoft-plus
# View logs with timestamps
docker logs -t doctorsoft-plus
Stop and start
# Stop container
docker stop doctorsoft-plus
# Start container
docker start doctorsoft-plus
# Restart container
docker restart doctorsoft-plus
Update application
# Pull latest code
git pull
# Rebuild image
docker build -t doctorsoft-plus:latest .
# Stop old container
docker stop doctorsoft-plus
docker rm doctorsoft-plus
# Run new container
docker run -d \
--name doctorsoft-plus \
-p 3000:3000 \
--env-file .env.docker \
doctorsoft-plus:latest
Remove container and image
# Stop and remove container
docker stop doctorsoft-plus
docker rm doctorsoft-plus
# Remove image
docker rmi doctorsoft-plus:latest
Troubleshooting
Container won’t start
Check logs:
docker logs doctorsoft-plus
Common causes:
Missing required environment variables
Port 3000 already in use
Invalid Supabase credentials
Solutions:
Verify all environment variables are set
Use a different port: -p 8080:3000
Check Supabase URL and anon key
Application not accessible
Verify container is running:
docker ps | grep doctorsoft-plus
Check port mapping:
docker port doctorsoft-plus
Solutions:
Ensure port is not blocked by firewall
Verify correct port mapping in docker run command
Check if container is healthy: docker inspect doctorsoft-plus
Build fails
Common causes:
Missing files in build context
Network issues during npm install
Insufficient disk space
Solutions:
Ensure all files are committed to git
Check internet connection
Free up disk space: docker system prune
Build with verbose output: docker build --progress=plain -t doctorsoft-plus:latest .
Deployment to cloud providers
AWS ECS
Push image to Amazon ECR
Create ECS task definition
Configure environment variables
Deploy to ECS cluster
Google Cloud Run
# Build and push to Google Container Registry
gcloud builds submit --tag gcr.io/PROJECT_ID/doctorsoft-plus
# Deploy to Cloud Run
gcloud run deploy doctorsoft-plus \
--image gcr.io/PROJECT_ID/doctorsoft-plus \
--platform managed \
--set-env-vars VITE_SUPABASE_URL=https://your-project.supabase.co,VITE_SUPABASE_ANON_KEY=your-key
Push code to GitHub
Create new app from GitHub repo
Configure environment variables in dashboard
Deploy automatically
Kubernetes
Create Kubernetes deployment and service manifests:
apiVersion : apps/v1
kind : Deployment
metadata :
name : doctorsoft-plus
spec :
replicas : 3
selector :
matchLabels :
app : doctorsoft-plus
template :
metadata :
labels :
app : doctorsoft-plus
spec :
containers :
- name : doctorsoft-plus
image : doctorsoft-plus:production
ports :
- containerPort : 80
env :
- name : VITE_SUPABASE_URL
valueFrom :
secretKeyRef :
name : doctorsoft-secrets
key : supabase-url
- name : VITE_SUPABASE_ANON_KEY
valueFrom :
secretKeyRef :
name : doctorsoft-secrets
key : supabase-anon-key
Next steps
Environment Variables Configure environment variables for Docker
Deployment Overview Back to deployment overview
Docker Documentation Official Docker documentation
Docker Compose Learn more about Docker Compose