Sitemap
Dungeon Keeper Studios

Dungeon Keeper Studios

A game development company.

WAX Blockchain Application Development: Client/Server with React and Node.js (VII)

7 min readJul 19, 2025

--

Press enter or click to view image in full size

Part 7: Deployment and Maintenance

Objective

Taking an application from the development environment to production and keeping it operational is the final and continuous phase of the software lifecycle. In this part, we will cover the essential aspects of deploying the server and client, automation with CI/CD tools, monitoring and logging in production, and strategies for long-term maintenance and updates.

1. Application Deployment

Deployment involves preparing and running your application on a server accessible to your users.

a. Server Deployment (Node.js/Express)

There are multiple options for deploying a Node.js application:

  • Platform as a Service (PaaS):
  • Examples: Heroku, Render, Google App Engine, AWS Elastic Beanstalk, Vercel (for serverless functions or Node.js servers).
  • Advantages: Simplify the deployment process, manage the underlying infrastructure (servers, basic load balancing, scaling).
  • General Process (e.g., with Render or Heroku):
  1. Prepare your application for production:
  • Ensure yarn start or a similar script (e.g., yarn serve:prod) runs the server in production mode.
  • Configure environment variables (PORT, MONGO_URI, WAXKEY, ACCOUNT, RPC_ENDPOINT, ALLOWED_ORIGINS, etc.) in the PaaS platform's dashboard. Never commit them to your repository.
  • Ensure process.env.NODE_ENV is set to 'production' in the deployment environment. This usually enables optimizations in Express and other libraries.
  1. Connect your Git repository to the platform.
  2. Configure build commands (if necessary, though for a pure Node.js server, it’s often just installing dependencies) and the start command.
  3. Deploy. The platform will handle fetching the code, installing dependencies, and running the server.
  • Infrastructure as a Service (IaaS) / Virtual Private Servers (VPS):
  • Examples: AWS EC2, Google Compute Engine, DigitalOcean Droplets, Linode.
  • Advantages: Greater control over the server environment.
  • Disadvantages: More responsibility for server configuration and maintenance (OS updates, security, network configuration, etc.).
  • General Process:
  1. Provision a virtual server.
  2. Configure the environment: install Node.js, Yarn, and any other system dependencies.
  3. Copy your application code to the server (e.g., using Git clone, scp, rsync).
  4. Install project dependencies: yarn install --production.
  5. Configure environment variables securely (e.g., using an unversioned .env file, or cloud provider tools).
  6. Process Manager: Use a process manager like PM2 or systemd to keep your Node.js application running in the background, restart it automatically in case of crashes, and manage logs.
  • Example with PM2:
```bash
# Install PM2 globally
sudo yarn global add pm2
# Start your application
pm2 start server.js --name "my-wax-api" # Or your package.json start script
# Save the configuration to restart on server reboot
pm2 save
pm2 startup
```

7. Reverse Proxy Server: Consider using Nginx or Apache in front of your Node.js application to:

  • Handle HTTPS connections (SSL termination).
  • Serve static content efficiently.
  • Basic load balancing.
  • Apply compression.
  • Containers (Docker and Kubernetes):
  • Advantages: Portability, consistency between environments, robust scalability with orchestrators like Kubernetes.
  • General Process:
  1. Create a Dockerfile for your server:
```dockerfile
# Use a Node.js base image
FROM node:18-alpine AS builder

WORKDIR /usr/src/app

# Copy package.json and yarn.lock
COPY package.json yarn.lock ./

# Install production dependencies
RUN yarn install --production --frozen-lockfile

# Copy the rest of the application source code
COPY . .

# (Optional) If you have a TypeScript build step
# RUN yarn build

# Smaller final image
FROM node:18-alpine

WORKDIR /usr/src/app

# Copy dependencies and code from the builder stage
COPY --from=builder /usr/src/app/node_modules ./node_modules
COPY --from=builder /usr/src/app/package.json ./package.json
# If you have a build, copy the dist/build folder
# COPY --from=builder /usr/src/app/dist ./dist
COPY --from=builder /usr/src/app/src ./src # Or path to your transpiled code if applicable
COPY --from=builder /usr/src/app/.env-cmdrc.json ./.env-cmdrc.json # If you use it this way

# Expose the port the application runs on
EXPOSE 3000 # Or the port you use

# Command to run the application
# Adjust the command based on how you start your server for production
CMD [ "yarn", "start" ]
```

