How to Run a Mono Application in Docker: A Step-by-Step Tutorial

Learn how to containerize and run a legacy Mono application using Docker. This step-by-step guide covers creating a Dockerfile, setting up Docker Compose, and leveraging health checks and auto-healing for seamless deployment.

How to Run a Mono Application in Docker: A Step-by-Step Tutorial
Mono and Docker: A winning combination?

Running a Mono Application in Docker

What is Mono?

Mono is a cross-platform, open-source .NET framework that enables developers to create applications that run on multiple operating systems. It's especially useful for maintaining legacy applications built with earlier versions of .NET.

I have an old application written in Mono that I still need to maintain. However, managing its dependencies on my VPS had become a hassle, so I decided to containerize it using Docker. Here's how I did it.


What You'll Need

  • Docker
  • Dockerfile
  • Docker Compose (optional)

Writing a Dockerfile for an Old Mono Application

We'll use the official Mono image as the base for our Dockerfile. Below is an example:

# Use the official Mono image
FROM mono:6.12

# Set the working directory in the container
WORKDIR /app

# Copy the project files to the working directory
COPY . /app

# Set the user to a non-root user for security
USER 1001:1001

# Set the entry point to run the application
ENTRYPOINT ["mono", "/app/bin.exe"]

This straightforward configuration copies your application files into the container, sets up a working directory, and defines an entry point to execute your Mono application.


Writing a docker-compose.yml for a Mono Application

If you prefer using Docker Compose (as I do), here's an example configuration for a docker-compose.yml file:

services:
  app:
    container_name: app
    restart: always
    build:
      context: .
      dockerfile: Dockerfile
    user: 1001:1001
    volumes:
      - ./:/app
    # Optional health checks
    healthcheck:
      test: ["CMD", "bash", "-c", "! grep -iq 'error' /app/logs/error.log"]
      interval: 30s
      timeout: 10s
      retries: 3
    # Optional auto-healing
    labels:
      autoheal: 'true'

Here's what each section does:

  • Volumes: Binds the application directory to the container, enabling easy file sharing.
  • Health Check: Optionally monitors the application's logs for errors using a custom health check.
  • Auto-Healing: Adds the autoheal label to enable automatic container restarts in case of failure (requires an additional autoheal container or service).

Conclusion

Containerizing an old Mono application with Docker simplifies dependency management and ensures a consistent runtime environment. This approach is especially useful for legacy applications, though it can benefit any project.

Using Docker Compose can further enhance your workflow with features like health checks and auto-healing. With this setup, you can modernize your legacy Mono application's deployment process and focus on maintenance without worrying about managing dependencies manually on your VPS.