[LINUX] The story of remounting the application server

We responded to a request to replace the application server about 10 years ago with a new server without stopping the service, so we will briefly introduce the migration procedure. image.png

Specifications / requirements

Move the Web application running on the old server to the new server. The specifications of both old and new servers are as follows.

Type Old server New server
Cloud Sakura's VPS Azure VM
OS CentOS 5.11 CentOS 7.4
WWW server httpd 2.2.3 httpd 2.4.6
AP server Tomcat 5.5.26 Tomcat 5.5.26
connector mod_jk mod_proxy_ajp
runtime jdk 1.5.0_22 jdk 1.8.0_162
DBMS PostgreSQL 8.1.23 PostgreSQL 9.2.23

――It is a BtoB Web service, which is used by dozens of companies, albeit on a small scale, 24 hours a day, 365 days a year. --I want to add a new framework called ** PHP / Laravel ** to the new server and share the database with ** JavaServlet / JSP **, so I will update the middleware as much as possible.

Build a new server

Deploy ** CentOS-based 7.4 ** from "Create Resource" in the Azure portal. image.png Log in to the VM and add the required modules.

Installing Oracle Java 8 (JDK 1.8)

I didn't use OpenJDK because it is not officially supported by Tomcat.

# rpm -ivh jdk-8u162-linux-x64.rpm

# java -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

WWW server (Apache) installation

yum -y install httpd
yum -y install mod_ssl

httpd -v
Server version: Apache/2.4.6 (CentOS)

Link with Tomcat.


<Location /foo/>
    ProxyPass ajp://

Make holes in the ports you need for business.

firewall-cmd --list-all
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

After entering the server certificate, it may be a good idea to go to https://www.ssllabs.com/ssltest/ for an SSL vulnerability diagnosis and correct the indication.

Install tomcat

When 5.5.36, which is the latest 5.5 series, was adopted, the HttpServletRequest # getAttribute method threw a NullPointerException on some screens, so the conventional 5.5.26 was maintained. The source code is not disclosed, or the developer is out of business, so decompile and fix it with the IntelliJ IDEA plugin. I don't do it because the risk is high.

cd /usr/local
wget https://archive.apache.org/dist/tomcat/tomcat-5/v5.5.26/bin/apache-tomcat-5.5.26.tar.gz
tar zxvf apache-tomcat-5.5.26.tar.gz

ln -s apache-tomcat-5.5.26 tomcat5

Create a context descriptor.


<?xml version="1.0" encoding="utf-8"?>
<Context path="/foo" reloadable="true" docBase="/var/app/webapps/foo"></Context>

Set port 8009 for Tomcat to communicate with mod_proxy_ajp.


<Connector port="8009"
    maxThreads="150" minSpareThreads="25" maxSpareThreads="100"
    acceptCount="100" connectionTimeout="0"

Comment out <Connector port =" 8080 "... /> to disable it. Since the Servlet was copied from the old server to / var / app / webapps, change the appBase of <Host name =" localhost "... /> to " / var / app / webapps ".

Register tomcat to service


Description=Apache Tomcat 5 Servlet Container
After=syslog.target network.target



JDBC driver update

The JDBC under webapps is still old, so replace it with a JDBC that supports PostgreSQL 9.2.

cd /var/app/webapps/foo/WEB-INF/lib
wget https://jdbc.postgresql.org/download/postgresql-42.2.2.jar

PHP7 installation

The new server requires PHP to provide services with PHP / Laravel in addition to JavaServlet / JSP.

rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum -y install --enablerepo=remi-php72 php php-mbstring php-pear php-fpm php-pecl-mcrypt php-pecl-zip php-xml php-gd php-pdo php-mysqlnd php-pgsql

Let's add Composer as well. (Not used on the production server, but just in case)

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

DB server installation

# yum -y install postgresql-server
# postgresql-setup initdb

# psql --version
psql (PostgreSQL) 9.2.23

Database migration

Get a dump on the old server and copy it to the new server.

Old server

su - postgres
pg_dump foo > /tmp/foo.txt

scp /tmp/foo.txt [email protected]:/tmp

Restore on the new server.

su - postgres
createdb foo
psql foo < /tmp/foo.txt

Add implicit cast

Since version 8.3, PostgreSQL has stricter type conversion checks and no implicit type conversions. https://qiita.com/seiketkm/items/9d069348c2906a6ae011 https://qiita.com/6in/items/f23ead1314b9e6d2f2b7 Add an implicit cast by referring to articles such as.

