Skip to main content

System — Admin Guide

Comprehensive administration guide for the System (Techpartners) system, covering server infrastructure, database, back-end, front-end, mobile application, and deployment workflows.


Table of Contents


1. Initial Server Setup

1.1 JBoss Application Server

TaskDuration
ZIP file upload~1 min 11 sec
ZIP extraction~4.258 sec

1.2 Java 17 SDK

TaskDuration
ZIP file upload~30 sec
ZIP extraction~2.425 sec
Installation~0.194 sec

1.3 NGINX

Install NGINX from the official repository on CentOS 9:

# Download the RPM package
wget https://nginx.org/packages/centos/9/x86_64/RPMS/nginx-1.24.0-1.el9.ngx.x86_64.rpm

# Install the package
# 0 2 4 6 8 even-numbered versions is Stable
sudo rpm -ivh nginx-1.24.0-1.el9.ngx.x86_64.rpm

# Start and enable NGINX
sudo systemctl start nginx
sudo systemctl enable nginx

Open port 7007 through SELinux:

sudo semanage port -a -t http_port_t -p tcp 7007
TaskDuration
Download~2.850 sec
Installation~1.021 sec

2. Database (Oracle)

2.1 Initial Setup

Download: Oracle 19c

TaskDuration
Backup~3 min 51 sec
Upload~3 min 9 sec
Restore~4 min 23 sec

Connection & Environment

-- Set the Oracle SID
SET ORACLE_SID=ORCL

-- Connect as SYSDBA (various methods)
sqlplus / AS SYSDBA;
sqlplus SQL/ORACLE AS SYSDBA;
sqlplus SYS/MYPASSWORD@XE AS SYSDBA;

Pluggable Database (PDB)

-- Show all PDBs
SHOW PDBS

-- Switch to a PDB
ALTER SESSION SET CONTAINER = ORCLPDB;

-- Grant tablespace to a user
GRANT UNLIMITED TABLESPACE TO USER_NAME;

Connection Strings

EnvironmentConnection String
DefaultUSER_NAME/PASSWORD@LOCALHOST:1521/ORCL
PDBUSER_NAME/PASSWORD@LOCALHOST:1521/ORCLPDB
SYSDBA (PDB)sqlplus USER_NAME/PASSWORD@LOCALHOST:1521/ORCLPDB as sysdba

Useful Queries

-- List active sessions
SELECT USERNAME FROM V$SESSION;

-- Connect as SYSDBA
CONNECT username/password AS SYSDBA;

-- Open the database
ALTER DATABASE OPEN;

-- Show current memory parameter values
SHOW PARAMETER TARGET;

2.2 Memory Configuration

Adjust memory parameters for performance (requires restart):

ALTER SYSTEM SET pga_aggregate_target = 3G SCOPE=SPFILE;
ALTER SYSTEM SET sga_target = 7G SCOPE=SPFILE;
ALTER SYSTEM SET memory_max_target = 10G SCOPE=SPFILE;

-- Apply changes
SHUTDOWN IMMEDIATE;
STARTUP;

2.3 Server Environments

EnvironmentServer
Productionoracle@<prod_server_ip>
Testdev_oracle@<test_server_ip>

2.4 Common Commands

Start the Listener:

lsnrctl start

Start the Pluggable Database:

sqlplus / AS SYSDBA;
STARTUP;
ALTER DATABASE OPEN;

Shutdown:

SHUTDOWN IMMEDIATE;

Disable Windows Firewall (if applicable):

NETSH FIREWALL SET OPMODE MODE=DISABLE

2.5 Database Backup System

The backup system is built in Go (latest stable version) and consists of four services managed by systemd.

Service Status

sudo systemctl status ora-backup
sudo systemctl status ora-upload
sudo systemctl status ora-notif
sudo systemctl status ora-main
sudo systemctl status ora-timer.timer

File Locations

ComponentPath
Source code/home/admin/backup
Systemd configs/etc/systemd/system
Compiled binaries/usr/local/bin

Build Commands

go build -o /usr/local/bin/ora-backup backup/backup.go
go build -o /usr/local/bin/ora-upload upload/upload.go
go build -o /usr/local/bin/ora-notif notif/notif.go
go build -o /usr/local/bin/ora-main main.go

2.6 PostgreSQL Setup

Installation (CentOS / RHEL 9)

# Install the PostgreSQL 18 repository
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# Disable the built-in PostgreSQL module
sudo dnf -qy module disable postgresql

# Install PostgreSQL 18 server
sudo dnf install -y postgresql18-server postgresql18

# Initialize the database cluster
sudo /usr/pgsql-18/bin/postgresql-18-setup initdb

# Start and enable the service
sudo systemctl start postgresql-18
sudo systemctl enable postgresql-18

Authentication Configuration

Edit pg_hba.conf to allow password-based connections:

