10 KiB
10 KiB
LA2 Eternal - Deployment Guide
Complete step-by-step guide for deploying the LA2 Eternal Lineage 2 server portal on a fresh Ubuntu server.
Prerequisites
- Ubuntu 22.04 LTS or newer (Ubuntu 24.04 LTS recommended)
- Root or sudo access
- Minimum 2GB RAM, 10GB disk space
- Internet connection
Step 1: Update System
sudo apt update && sudo apt upgrade -y
Step 2: Install Docker and Docker Compose
# Remove any old Docker versions
sudo apt remove -y docker docker-engine docker.io containerd runc
# Install prerequisites
sudo apt install -y ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set up Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Verify installation
sudo docker --version
sudo docker compose version
# Add your user to docker group (optional, to run docker without sudo)
sudo usermod -aG docker $USER
newgrp docker
Step 3: Clone Project Repository
# Create directory for the project
mkdir -p /opt/la2eternal
cd /opt/la2eternal
# Clone the repository (replace with your actual repository URL)
git clone <your-repository-url> .
# Or if you have the project files locally, copy them
cp -r /path/to/project/* /opt/la2eternal/
Step 4: Configure Environment Variables
# Copy the example environment file
cp .env .env.local
# Edit the environment file with your settings
nano .env.local
Required Environment Variables:
# Portal Auth
JWT_SECRET=your-super-secret-jwt-key-change-this
JWT_EXPIRES_IN=8h
# Portal Database (SQLite - embedded, no external service needed)
DATABASE_URL=file:./dev.db
# Game Server Database (MSSQL)
GAME_SERVER_HOST=your-game-server-ip
GAME_SERVER_PORT=1433
GAME_SERVER_USER=sa
GAME_SERVER_PASSWORD=your_game_server_password
GAME_SERVER_DATABASE=lin2db
# Game World Database (MSSQL)
GAME_WORLD_HOST=your-game-server-ip
GAME_WORLD_PORT=1433
GAME_WORLD_USER=sa
GAME_WORLD_PASSWORD=your_game_server_password
GAME_WORLD_DATABASE=lin2world
# Server Info
SERVER_ID=1
SERVER_NAME=LA2 Eternal
SERVER_IP=your-server-public-ip
SERVER_PORT=7777
# Frontend
CORS_ORIGIN=http://localhost:5173
API_PORT=3001
REACT_PORT=5173
NODE_ENV=production
VITE_API_URL=http://your-server-ip:3001
Important: Change all default passwords before deploying!
Step 5: Build and Start Services
# Build all Docker images
sudo docker compose build
# Start all services in detached mode
sudo docker compose up -d
# Check if all containers are running
sudo docker compose ps
You should see:
la2_portal_api- Node.js API server (with SQLite database)la2_portal_fe- React frontend
Step 6: Verify Deployment
# Check API health
curl http://localhost:3001/health
# Expected response:
# {"status":"ok","timestamp":"..."}
# View logs if needed
sudo docker compose logs -f api
sudo docker compose logs -f react
Step 7: Access the Website
Open your browser and navigate to:
- Frontend: http://your-server-ip:5173
- API: http://your-server-ip:3001
Step 8: Configure Firewall (Optional but Recommended)
# Install UFW if not already installed
sudo apt install -y ufw
# Allow SSH (don't lock yourself out!)
sudo ufw allow 22/tcp
# Allow HTTP
sudo ufw allow 80/tcp
sudo ufw allow 5173/tcp
# Allow API
sudo ufw allow 3001/tcp
# Enable firewall
sudo ufw enable
# Check status
sudo ufw status
Step 9: Setup Domain and SSL (Optional)
If you have a domain name and want to use HTTPS:
Install Nginx
sudo apt install -y nginx
Configure Nginx as Reverse Proxy
Create a new Nginx configuration:
sudo nano /etc/nginx/sites-available/la2eternal
Add the following configuration:
server {
listen 80;
server_name your-domain.com www.your-domain.com;
# Frontend
location / {
proxy_pass http://localhost:5173;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# API
location /api {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# Downloads
location /downloads {
alias /opt/la2eternal/public/downloads;
autoindex off;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/la2eternal /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Setup SSL with Let's Encrypt
# Install Certbot
sudo apt install -y certbot python3-certbot-nginx
# Obtain SSL certificate
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
# Test automatic renewal
sudo certbot renew --dry-run
Step 10: Production Optimizations
Enable Auto-Restart for Docker
sudo systemctl enable docker
Create Systemd Service (Optional)
Create a systemd service for auto-start on boot:
sudo nano /etc/systemd/system/la2eternal.service
Add:
[Unit]
Description=LA2 Eternal Portal
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/la2eternal
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target
Enable the service:
sudo systemctl daemon-reload
sudo systemctl enable la2eternal.service
sudo systemctl start la2eternal.service
Testing (Docker)
Smoke Test Script
A test/smoke-test.sh script is included to verify the Docker deployment works end-to-end.
Run the smoke test after starting Docker:
# Make sure containers are running first
sudo docker compose up -d
# Run the smoke test
chmod +x test/smoke-test.sh
./test/smoke-test.sh
What the smoke test verifies:
- API container is reachable on port 3001
- Frontend container is reachable on port 5173
- API
/auth/registeraccepts valid registration (alphanumeric username only) - API
/auth/loginreturns a JWT token - API
/auth/mereturns the authenticated user profile - API
/auth/game-accountreturns game account status for the authenticated user
Manual Docker Verification
# 1. Build and start all services
sudo docker compose build
sudo docker compose up -d
# 2. Wait for API to be ready
sleep 5
# 3. Verify API is up
curl -s http://localhost:3001/health || echo "API health check not configured — try registering a test user instead"
# 4. Test registration (username must be alphanumeric)
curl -s -X POST http://localhost:3001/api/auth/register \
-H "Content-Type: application/json" \
-d '{"username":"testuser123","email":"test@example.com","password":"testpass123"}'
# 5. Test login
curl -s -X POST http://localhost:3001/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"testpass123"}'
# 6. Verify frontend is serving
curl -s -o /dev/null -w "%{http_code}" http://localhost:5173
# Expected: 200
Running Tests in Docker (API)
# Access the API container shell
sudo docker exec -it la2_portal_api sh
# Inside the container, run type checks
npx tsc --noEmit
# Exit the container shell
exit
Running Tests in Docker (Frontend)
# Access the React container shell (if using dev image)
sudo docker exec -it la2_portal_fe sh
# Inside the container, run the build to verify no TypeScript errors
npm run build
# Exit the container shell
exit
Maintenance Commands
# View all running containers
sudo docker compose ps
# View logs
sudo docker compose logs -f
# Restart services
sudo docker compose restart
# Stop all services
sudo docker compose down
# Stop and remove all containers and volumes (WARNING: deletes database data)
sudo docker compose down -v
# Update and rebuild
sudo docker compose pull
sudo docker compose build
sudo docker compose up -d
# Backup SQLite database (from API container)
sudo docker exec la2_portal_api sh -c 'cp /app/dev.db /app/dev.db.backup.$(date +%Y%m%d)'
sudo docker cp la2_portal_api:/app/dev.db.backup.$(date +%Y%m%d) ./backup-$(date +%Y%m%d).db
# Restore SQLite database (to API container)
sudo docker cp ./backup-date.db la2_portal_api:/app/dev.db
sudo docker restart la2_portal_api
Troubleshooting
Container won't start
# Check logs
sudo docker compose logs [service-name]
# Check for port conflicts
sudo netstat -tulpn | grep 3001
sudo netstat -tulpn | grep 5173
# Restart specific service
sudo docker compose restart api
Database connection issues
# Check if SQLite database file exists
cd /home/user/Documents/LA2NodeJS/api && ls -la dev.db
# View API logs for database errors
sudo docker compose logs -f api
# Reset database (WARNING: deletes all data)
rm -f /home/user/Documents/LA2NodeJS/api/dev.db
# Restart API to recreate database with Prisma migrations
sudo docker compose restart api
Permission denied errors
# Fix Docker socket permissions
sudo chmod 666 /var/run/docker.sock
# Or add user to docker group
sudo usermod -aG docker $USER
newgrp docker
Out of disk space
# Clean up unused Docker images and containers
sudo docker system prune -a
# Check disk usage
sudo docker system df
Security Recommendations
- Change all default passwords in
.envfile - Use strong JWT_SECRET (at least 32 random characters)
- Enable UFW firewall and only open necessary ports
- Keep system updated with
sudo apt update && sudo apt upgrade - Use SSL/HTTPS for production deployments
- Regular backups of the database
- Monitor logs for suspicious activity
Support
For issues or questions:
- Check the logs:
sudo docker compose logs -f - Verify environment variables in
.envfile - Ensure game server database is accessible from the web server
- Check firewall rules if services are not accessible
License
This project is for private use only. All Lineage 2 assets and trademarks belong to NCSoft.