Posts Tagged ‘Maps’

Migrating Server environments to Docker Containers a brief step-by-step guide

Wednesday, November 12th, 2025

migrating-server--applications-environment-to-docker-containers

In modern IT environments, containerization has become an essential strategy for improving application portability, scalability, and consistency. Docker, as a containerization platform, allows you to package applications and their dependencies into isolated containers that can be easily deployed across different environments. Migrating an existing server environment into Docker containers is a common scenario, and this guide will walk you through the key steps of doing so.

Why Migrate to Docker?

Before we dive into the specifics, let’s briefly understand why you might want to migrate your server environment to Docker:

  • Portability: Containers encapsulate applications and all their dependencies, making them portable across any system running Docker.
  • Scalability: Containers are lightweight and can be scaled up or down easily, offering flexibility to handle varying loads.
  • Consistency: With Docker, you can ensure that your application behaves the same in development, testing, and production.
  • Isolation: Docker containers run in isolation from the host system, minimizing the risk of configuration conflicts.
     

Steps to Migrate a Server Environment into Docker

Migrating an environment of servers into Docker typically involves several steps: evaluating the current setup, containerizing applications, managing dependencies, and orchestrating deployment. Here’s a breakdown:

1. Evaluate the Existing Server Environment

Before migrating, it's essential to inventory the current server environment to understand the following:

  • The applications running on the servers
  • Dependencies (e.g., databases, third-party services, libraries, etc.)
  • Networking setup (e.g., exposed ports, communication between services)
  • Storage requirements (e.g., persistent data, volumes)
  • Security concerns (e.g., user permissions, firewalls)
     

For example, if you're running a web server with a backend database and some caching layers, you'll need to break down these services into their constituent parts so they can be containerized.

2. Containerize the Application

The next step is to convert the services running on your server into Docker containers. Docker containers require a Dockerfile, which is a blueprint for how to build and run the container. Let's walk through an example of containerizing a simple web application.

Example: Migrating a Simple Node.js Web Application

Assume you have a Node.js application running on your server. To containerize it, you need to:

  • Create a Dockerfile
  • Build the Docker image
  • Run the containerized application

2.1. Write a Dockerfile

A Dockerfile defines how your application will be built within a Docker container. Here’s an example for a Node.js application:

# Step 1: Use the official Node.js image as a base image FROM node:16

# Step 2: Set the working directory inside the container WORKDIR /usr/src/app # Step 3: Copy package.json and package-lock.json to the container COPY package*.json ./

# Step 4: Install dependencies inside the container RUN npm install

# Step 5: Copy the rest of the application code to the container COPY . .

# Step 6: Expose the port that the application will listen on EXPOSE 3000

# Step 7: Start the application CMD ["npm", "start"]

This Dockerfile:

  1. Uses the official node:16 image as a base.
  2. Sets the working directory inside the container to /usr/src/app.
  3. Copies the package.json and package-lock.json files to the container and runs npm install to install dependencies.
  4. Copies the rest of the application code into the container.
  5. Exposes port 3000 (assuming that’s the port your app runs on).
  6. Defines the command to start the application.

2.2: Build the Docker Image

Once the Dockerfile is ready, build the Docker image using the following command:

# docker build -t my-node-app .

This command tells Docker to build the image using the current directory (.) and tag it as my-node-app.

2.3: Run the Docker Container

After building the image, you can run the application as a Docker container:

# docker run -p 3000:3000 -d my-node-app

This command:

  • Maps port 3000 from the container to port 3000 on the host machine.
  • Runs the container in detached mode (-d).

3. Handling Dependencies and Services

If your server environment includes multiple services (e.g., a database, caching layer, or message queue), you'll need to containerize those as well. Docker Compose can help you define and run multi-container applications.

Example: Dockerizing a Node.js Application with MongoDB

To run both the Node.js application and a MongoDB database, you’ll need a docker-compose.yml file.

Create a docker-compose.yml file in your project directory:

    version: '3'

    services:
      web:
        build: .
        ports:
          – "3000:3000"
        depends_on:
          – db
      db:
        image: mongo:latest
        volumes:
          – db-data:/data/db
        networks:
          – app-network

    volumes:
      db-data:

    networks:
      app-network:
        driver: bridge

This docker-compose.yml file:

  1. Defines two services: web (the Node.js app) and db (the MongoDB container).
  2. The depends_on directive ensures the database service starts before the web application.
  3. Uses a named volume (db-data) for persistent data storage for MongoDB.
  4. Defines a custom network (app-network) for communication between the two containers.

3.1. Start Services with Docker Compose

To start the services defined in docker-compose.yml, use the following command:

# docker-compose up -d

This command will build the web service (Node.js app), pull the MongoDB image, create the necessary containers, and run them in the background.

4. Manage Data Persistence

Containers are ephemeral by design, meaning data stored inside a container is lost when it stops or is removed. To persist data across container restarts, you’ll need to use volumes.

In the example above, the MongoDB service uses a named volume (db-data) to persist the database data. Docker volumes allow you to:

  • Persist data on the host machine outside of the container.
  • Share data between containers.

To check if the volume is created and inspect its usage, use:

# docker volume ls # docker volume inspect db-data

5. Networking Between Containers

In Docker, containers communicate with each other over a network. By default, Docker Compose creates a network for each application defined in a docker-compose.yml file. Containers within the same network can communicate with each other using container names as hostnames.