sudo nano /var/lib/pgsql/18/data/pg_hba.conf

Update the following lines (change peer / ident to md5 or scram-sha-256):

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local all all md5
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
host all all 0.0.0.0/0 md5

Listen Address & Port

Edit postgresql.conf to accept remote connections:

sudo nano /var/lib/pgsql/18/data/postgresql.conf
listen_addresses = '*'
port = 5432

Apply the changes:

sudo systemctl restart postgresql-18

Firewall

sudo firewall-cmd --permanent --add-port=5432/tcp
sudo firewall-cmd --reload

Create Users & Databases

# Switch to the postgres OS user
sudo -u postgres psql
-- Create an application user (replace with your actual values)
CREATE USER db_admin WITH PASSWORD 'S3cur3P@ss!';

-- Create the production database
CREATE DATABASE app_production OWNER db_admin ENCODING 'UTF8';

-- Create the test database
CREATE DATABASE app_staging OWNER db_admin ENCODING 'UTF8';

-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE app_production TO db_admin;
GRANT ALL PRIVILEGES ON DATABASE app_staging TO db_admin;

-- Verify
\l

Server Environments

EnvironmentServerPortDatabaseUser
Productionpostgres@<prod_server_ip>5432app_productiondb_admin
Testpostgres@<test_server_ip>5432app_stagingdb_admin

Connection Strings

# Production
psql -h <prod_server_ip> -p 5432 -U db_admin -d app_production

# Test
psql -h <test_server_ip> -p 5432 -U db_admin -d app_staging

# JDBC (for JBoss / Spring)
# jdbc:postgresql://<prod_server_ip>:5432/app_production
# jdbc:postgresql://<test_server_ip>:5432/app_staging

Memory & Performance Tuning

Edit postgresql.conf:

# Memory (adjust based on available RAM)
shared_buffers = 2GB
effective_cache_size = 6GB
work_mem = 64MB
maintenance_work_mem = 512MB

# WAL
wal_buffers = 64MB
max_wal_size = 2GB
min_wal_size = 512MB

# Connections
max_connections = 200
sudo systemctl restart postgresql-18

Common Commands

# Service management
sudo systemctl start postgresql-18
sudo systemctl stop postgresql-18
sudo systemctl restart postgresql-18
sudo systemctl status postgresql-18

# Connect as postgres superuser
sudo -u postgres psql

# List databases
sudo -u postgres psql -c "\l"

# List users/roles
sudo -u postgres psql -c "\du"

# Check active connections
sudo -u postgres psql -c "SELECT pid, usename, datname, state FROM pg_stat_activity;"

Backup & Restore

Single database backup:

# Backup (custom format — recommended)
pg_dump -h <prod_server_ip> -U db_admin -Fc app_production > app_production_$(date +%Y%m%d).dump

# Backup (plain SQL)
pg_dump -h <prod_server_ip> -U db_admin app_production > app_production_$(date +%Y%m%d).sql

Full cluster backup (all databases):

sudo -u postgres pg_dumpall > full_backup_$(date +%Y%m%d).sql

Restore:

# Restore from custom format
pg_restore -h <prod_server_ip> -U db_admin -d app_production app_production_20260630.dump

# Restore from plain SQL
psql -h <prod_server_ip> -U db_admin -d app_production < app_production_20260630.sql

# Restore full cluster
sudo -u postgres psql < full_backup_20260630.sql

3. Back-End

3.1 Java (JBoss)

Server Environments

EnvironmentServerJBoss Path
Productionroot@<prod_server_ip>/home/admin/System/jboss-eap-7.4
Testroot@<test_server_ip>/home/admin/System/jboss-eap-7.4

Process Management

Check if JBoss is running:

ps ax | grep jboss

Production — Restart JBoss:

# Kill existing process
pkill -9 -f /home/admin/System/jboss-eap-7.4

# Start JBoss
cd /home/admin/System/jboss-eap-7.4/bin
nohup ./standalone.sh &

Test — Restart JBoss:

# Kill existing process
pkill -9 -f /home/admin/System/jboss-eap-7.4

# Start JBoss
cd /home/admin/System/jboss-eap-7.4/bin
nohup ./standalone.sh &

3.2 Go (Docker)

Server Environments

EnvironmentServerPortContainer Name
Productionroot@<prod_server_ip>8080go-api-prod
Testroot@<test_server_ip>8081go-api-test

Docker Installation (CentOS / RHEL 9)

# Install Docker
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Start and enable Docker
sudo systemctl start docker
sudo systemctl enable docker

# (Optional) Add user to docker group
sudo usermod -aG docker $USER

Dockerfile

# Build stage
FROM golang:latest AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

# Production stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /root/
COPY --from=builder /app/main .
COPY --from=builder /app/.env .
EXPOSE 8080
CMD ["./main"]