cat << 'EOF' > /tmp/cast.sql
CREATE CAST (character varying AS numeric) WITH INOUT AS IMPLICIT;
CREATE CAST (timestamp without time zone AS text) WITH INOUT AS IMPLICIT;
CREATE CAST (timestamp without time zone AS character varying) WITH INOUT AS IMPLICIT;
CREATE CAST (character varying AS timestamp without time zone) WITH INOUT AS IMPLICIT;
CREATE CAST (timestamp with time zone AS text) WITH INOUT AS IMPLICIT;
CREATE FUNCTION textint4cat(text, int4) RETURNS text AS 'SELECT $1 || $2::pg_catalog.text' LANGUAGE sql IMMUTABLE STRICT;
CREATE OPERATOR || (PROCEDURE = textint4cat,LEFTARG = text, RIGHTARG = int4);

psql foo < /tmp/cast.sql

Check the list of casts.

psql foo

Operation check

At this point, check the operation of the Web application once.


It is decided at midnight when the number of service users is overwhelmingly small. The following are all old server operations.

Access log monitoring

Start another terminal and monitor the access log.

tail -f /var/log/httpd/old.example.com.access.log

Database copy

If there is no access, restore the dump of the old server on the new server. If there is access in the meantime, try again!

Redirect settings

301 redirect (permanent transfer) leaves the redirect cache in the browser and cannot be returned, so use 302 redirect (temporary transfer).


Redirect temp /foo/ https://new.example.com/foo/

After confirming that there is no access again, restart httpd. Check if the request has been forwarded to the new server.

Change the database name of the old server

Make sure that even if you can access the old server by some mistake, it will be reported as an error.

su - postgres
alter database "foo" rename to "foo_BK";

DNS switching

When operating on a virtual host, it will not be displayed correctly unless you access it with the domain at the time of publication. To test with the new domain before rewriting the DNS, edit the client's hosts file. For Windows, the location of the hosts file is below.


Start a text editor such as Notepad with administrator privileges, and add it with the "new IP address (space) old domain".

If the test is successful, edit the DNS server zone file. Change the global IP address defined in the domain of the old server to the global IP address of the new server, and close the old server when DNS is propagated.


$TTL 3600
$ORIGIN example.com.
@       IN      SOA     xxx.example.com. (
        2019070101      ; Serial
        43200           ; Refresh after 12 hours
        3600            ; Retry after one hour
        2419200         ; Expire after 4 weeks
        1200    )       ; Negative cache TTL of 20 minutes
; Authoritative name servers
        IN      NS      ns01.example.com.
; Host
old     3600     IN      A       nnn.nnn.nnn.nnn  ;Change to the IP address of the new server

Recommended Posts

The story of remounting the application server
The story of sys.path.append ()
The story of building Zabbix 4.4
[Apache] The story of prefork
The story of launching a Minecraft server from Discord
The story of Python and the story of NaN
The story of participating in AtCoder
The story of writing a program
The story of the release work of the application that Google does not tell
The story of trying to reconnect the client
I tried the asynchronous server of Django 3.0
The story of an error in PyOCR
The story of verifying the open data of COVID-19
The story of adding MeCab to ubuntu 16.04
The story of making Python an exe
The story of making an immutable mold
The story of manipulating python global variables
The story of trying deep3d and losing
The story of deciphering Keras' LSTM model.predict
Let's summarize the construction of NFS server
The story of blackjack A processing (python)
The story of pep8 changing to pycodestyle
Change the destination batfish server of pybatfish
The story of developing a web application that automatically generates catchphrases [MeCab]
The story of doing deep learning with TPU
Kill the frozen Rails local application server (Puma)
The story of low learning costs for Python
The story of making the Mel Icon Generator version2
Regularly monitor the HTTP response of the web server
Image processing? The story of starting Python for
The story of making a lie news generator
The story of misreading the swap line of the top command
The story of reading HSPICE data in Python
The story of trying Sourcetrail × macOS × VS Code
The story of viewing media files in Django
The story of making a mel icon generator
[Small story] Download the image of Ghibli immediately
The story of moving from Pipenv to Poetry
The story of making a web application that records extensive reading with Django
The beginning of cif2cell
The story of Python without increment and decrement operators.
The story of stopping the production service with the hostname command
The story of replacing Nvidia GTX 1650 with Linux Mint 20.1.
The story of Hash Sum mismatch caused by gcrypto20
The meaning of self
The story of sharing the pyenv environment with multiple users
the zen of Python
The story of making a music generation neural network
The story of FileNotFound in Python open () mode ='w'
Visualization of the connection between malware and the callback server
A story about changing the master name of BlueZ
Find a guideline for the number of processes / threads to set in the application server
The story that the return value of tape.gradient () was None
A story that analyzed the delivery of Nico Nama.
AttributeError: The story of solving module'tensorflow' has no attribute'log'.
The story of automatic language conversion of TypeScript / JavaScript / Python
Application of Python 3 vars
The story of wanting to buy Ring Fit Adventure
The story of using circleci to build manylinux wheels
Revenge of the Types: Revenge of types
The story of creating a VIP channel for in-house chatwork