For example, in the docker-compose.yml above:

  • The web container can access the db container using db:27017 as the database URL (MongoDB's default port).

6. Scaling and Orchestrating with Docker Swarm or Kubernetes

If you need to scale your application to multiple instances or require orchestration, Docker Swarm and Kubernetes are the two most popular container orchestration platforms.

Docker Swarm:

Built into Docker, Swarm allows you to easily manage a cluster of Docker nodes and scale your containers across multiple machines. To initialize a swarm:

# docker swarm init

Kubernetes:

Kubernetes is a powerful container orchestration tool that provides high availability, automatic scaling, and management of containerized applications. If you’re migrating a more complex server environment, Kubernetes will offer additional features like rolling updates, automatic recovery, and more sophisticated networking options.

7. Security and Permissions

When migrating to Docker, it's important to pay attention to security best practices, such as:

 

  • Running containers with the least privileges (using the USER directive in the Dockerfile).
  • Using multi-stage builds to keep the image size small and reduce the attack surface.
  • Regularly scanning Docker images for known vulnerabilities using tools like Anchore, Trivy, or Clair.
  • Configuring network isolation for sensitive services.

Conclusion

Migrating a server environment into Docker containers involves more than just running an application in isolation. It requires thoughtful planning around dependencies, data persistence, networking, scaling, and security. By containerizing services with Docker, you can create portable, scalable, and consistent environments that streamline both development and production workflows.

By following the steps outlined in this guide—writing Dockerfiles, using Docker Compose for multi-container applications, and ensuring data persistence—you can successfully migrate your existing server environment into a Dockerized architecture. For larger-scale environments, consider leveraging orchestration tools like Docker Swarm or Kubernetes to manage multiple containerized services across a cluster.

How to fix postfix mail server error ‘relay access denied’ on FreeBSD

Wednesday, January 30th, 2013

If you're running a newly configured Postfix SMTP server and you get in /var/log/maillog errors like:

Relay access denied

i.e. in log whenever you try to deliver a mail to the mail server you get something like:

Jan 29 10:05:04 600h postfix/smtpd[4624]: NOQUEUE: reject: RCPT from mxtb-pws3.mxtoolbox.com[64.20.227.133]: 554 5.7.1 <test@example.com>: Relay access denied; from=<supertool@mxtoolbox.com> to=<test@example.com> proto=ESMTP helo=<please-read-policy.mxtoolbox.com>

This is to because the virtualdomain to which postfix is trying to deliver is not added among the domains for which relaying is allowed.

To fix it edit /etc/postfix/main.cf ; find line

relay_domains = $mydestination

and add all domains, for which relaying should be allowed. Let's say you have virtual domains example.com and example1.com to enable relaying, add to conf:

relay_domains = $mydestination example.com example1.com

Also whether, virtual domain names are read from a separate configured hashed .db file like /etc/postfix/virtual.db

Usually done via /etc/postfix/main.cf via vars:

virtual_mailbox_maps = hash:/etc/postfix/virtual
virtual_alias_maps = hash:/etc/postfix/virtual

Its necessery to run cmd;

postmap virtual
# ls -al /etc/postfix/virtual*
-rwxrwxrwx  1 root  wheel      45 Jan 29 05:27 /etc/postfix/virtual
-rwxrwxrwx  1 root  wheel  131072 Jan 29 10:58 /etc/postfix/virtual.db

This command re-builds virtual.db including all newly input domains in /etc/postfix/virtual

Finally to load new configs its necessary to restart postfix;

This particular Postfix is running on FreeBSD so to restart it;

# /etc/rc.d/postfix restart
....

 

 

How to fix php “Fatal error: Class ‘SimpleXMLElement’ not found” and “Fatal error: Class ‘JLoader’ not found” on FreeBSD

Tuesday, June 21st, 2011

One of the contact forms running on a FreeBSD server configured to work on top of Apache+MySQL suddenly stopped working.

The errors that appeared on the webpage during a page request to the form url was:

Fatal error: Class 'SimpleXMLElement' not found in /var/www/joomla/plugins/system/plugin_googlemap2_helper.php on line 2176 Fatal error: Class 'JLoader' not found in /var/www/joomla/plugins/libraries/loader.php on line 161

As you see in the output the website which was causing the issues was running a Joomla version 1.5.23 Stable configured with RSForm!ver 1.5.x (as a contact form solution) and Google Maps version 2.13b plugins.

The Google Map from Google Maps plugin and the RSform were configured to appear on one physical configured article in Joomla and seemed to work just until now. However yesterday suddenly the error messages:
Fatal error: Class ‘SimpleXMLElement’ not found
Fatal error: Class ‘JLoader’ not found

came out of nothing, it’s really strange as I don’t remember doing any changes to either Joomla or the PHP installation on this server.
There is one more guy who has access to the Joomla installation which I suspect might have changed something in the Joomla, but this scenario is not very likely.

Anyways as the problem was there I had to fix it up. Obviously as the error message Fatal error: Class ‘SimpleXMLElement’ not found reported the server php simplexml was missing!

Just to assure myself the php simplexml extension is not present on the server I used the classical method of setting up a php file with phpinfo(); in it to check all the installed php extensions on the server.

Finally to solve the issue I had to install the module from ports php5-simplexml , e.g.:

freebsd# cd /usr/ports/textproc/php5-simplexml
freebsd# make install clean

Afterwards to make the new settings take place I did restart of my Apache server:

freebsd# /usr/local/etc/rc.d/apache2 restart
Syntax OK
Stopping apache2.
Waiting for PIDS: 63883.
Performing sanity check on apache2 configuration:
Syntax OK
Starting apache2.

Now my Joomla contact form is back to normal 😉

If someone has any idea why this error occured without any php or server modifications, and how comes that all worked fine beforehand even though I did not have the simplexml module instlaled on the server o_O, I would be enormously greatful.