Build & Deploy

# Build the Docker image
docker build -t go-api:latest .

# Production — Run container
docker run -d \
--name go-api-prod \
--restart unless-stopped \
-p 8080:8080 \
--env-file .env.production \
go-api:latest

# Test — Run container
docker run -d \
--name go-api-test \
--restart unless-stopped \
-p 8081:8080 \
--env-file .env.test \
go-api:latest

Container Management

# Check running containers
docker ps

# View logs
docker logs -f go-api-prod
docker logs -f go-api-test

# Restart a container
docker restart go-api-prod
docker restart go-api-test

# Stop and remove a container
docker stop go-api-prod && docker rm go-api-prod
docker stop go-api-test && docker rm go-api-test

# Rebuild and redeploy (Production)
docker stop go-api-prod && docker rm go-api-prod
docker build -t go-api:latest .
docker run -d \
--name go-api-prod \
--restart unless-stopped \
-p 8080:8080 \
--env-file .env.production \
go-api:latest

Docker Compose (Optional)

# docker-compose.yml
version: '3.8'
services:
go-api:
build: .
container_name: go-api-prod
restart: unless-stopped
ports:
- "8080:8080"
env_file:
- .env.production
volumes:
- ./logs:/root/logs
# Start with Docker Compose
docker compose up -d

# Rebuild and restart
docker compose up -d --build

# View logs
docker compose logs -f

# Stop
docker compose down

4. Front-End

4.1 Initial Setup

Required: Node.js v18.19.1

# List installed Node versions
nvm list

# Switch to the required version
nvm use

# Install project dependencies
npm install

4.2 Server Environments

EnvironmentServerWeb Root
Production<prod_server_ip>/etc/nginx/web
Test<test_server_ip>/etc/nginx/web

4.3 Build & Deploy

  1. Run the build command in the terminal:

    npm run build
  2. A dist folder will be generated.

  3. Copy the dist folder contents to the corresponding web root directory on the server.

4.4 CI / CD (GitLab Runner)

Install GitLab Runner

# Add the repository
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash

# Install
sudo dnf -y install gitlab-runner

# Enable and start
sudo systemctl enable --now gitlab-runner

# Verify status
sudo systemctl status gitlab-runner --no-pager

Register the Runner

gitlab-runner register \
--url https://git.techpartners.asia/ \
--token <your_tolen>

Run & Permissions

gitlab-runner run

# Grant the runner user ownership of the deployment directory
sudo chown -R gitlab-runner:gitlab-runner /etc/nginx/bzuv

4.5 Production Server (Next.js)

Start the Server

cd /home/ubuntu/project
PORT=3000 node server.js

# Or use PM2 for process management
pm2 start server.js --name next-standalone

Production Build & Deploy

cd /home/ubuntu