2. Build the Docker image: docker build -t my-wax-api-server .

3. Run the container (locally for testing or on a container hosting service): docker run -p 3000:3000 -e NODE_ENV=production -e PORT=3000 --env-file ./prod.env my-wax-api-server (where prod.env is a file with your production environment variables).

Get Dungeon Keeper Studios’s stories in your inbox

Join Medium for free to get updates from this writer.

4. Push the image to a container registry (Docker Hub, AWS ECR, Google Container Registry) and then deploy to an orchestration service (Kubernetes, AWS ECS, Google Kubernetes Engine) or a PaaS that supports Docker.

b. Client Deployment (React/Vite)

The client is a static application once built.

  • General Process:
  1. Run the build command: cd Client && yarn build. This will generate optimized static files in the Client/dist/ folder.
  2. Deploy the contents of this dist/ folder to a static site hosting service.
  • Static Hosting Options:
  • Netlify, Vercel, GitHub Pages, Cloudflare Pages: Excellent options, many with generous free tiers, integrated CI/CD, automatic HTTPS, and CDN optimizations.
  • Cloud Storage Services: AWS S3 (configured for static hosting) + CloudFront (for CDN and HTTPS), Google Cloud Storage, Azure Blob Storage.
  • Traditional Web Server: You can also serve these files from a web server like Nginx or Apache.
  • Routing Configuration:
  • For Single Page Applications (SPAs) like React, ensure your hosting server is configured to redirect all route requests (e.g., /getinfo, /profile) to your main index.html file, so the React router can handle them. Most modern static hosts have settings for this.
  • Client Environment Variables:
  • Vite environment variables (prefixed with VITE_) are embedded into the build at compile time. Configure them in your CI/CD system or the environment where you run yarn build.

2. Using CI/CD Tools

Continuous Integration (CI) and Continuous Deployment (CD) automate the build, test, and deployment processes.

  • CI (Continuous Integration):
  • Whenever code is pushed to the repository (e.g., to main or a feature branch), a CI pipeline is automatically triggered.
  • Typical Steps:
  1. Fetch the latest code.
  2. Install dependencies.
  3. Run linters and formatters.
  4. Run unit and integration tests.
  5. (Optional) Build the application.
  6. (Optional) Generate test coverage reports.
  • If any step fails, the pipeline fails and notifies the team.
  • CD (Continuous Deployment / Continuous Delivery):
  • Continuous Delivery: After the CI pipeline passes successfully, the application (or a build artifact) is prepared and automatically deployed to a staging or pre-production environment for further testing (manual, E2E).
  • Continuous Deployment: If continuous delivery to staging is successful (and optionally after manual approval), the application is automatically deployed to production.
  • This reduces manual work, speeds up delivery, and decreases the risk of human error.
  • Popular CI/CD Tools:
  • GitHub Actions: Integrated directly into GitHub. You can create YAML workflows to define your pipelines.
  • GitLab CI/CD: Integrated into GitLab.
  • Jenkins: A very powerful and customizable self-hosted solution.
  • CircleCI, Travis CI, Bitbucket Pipelines: Cloud-based services.
  • Many PaaS platforms (Netlify, Vercel, Render) have built-in CI/CD that activates when you connect your Git repository.
  • Example of a Basic Workflow with GitHub Actions (conceptual):
  • A .github/workflows/main.yml file could define:
  • Triggers: on: push (for specific branches like main) and on: pull_request.
  • Jobs:
  • lint_and_test_server:
  • Checkout code.
  • Setup Node.js.
  • cd Server && yarn install --frozen-lockfile.
  • yarn lint.
  • yarn test.
  • lint_and_test_client:
  • Checkout code.
  • Setup Node.js.
  • cd Client && yarn install --frozen-lockfile.
  • yarn lint.
  • yarn test.
  • build_client (depends on lint_and_test_client):
  • cd Client && yarn build.
  • (Optional) Upload build artifact.
  • deploy_server (if main branch and lint_and_test_server passes):
  • Commands to deploy to your PaaS or build and push Docker image.
  • deploy_client (if main branch and build_client passes):
  • Commands to deploy to Netlify, Vercel, etc.

