Files
grabowski eac11c3a24 Add Proxmox LXC deployment guide
Covers NixOS LXC (recommended, uses the flake module) and Debian/Ubuntu
LXC (traditional setup). Includes PostgreSQL setup, systemd service,
nginx reverse proxy, backup strategies, and update instructions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 13:30:52 +07:00

6.2 KiB

Deploying buildfor_life_repair on Proxmox LXC

This guide covers deploying the app in a lightweight LXC container on Proxmox VE.

NixOS is ideal for LXC — declarative config, small footprint, reproducible builds.

1. Create the LXC container

Download the NixOS LXC template (or build one):

# On Proxmox host
pveam update
pveam download local nixos-24.11-default_20241101_amd64.tar.xz

# Create container (adjust ID, storage, resources)
pct create 200 local:vztmpl/nixos-24.11-default_20241101_amd64.tar.xz \
  --hostname bflr \
  --memory 1024 \
  --swap 512 \
  --cores 2 \
  --storage local-lvm \
  --rootfs local-lvm:8 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --unprivileged 1 \
  --features nesting=1

pct start 200

If no NixOS template is available, use the nixos-infect script on a Debian LXC, or build a NixOS LXC image with:

nix build github:nix-community/nixos-generators#lxc

2. Configure NixOS

SSH into the container and edit /etc/nixos/configuration.nix:

{ config, pkgs, ... }:

let
  bflr = builtins.getFlake "git+https://git.b4l.co.th/B4L/buildfor_life_repair.git";
in
{
  imports = [
    bflr.nixosModules.default
  ];

  # PostgreSQL
  services.postgresql = {
    enable = true;
    ensureDatabases = [ "buildfor_life_repair" ];
    ensureUsers = [{
      name = "bflr";
      ensureDBOwnership = true;
    }];
    authentication = ''
      local buildfor_life_repair bflr trust
    '';
  };

  # The app
  services.buildfor-life-repair = {
    enable = true;
    port = 3000;
    databaseUrl = "postgresql://bflr@localhost/buildfor_life_repair";
    baseUrl = "http://bflr.local:3000"; # or your domain
    openFirewall = true;
  };

  # Optional: nginx reverse proxy with SSL
  # services.nginx = {
  #   enable = true;
  #   virtualHosts."repair.example.com" = {
  #     forceSSL = true;
  #     enableACME = true;
  #     locations."/".proxyPass = "http://127.0.0.1:3000";
  #   };
  # };

  networking.firewall.allowedTCPPorts = [ 3000 ];

  system.stateVersion = "24.11";
}

3. Build and switch

nixos-rebuild switch

4. Create the first user

# Enter the app directory
cd /var/lib/buildfor-life-repair

# Run the create-user script
nix run git+https://git.b4l.co.th/B4L/buildfor_life_repair.git -- \
  npx tsx scripts/create-user.ts admin@b4l.co.th yourpassword "Admin"

Or connect to the database directly:

sudo -u postgres psql buildfor_life_repair

Option B: Debian/Ubuntu LXC

If you prefer a traditional setup.

1. Create the LXC container

# On Proxmox host
pct create 200 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst \
  --hostname bflr \
  --memory 1024 \
  --swap 512 \
  --cores 2 \
  --storage local-lvm \
  --rootfs local-lvm:8 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --unprivileged 1 \
  --features nesting=1

pct start 200
pct enter 200

2. Install dependencies

apt update && apt upgrade -y
apt install -y curl git postgresql

# Install Node.js 22
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install -y nodejs

# Install build tools for native modules (sharp)
apt install -y build-essential python3 libvips-dev

3. Set up PostgreSQL

sudo -u postgres psql <<EOF
CREATE USER bflr WITH PASSWORD 'your-secure-password';
CREATE DATABASE buildfor_life_repair OWNER bflr;
GRANT ALL PRIVILEGES ON DATABASE buildfor_life_repair TO bflr;
\c buildfor_life_repair
GRANT ALL ON SCHEMA public TO bflr;
EOF

4. Clone and build

# Create app user
useradd -m -s /bin/bash bflr
su - bflr

git clone https://git.b4l.co.th/B4L/buildfor_life_repair.git
cd buildfor_life_repair

npm install
npm run build

# Create .env
cat > .env <<EOF
DATABASE_URL=postgresql://bflr:your-secure-password@localhost:5432/buildfor_life_repair
UPLOAD_DIR=/home/bflr/buildfor_life_repair/static/uploads
BASE_URL=http://your-ip:3000
EOF

# Push schema
npm run db:push

# Create first user
npm run create-user -- admin@b4l.co.th yourpassword "Admin"

5. Create systemd service

# As root
cat > /etc/systemd/system/bflr.service <<EOF
[Unit]
Description=buildfor_life_repair
After=network.target postgresql.service

[Service]
Type=simple
User=bflr
WorkingDirectory=/home/bflr/buildfor_life_repair
EnvironmentFile=/home/bflr/buildfor_life_repair/.env
Environment=NODE_ENV=production
Environment=PORT=3000
Environment=HOST=0.0.0.0
ExecStart=/usr/bin/node build/index.js
Restart=on-failure
RestartSec=5

# Hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/bflr/buildfor_life_repair/static/uploads
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now bflr

6. Verify

systemctl status bflr
curl http://localhost:3000

Resource recommendations

Resource Minimum Recommended
CPU 1 core 2 cores
RAM 512 MB 1024 MB
Disk 4 GB 8 GB

Add more disk if storing many device images/documents.

Reverse proxy (optional)

If running behind nginx on the Proxmox host or another LXC:

server {
    listen 443 ssl;
    server_name repair.example.com;

    ssl_certificate /etc/letsencrypt/live/repair.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/repair.example.com/privkey.pem;

    client_max_body_size 50M;  # for image uploads

    location / {
        proxy_pass http://192.168.1.x:3000;  # LXC IP
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Backups

# Database dump (add to cron)
pg_dump -U bflr buildfor_life_repair > /backup/bflr-$(date +%Y%m%d).sql

# Or use Proxmox's built-in LXC backup
vzdump 200 --storage backup --mode snapshot

Updating

# Debian/Ubuntu
su - bflr
cd buildfor_life_repair
git pull
npm install
npm run build
npm run db:push
exit
systemctl restart bflr

# NixOS
nixos-rebuild switch --flake git+https://git.b4l.co.th/B4L/buildfor_life_repair.git