# Clean old build
rm -rf landing-intro/*
rm -rf landing-intro/.next

# Deploy new build
unzip deploy.zip -d landing-intro/
rm deploy.zip

# Restart the PM2 process
pm2 restart 0

5. Mobile App (Flutter)

5.1 Flutter Installation (macOS)

Install Rosetta 2 (Apple Silicon)

sudo softwareupdate --install-rosetta --agree-to-license

Download & Extract Flutter

Download the latest stable Flutter SDK from flutter.dev and extract it:

unzip ~/Downloads/flutter_macos_arm64_3.24.3-stable.zip \
-d ~/development/

Add Flutter to PATH

# Open the shell config
sudo nano ~/.zshrc

# Add the following line, then save (Ctrl+X → Y → Enter)
export PATH=$HOME/development/flutter/bin:$PATH

# Reload the config
source ~/.zshrc

5.2 Android Studio Setup

  1. Download and install the latest version of Android Studio.
  2. Go to Settings → Plugins → Search for and install both Dart and Flutter plugins → Restart the IDE.
  3. Open your Flutter project via File → Open.
  4. Go to Settings → Languages & Frameworks → Flutter → Set the Flutter SDK path to your Flutter installation directory (e.g., ~/development/flutter) → Click OK.
  5. Verify that Settings → Languages & Frameworks → Dart → Dart SDK path is automatically populated.

Flutter Run Configuration

  1. In the toolbar, click + (Add Configuration).
  2. Select Flutter.
  3. Configure the entry point and device, then click OK.

5.3 Xcode & iOS Setup

Install Xcode

  1. Open the App Store, search for Xcode, and install it.

  2. Run first-launch setup:

    sudo sh -c 'xcode-select -s /Applications/Xcode.app/Contents/Developer && xcodebuild -runFirstLaunch'
    sudo xcodebuild -license
    xcodebuild -downloadPlatform iOS
  3. Open the iOS Simulator:

    open -a Simulator

Set Up a Physical iOS Device

  1. Connect your iOS device to the Mac via USB.
  2. When the "Trust this computer?" dialog appears on the device, tap Trust.

Enable Developer Mode (iOS 16+)

On the iOS device, go to:

Settings → Privacy & Security → Developer Mode → Toggle On → Tap Restart

After restart, unlock the device to confirm.

Enable Developer Code Signing

  1. In Android Studio, open the terminal and run:

    cd ios && open Runner.xcworkspace
  2. In Xcode, go to Xcode → Settings… → Accounts.

  3. Click +, select Apple ID, and sign in.

  4. Close the Settings dialog.

  5. In the Runner project settings, click Signing & Capabilities.

  6. Select All at the top.

  7. Check Automatically manage signing.

  8. Choose your Team from the dropdown.

5.4 CocoaPods

# Install CocoaPods
sudo gem install cocoapods

# Add gem binaries to PATH
sudo nano ~/.zshrc
# Add the following line:
export PATH=$HOME/.gem/bin:$PATH
# Save: Ctrl+X → Y → Enter

source ~/.zshrc

5.5 Build Commands

Production Builds

PlatformCommand
Android App Bundleflutter build appbundle --release
Android APKflutter build apk --release
iOSflutter build ios --release then flutter build ipa --release

Test Builds

PlatformCommand
Android App Bundleflutter build appbundle
Android APKflutter build apk
iOSflutter build ios --release then flutter build ipa

5.6 Publishing & Distribution

Android — Google Play (Production)

  1. Go to Google Play Console.
  2. Select the app → ProductionCreate new release.
  3. In the App bundles section, upload the .appbundle file.
  4. Scroll down and fill in the Release notes.
  5. Click Save as draftNext → Review → Send for review.

Android — Firebase App Distribution (Testing)

  1. Go to Firebase Console.
  2. Select the app → App Distribution.
  3. Upload the .apk file.
  4. Under Testers & Groups, click Add group to create a tester group.
  5. Add tester email addresses and send invitations.
  6. Testers will receive the invite via email, install the Firebase App Distribution app, and download the test build.
  7. On the uploaded release, click Add testers or groups and select the appropriate group.

iOS — TestFlight (Testing)

  1. Build the IPA and open it with Transporter:

    open build/ios/ipa/Applicatoin.ipa
  2. Use the Transporter app to upload the .ipa file to App Store Connect.

  3. Go to App Store Connect → Select the app → TestFlight.

  4. Under Testers, create a new group or select an existing one.

  5. Add testers by their Apple ID and send invitations.

  6. Testers install the TestFlight app from the App Store, accept the invite, and download the test build.

  7. On the uploaded build in TestFlight, add release notes and assign tester groups.

iOS — App Store (Production)

  1. Upload the .ipa file using Transporter to App Store Connect.
  2. In App Store Connect, go to the app's page and create a new version by entering the version number.
  3. Fill in the release notes describing the changes.
  4. In the Build section, select the uploaded build.
  5. Click SaveAdd for ReviewSubmit to App Review.

6. 3rd Party Integrations

6.1 ХУР / XYP (KhUR) Integration

Connection Check

Verify that the ХУР (KhUR) service is reachable:

http://<prod_server_ip>:8008/xyp/citizen-1.3.0/ws?WSDL

Establish VPN Connection

# Server: root@<prod_server_ip>
openvpn --config /home/admin/vpn/company_name.ovpn &

Note: The password.txt file contains the login credentials. The VPN connects automatically without any additional interaction.

Ticket Token

Token: ad93************************49d6

Tip — Local Time Offset Issue: If ХУР is not working in the local environment due to a time difference, uncomment the "minute-adding" section in the getCurrentTimestamp() function inside the HurService bean.

JKS Certificate Generation

  1. Generate a PKCS12 keystore from the certificate and private key:

    openssl pkcs12 -export \
    -in your_xyp.crt \
    -inkey your_xyp.key \
    -name "xyp" \
    -out your_xyp-pass.p12

    When prompted, enter the export password (e.g., hurdan).

  2. Convert PKCS12 to JKS:

    keytool -importkeystore \
    -deststorepass "hurdan" \
    -destkeystore your_xyp.jks \
    -srckeystore your_xyp-pass.p12 \
    -srcstoretype PKCS12
  3. (Optional) Convert JKS to PKCS12 format — use only if you need to change a default password:

    keytool -importkeystore \
    -srckeystore your_xyp.jks \
    -destkeystore your_xyp.jks \
    -deststoretype pkcs12
  4. Change the JKS keystore password:

    keytool -storepasswd -keystore your_xyp.jks

6.2 ЗМС / ZMS Integration

When using the ZMS API, user passwords must be encrypted. Use the following tool to generate the encrypted hash:

🔗 https://zms.sainscore.mn/convert-hash-map


Document maintained by the System admin team.