3. Application Monitoring and Logging

Once in production, you need to know what’s happening with your application.

  • Server-Side Logging:
  • Log Levels: Configure your logger (pino in this template) to use different levels (DEBUG, INFO, WARN, ERROR, FATAL) and ensure that in production the level is appropriate (usually INFO or WARN, with ERRORs always logged).
  • Structured Logs: pino produces JSON logs, which are good for processing by log management systems.
  • Log Aggregation: In production, especially with multiple server instances or containers, send your logs to a centralized log management system (e.g., ELK Stack — Elasticsearch, Logstash, Kibana; Grafana Loki; Datadog Logs; Sentry; Papertrail). This facilitates searching and analysis.
  • What to Log: Incoming requests (with metadata like IP, URL, method), important errors, significant business events, server starts and stops.
  • Server-Side Monitoring:
  • Key Metrics:
  • CPU and memory usage.
  • API response latency.
  • Error rate (e.g., percentage of 5xx requests).
  • Database performance (if applicable).
  • Status of connections to external services (like the WAX RPC).
  • Tools:
  • APM (Application Performance Monitoring): Datadog, New Relic, Dynatrace, Sentry (also does APM). These tools can instrument your code to collect detailed metrics and distributed traces.
  • Metrics-Based: Prometheus (collection) + Grafana (visualization).
  • Many cloud providers offer their own monitoring tools.
  • Client-Side Monitoring:
  • Error Tracking: Use services like Sentry, Bugsnag, or LogRocket to capture JavaScript errors that occur in users’ browsers.
  • Performance Analytics (Real User Monitoring — RUM): Tools like Sentry, Datadog RUM, Google Analytics (for page load metrics) can give you insights into how real users experience your client’s performance.
  • Core Web Vitals: Monitor these Google metrics for user experience.

4. Maintenance and Update Strategies

Maintaining an application is an ongoing effort.

  • Dependency Updates:
  • Regularly review and update dependencies (Node.js, server libraries, client libraries) to get new features, performance improvements, and, crucially, security patches.
  • Do this in a development/staging environment first and test thoroughly.
  • OS and Environment Security Patches:
  • If you manage your own servers (IaaS/VPS), ensure you apply security patches to the operating system and other stack components.
  • Backups (If Applicable):
  • If your server uses a database, implement and regularly test a backup and restore strategy. For the WAX blockchain, data is decentralized, but your cache or any auxiliary data you store might need backups.
  • Refactoring and Technical Debt:
  • Dedicate time to refactor code to keep it clean, understandable, and efficient. Address technical debt before it becomes a major problem.
  • End-of-Life (EOL) Planning for Components:
  • Be aware of the lifecycle of the technologies and libraries you use. Plan migrations if key components become obsolete or unsupported.
  • Listen to Users:
  • Collect user feedback to identify bugs, pain points, and desired features. This will guide your maintenance and future development efforts.

Conclusion of Part 7 and the Tutorial

Congratulations on reaching the end of this tutorial! We have covered a broad spectrum of topics, from the initial setup of the WAX client/server template to feature development, best practices, and finally, deployment and maintenance.

Deploying and maintaining an application is a significant step. Remember that specific tools and strategies may vary based on your needs, budget, and application scale. The key is to start with good practices, automate as much as possible, and be prepared to iterate and improve continuously.

This template has provided you with a solid foundation. You now have the knowledge to expand it, customize it, and bring your WAX dApp ideas to life. Good luck with your WAX blockchain developments!

This tutorial is part of a series on application development in the WAX blockchain by the 3DK Render team and Dungeon Keeper Studios. Stay tuned for our upcoming installments.

--

--