#deploy on my server

1 messages · Page 1 of 1 (latest)

green stormBOT
#
Searched deploy Twenty CRM self-host server VPS domain setup
#
Searched Docker Compose installation Twenty environment variables SERVER_URL FRONTEND_URL
#

Based on the documentation, here's how to deploy Twenty CRM on your VPS with your custom domain:

The key issue is likely the SERVER_URL configuration. When deploying to a VPS with a custom domain, you need to configure this properly.

Quick Setup Steps:

1. Set up your .env file with the correct SERVER_URL:

# Without SSL (direct access)
SERVER_URL=http://your-domain-or-ip:3000

# With SSL via reverse proxy (recommended)
SERVER_URL=https://your-domain.com

2. Generate required secrets:

openssl rand -base64 32

Add this to your .env:

APP_SECRET=your_generated_secret
PG_DATABASE_PASSWORD=your_strong_password

3. Start the containers:

docker compose up -d

Important Notes:

  • SSL is recommended for production. Some browser features (like clipboard) require HTTPS to work properly
  • If using a reverse proxy (Nginx, Traefik), make sure it forwards to port 3000 and configure SSL termination there
  • The SERVER_URL must match exactly how users access your app in their browser
  • After changing .env, restart with:
    docker compose down
    docker compose up -d
    

Can you share:

  1. What error or issue are you seeing when accessing your domain?
  2. Are you using a reverse proxy for SSL?
  3. What does curl http://localhost:3000 return on your VPS?

This will help narrow down whether it's a configuration, networking, or SSL issue.


These pages may help:

eternal phoenix
#

nn, i want to use my src github ( clone twentycrm ) and want deploy up server

green stormBOT
#
Searched deploy Twenty CRM from source code github clone build
#
Searched production deployment build server VPS custom domain configuration
#

To deploy Twenty CRM from your cloned GitHub source to a VPS with your custom domain, here's what you need to do:

Option 1: Build from Source and Deploy with Docker (Recommended)

Since you cloned the repo, the easiest production deployment is still using Docker Compose from your source:

1. On your VPS, clone your repo:

git clone https://github.com/twentyhq/twenty.git
cd twenty

2. Navigate to the Docker directory and set up environment:

cd packages/twenty-docker
cp .env.example .env

3. Generate secrets and configure .env:

# Generate secret
openssl rand -base64 32

Edit your .env file:

APP_SECRET=your_generated_secret
PG_DATABASE_PASSWORD=your_strong_password
SERVER_URL=https://your-domain.com

4. Start the containers:

docker compose up -d

Option 2: Build from Source Manually (Without Docker)

If you want to run directly from source on your VPS:

1. Install prerequisites on your VPS:

  • Node v24.5.0 (use nvm)
  • PostgreSQL
  • Redis
  • yarn (run corepack enable)

2. Set up the project:

cd twenty
yarn
cp ./packages/twenty-front/.env.example ./packages/twenty-front/.env
cp ./packages/twenty-server/.env.example ./packages/twenty-server/.env

3. Configure environment variables in both .env files:

  • Set SERVER_URL=https://your-domain.com in the server .env

4. Initialize database and start:

npx nx database:reset twenty-server
npx nx start twenty-server
npx nx worker twenty-server
npx nx start twenty-front

For Your Custom Domain

You need a reverse proxy (Nginx/Traefik) with SSL. Example Nginx config:

server {
    listen 443 ssl;
    server_name your-domain.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

eternal phoenix
#

i use linux server

green stormBOT
#
Searched Linux server deployment self-host installation
#

Here's how to deploy Twenty CRM from your cloned GitHub source on a Linux VPS:

Option 1: Docker Compose (Recommended for Production)

1. Clone your repo on the VPS:

git clone https://github.com/twentyhq/twenty.git
cd twenty/packages/twenty-docker

2. Set up environment:

cp .env.example .env

3. Generate secrets and configure:

openssl rand -base64 32

Edit .env:

APP_SECRET=your_generated_secret
PG_DATABASE_PASSWORD=your_strong_password
SERVER_URL=https://your-domain.com

4. Start containers:

docker compose up -d

Option 2: Build from Source (Without Docker)

1. Install prerequisites:

# Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
# Close and reopen terminal, then:
nvm install
nvm use
corepack enable

2. Install PostgreSQL:

# Follow: https://www.postgresql.org/download/linux/
sudo -u postgres psql postgres -c "CREATE DATABASE \"default\";" -c "CREATE DATABASE test;"

3. Install Redis:

# Follow: https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/

4. Clone and set up:

git clone https://github.com/twentyhq/twenty.git
cd twenty
yarn
cp ./packages/twenty-front/.env.example ./packages/twenty-front/.env
cp ./packages/twenty-server/.env.example ./packages/twenty-server/.env

5. Configure SERVER_URL in ./packages/twenty-server/.env:

SERVER_URL=https://your-domain.com

6. Initialize and run:

npx nx database:reset twenty-server
npx nx start twenty-server
npx nx worker twenty-server
npx nx start twenty-front

For Your Custom Domain

Set up a reverse proxy (Nginx) with SSL:

server {
    listen 443 ssl;
    server_name your-domain.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    location / {
        proxy_pass http://localhost:3000;
#

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}


---

What specific error are you seeing when you try to access your domain? That will help narrow down the issue.

These pages may help:
- [Docker Compose Installation](https://docs.twenty.com/developers/self-host/capabilities/docker-compose)
- [Local Setup Guide](https://docs.twenty.com/developers/contribute/capabilities/local-setup)
- [Setup & Configuration](https://docs.twenty.com/developers/self-host/capabilities/setup)
Twenty Documentation

The guide for contributors (or curious developers) who want to run Twenty locally.

Twenty Documentation
eternal phoenix
#

Phương án 1 đi

green stormBOT
#
Searched Docker Compose self-host deployment production setup
#

Dùng Docker Compose trên Linux VPS. Đây là các bước chi tiết:

Bước 1: Tạo thư mục và tải file cấu hình

mkdir twenty
cd twenty

Tải file .envdocker-compose.yml:

curl -o .env https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-docker/.env.example
curl -o docker-compose.yml https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-docker/docker-compose.yml

Bước 2: Tạo secret và cấu hình .env

Tạo secret key:

openssl rand -base64 32

Chỉnh sửa file .env:

nano .env

Cập nhật các giá trị sau:

APP_SECRET=your_generated_secret_here
PG_DATABASE_PASSWORD=your_strong_password_here
SERVER_URL=https://your-domain.com

Lưu ý:

  • PG_DATABASE_PASSWORD không nên chứa ký tự đặc biệt
  • SERVER_URL phải khớp với domain bạn sẽ truy cập

Bước 3: Khởi động containers

docker compose up -d

Bước 4: Kiểm tra

curl http://localhost:3000

Cấu hình Domain với Nginx (SSL)

Nếu bạn muốn dùng domain với HTTPS, cài đặt Nginx làm reverse proxy:

sudo apt install nginx certbot python3-certbot-nginx

Tạo file config Nginx:

sudo nano /etc/nginx/sites-available/twenty

Nội dung:

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

Kích hoạt và cài SSL:

sudo ln -s /etc/nginx/sites-available/twenty /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d your-domain.com

Yêu cầu hệ thống

  • RAM: tối thiểu 2GB
  • Docker và Docker Compose đã cài đặt

Bạn đang gặp lỗi gì cụ thể khi deploy? Paste lỗi vào đây để mình hỗ trợ thêm.

eternal phoenix
#

Ủa như này có chỉnh sửa src code được k

green stormBOT
#

Nếu bạn muốn chỉnh sửa source code thì cần clone repo và build từ source, không dùng Docker image có sẵn.

Cách deploy với source code tùy chỉnh:

Bước 1: Clone repo về VPS

git clone https://github.com/twentyhq/twenty.git
cd twenty

Bước 2: Chỉnh sửa source code theo ý bạn

Ví dụ chỉnh frontend:

nano packages/twenty-front/src/...

Hoặc chỉnh backend:

nano packages/twenty-server/src/...

Bước 3: Build và chạy với Docker Compose

Sau khi chỉnh sửa xong, vào thư mục docker:

cd packages/twenty-docker
cp .env.example .env

Cấu hình .env:

nano .env
APP_SECRET=your_generated_secret
PG_DATABASE_PASSWORD=your_strong_password
SERVER_URL=https://your-domain.com

Bước 4: Build image từ source và chạy

docker compose up -d --build

Flag --build sẽ build lại image từ source code bạn đã chỉnh sửa.


Hoặc chạy trực tiếp từ source (không dùng Docker)

Nếu muốn dev/test nhanh hơn:

cd twenty

# Cài dependencies
nvm install
nvm use
corepack enable
yarn

# Copy env files
cp ./packages/twenty-front/.env.example ./packages/twenty-front/.env
cp ./packages/twenty-server/.env.example ./packages/twenty-server/.env

# Chỉnh SERVER_URL trong twenty-server/.env
nano ./packages/twenty-server/.env

# Reset database và chạy
npx nx database:reset twenty-server
npx nx start twenty-server
npx nx worker twenty-server
npx nx start twenty-front

Bạn muốn chỉnh sửa phần nào của Twenty CRM? Frontend, backend, hay cả hai?

eternal phoenix
#

Mình muốn chỉnh mỗi frontend thôi á

green stormBOT
#

Nếu chỉ chỉnh frontend thì đây là cách làm:

Bước 1: Clone repo về VPS

git clone https://github.com/twentyhq/twenty.git
cd twenty

Bước 2: Chỉnh sửa frontend

Source code frontend nằm trong:

cd packages/twenty-front/src

Cấu trúc thư mục chính:

  • modules/ - Các module chức năng (CRM, settings, etc.)
  • pages/ - Các trang
  • components/ - Components dùng chung
  • themes/ - Theme và styling

Chỉnh sửa theo ý bạn:

nano packages/twenty-front/src/...

Bước 3: Build và deploy với Docker

Quay lại thư mục gốc và vào docker:

cd ~/twenty/packages/twenty-docker
cp .env.example .env

Cấu hình .env:

nano .env
APP_SECRET=your_generated_secret
PG_DATABASE_PASSWORD=your_strong_password
SERVER_URL=https://your-domain.com

Build và chạy:

docker compose up -d --build

Mỗi lần chỉnh sửa frontend

Sau khi sửa code, rebuild lại:

docker compose down
docker compose up -d --build

Tip: Dev nhanh hơn trên local

Nếu muốn xem thay đổi ngay lập tức khi dev, chạy frontend riêng:

cd packages/twenty-front
cp .env.example .env
yarn
yarn dev

Sau khi hoàn tất chỉnh sửa, mới build Docker để deploy lên VPS.


Bạn muốn chỉnh phần gì của frontend? Logo, màu sắc, layout, hay thêm tính năng mới?

eternal phoenix
#

Mục đích của mình á là dựng ci/cd từ github của mình vào server ( mỗi khi nhánh main thay đổi thì sẽ update code mới lên server ) ( đã xong ), sau đó mình muốn dùng chính bộ src trên server này để chạy twentycrm lên domain của server luôn

green stormBOT
#

Vậy bạn đã có CI/CD rồi, giờ chỉ cần setup để chạy Twenty CRM từ source trên server.

Cách 1: Dùng Docker Compose (Khuyên dùng cho production)

Trong CI/CD pipeline, sau khi pull code mới về, chạy:

cd /path/to/twenty/packages/twenty-docker
docker compose down
docker compose up -d --build

Setup lần đầu:

cd /path/to/twenty/packages/twenty-docker
cp .env.example .env
nano .env
APP_SECRET=your_generated_secret
PG_DATABASE_PASSWORD=your_strong_password
SERVER_URL=https://your-domain.com

Cách 2: Chạy trực tiếp từ source (dùng PM2)

Nếu không muốn dùng Docker, dùng PM2 để quản lý process:

Bước 1: Cài prerequisites

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
# Mở terminal mới
nvm install 24.5.0
nvm use 24.5.0
corepack enable
npm install -g pm2

Bước 2: Setup lần đầu

cd /path/to/twenty
yarn

cp ./packages/twenty-front/.env.example ./packages/twenty-front/.env
cp ./packages/twenty-server/.env.example ./packages/twenty-server/.env

# Chỉnh SERVER_URL
nano ./packages/twenty-server/.env
SERVER_URL=https://your-domain.com

Bước 3: Init database

npx nx database:reset twenty-server

Bước 4: Chạy với PM2

pm2 start "npx nx start twenty-server" --name twenty-server
pm2 start "npx nx worker twenty-server" --name twenty-worker
pm2 start "npx nx start twenty-front" --name twenty-front
pm2 save

Trong CI/CD pipeline, mỗi khi code thay đổi:

cd /path/to/twenty
git pull
yarn
pm2 restart all

Nginx reverse proxy

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}
sudo certbot --nginx -d your-domain.com
#

---

Bạn muốn dùng cách nào? Docker hay PM2?
eternal phoenix
#

cách 1 đi, mình chạy theo rồi nhưng lỗi ở bước docker compose up -d --build
dependency failed to start: container twenty-server-1 is unhealthy

green stormBOT
#

Lỗi này thường do container twenty-server không khởi động được. Kiểm tra log để xem nguyên nhân:

Bước 1: Xem log chi tiết

docker compose logs twenty-server

Bước 2: Kiểm tra các nguyên nhân phổ biến

1. Thiếu hoặc sai APP_SECRET:

cat .env | grep APP_SECRET

Nếu trống, tạo mới:

openssl rand -base64 32

Thêm vào .env:

APP_SECRET=your_generated_secret_here

2. Lỗi kết nối database - kiểm tra PG_DATABASE_PASSWORD:

cat .env | grep PG_DATABASE_PASSWORD

Đảm bảo password không chứa ký tự đặc biệt như @, #, $, %.

3. Kiểm tra container database đã chạy chưa:

docker compose ps

Bước 3: Reset và chạy lại

docker compose down -v
docker compose up -d --build

Flag -v sẽ xóa volumes cũ (database sẽ bị reset).


Bước 4: Theo dõi quá trình khởi động

docker compose logs -f twenty-server

Paste log lỗi từ docker compose logs twenty-server vào đây để mình xem cụ thể nhé.

eternal phoenix
#

root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# docker compose logs twenty-server
WARN[0000] The "STORAGE_S3_NAME" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_ENDPOINT" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_REGION" variable is not set. Defaulting to a blank string.
WARN[0000] The "DISABLE_DB_MIGRATIONS" variable is not set. Defaulting to a blank string.
WARN[0000] The "DISABLE_CRON_JOBS_REGISTRATION" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_REGION" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_NAME" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_ENDPOINT" variable is not set. Defaulting to a blank string.
no such service: twenty-server
root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# cat .env | grep APP_SECRET

APP_SECRET=fq6zNoVyAA

root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# cat .env | grep PG_DATABASE_PASSWORD
#PG_DATABASE_PASSWORD=fq6zNoVyAA
Đây nè

green stormBOT
#

Thấy vấn đề rồi. Có 2 lỗi:

Lỗi 1: Biến môi trường bị comment (có dấu # phía trước)

# APP_SECRET=fq6zNoVyAA        # <-- Bị comment
#PG_DATABASE_PASSWORD=fq6zNoVyAA  # <-- Bị comment

Lỗi 2: Service name không đúng

Bạn đang dùng source clone về nên tên service có thể khác. Kiểm tra:

docker compose config --services

Sửa lỗi:

Bước 1: Chỉnh file .env, bỏ dấu #:

nano .env

Sửa thành (bỏ dấu #):

APP_SECRET=fq6zNoVyAA
PG_DATABASE_PASSWORD=fq6zNoVyAA
SERVER_URL=https://your-domain.com

Bước 2: Reset và chạy lại:

docker compose down -v
docker compose up -d --build

Bước 3: Kiểm tra logs:

docker compose logs -f

Thử xem và paste kết quả nếu vẫn lỗi nhé.

eternal phoenix
#

TAG=latest

#PG_DATABASE_USER=postgres
PG_DATABASE_PASSWORD=fq6zNoVyAA
#PG_DATABASE_HOST=db
#PG_DATABASE_PORT=5432
#REDIS_URL=redis://redis:6379

SERVER_URL=http://crmdemo.samset.net

Use openssl rand -base64 32 for each secret

APP_SECRET=fq6zNoVyAA

STORAGE_TYPE=local

STORAGE_S3_REGION=eu-west3

STORAGE_S3_NAME=my-bucket

STORAGE_S3_ENDPOINT=

FFile.env như này đúng k

green stormBOT
#

Gần đúng rồi, nhưng cần sửa một số chỗ:

Vấn đề cần sửa:

1. APP_SECRET quá ngắn - cần ít nhất 32 ký tự để bảo mật:

openssl rand -base64 32

2. SERVER_URL nên dùng HTTPS nếu bạn setup SSL với Nginx:


File .env đúng:

nano .env
TAG=latest

PG_DATABASE_PASSWORD=fq6zNoVyAA

SERVER_URL=https://crmdemo.samset.net

APP_SECRET=paste_your_32_char_secret_here

STORAGE_TYPE=local

Sau khi sửa xong:

docker compose down -v
docker compose up -d --build

Kiểm tra:

docker compose ps
docker compose logs -f

Nhớ setup Nginx reverse proxy cho domain crmdemo.samset.net nữa nhé. Bạn đã cài Nginx chưa?

eternal phoenix
#

✘ Container twenty-server-1 Error dependency server failed to start 112.0s
✔ Container twenty-worker-1 Created 0.0s
dependency failed to start: container twenty-server-1 is unhealthy
root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# docker compose logs twenty-server
WARN[0000] The "DISABLE_DB_MIGRATIONS" variable is not set. Defaulting to a blank string.
WARN[0000] The "DISABLE_CRON_JOBS_REGISTRATION" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_REGION" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_NAME" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_ENDPOINT" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_ENDPOINT" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_REGION" variable is not set. Defaulting to a blank string.
WARN[0000] The "STORAGE_S3_NAME" variable is not set. Defaulting to a blank string.
no such service: twenty-server
root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# cat .env | grep PG_DATABASE_PASSWORD
PG_DATABASE_PASSWORD=fq6zNoVyAA
root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# cat .env | grep APP_SECRET
APP_SECRET=TAeZomAYPNo0ZyHWWsBkUuHkXl61xDk2kbWiSVOjeWg=
Sao vẫn lỗi nè

green stormBOT
#

Lỗi no such service: twenty-server cho thấy tên service trong docker-compose.yml khác với tên mặc định.

Bước 1: Kiểm tra tên services thực tế

docker compose config --services

Bước 2: Xem tất cả logs

docker compose logs

Bước 3: Kiểm tra container nào đang chạy/lỗi

docker compose ps -a

Paste kết quả 3 lệnh trên vào đây để mình xem tên service đúng và lỗi cụ thể nhé.

eternal phoenix
#

BBước1 :
db
redis
server
worker

Bước 2 : dài quá
BBước3 :
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
twenty-db-1 postgres:16 "docker-entrypoint.s…" db 6 minutes ago Up 6 minutes (healthy) 5432/tcp
twenty-redis-1 redis "docker-entrypoint.s…" redis 6 minutes ago Up 6 minutes (healthy) 6379/tcp
twenty-server-1 twentycrm/twenty:latest "/app/entrypoint.sh …" server 6 minutes ago Up 5 minutes (healthy) 0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp
twenty-worker-1 twentycrm/twenty:latest "/app/entrypoint.sh …" worker 6 minutes ago Created

green stormBOT
#

Tất cả đang chạy tốt rồi. twenty-server-1 đã healthy và đang listen port 3000.

Kiểm tra xem Twenty CRM đã hoạt động chưa:

curl http://localhost:3000

Khởi động worker (đang ở trạng thái Created):

docker compose up -d worker

Kiểm tra lại:

docker compose ps -a

Nếu curl localhost:3000 trả về HTML, setup Nginx:

sudo apt install nginx -y
sudo nano /etc/nginx/sites-available/twenty

Nội dung:

server {
    listen 80;
    server_name crmdemo.samset.net;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

Kích hoạt:

sudo ln -s /etc/nginx/sites-available/twenty /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Cài SSL:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d crmdemo.samset.net

Thử curl http://localhost:3000 và cho mình biết kết quả nhé.

eternal phoenix
#

root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# curl http://localhost:3000
<!doctype html>
<html lang="en" translate="no">
<head>
<meta charset="UTF-8" />

<link
  rel="icon"
  type="image/x-icon"
  href="/images/icons/android/android-launchericon-48-48.png"
  data-rh="true"
/>
<link rel="apple-touch-icon" href="/images/icons/ios/192.png" />
<link rel="manifest" href="/manifest.json" />

<meta name="theme-color" content="#000000" />
<meta name="description" content="A modern open-source CRM" />
<meta
  property="og:image"
  content="https://raw.githubusercontent.com/twentyhq/twenty/main/docs/static/img/social-card.png"
/>
<meta property="og:description" content="A modern open-source CRM" />
<meta property="og:title" content="Twenty" />
<meta name="twitter:card" content="summary_large_image" />
<meta
  name="twitter:image"
  content="https://raw.githubusercontent.com/twentyhq/twenty/main/docs/static/img/social-card.png"
/>

<meta name="twitter:description" content="A modern open-source CRM" />
<meta name="twitter:title" content="Twenty" />
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
/>

....

green stormBOT
#

Twenty CRM đã chạy thành công rồi.

Giờ setup Nginx để truy cập qua domain:

Bước 1: Cài Nginx

sudo apt install nginx -y

Bước 2: Tạo config

sudo nano /etc/nginx/sites-available/twenty

Paste nội dung:

server {
    listen 80;
    server_name crmdemo.samset.net;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

Bước 3: Kích hoạt và reload

sudo ln -s /etc/nginx/sites-available/twenty /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Bước 4: Cài SSL

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d crmdemo.samset.net

Bước 5: Cập nhật .env với HTTPS

nano .env

Sửa:

SERVER_URL=https://crmdemo.samset.net

Restart containers:

docker compose down
docker compose up -d

Sau đó truy cập https://crmdemo.samset.net để kiểm tra.

Nhớ đảm bảo DNS của crmdemo.samset.net đã trỏ về IP server của bạn nhé.

eternal phoenix
#

root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dcd06ebd11cc twentycrm/twenty:latest "/app/entrypoint.sh …" 2 minutes ago Up About a minute twenty-worker-1
6303de642775 twentycrm/twenty:latest "/app/entrypoint.sh …" 2 minutes ago Up 2 minutes (healthy) 0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp twenty-server-1
7d31e26a370f postgres:16 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes (healthy) 5432/tcp twenty-db-1
338f7d5cfbd9 redis "docker-entrypoint.s…" 2 minutes ago Up 2 minutes (healthy) 6379/tcp twenty-redis-1
Nhưng mở trang crmdemo.samset.net thì nó báo trên UI là Không Thể Kết Nối Back-end

green stormBOT
#

Lỗi này do frontend không kết nối được với backend. Kiểm tra và sửa như sau:

Bước 1: Kiểm tra SERVER_URL trong .env

cat .env | grep SERVER_URL

Đảm bảo giá trị là:

SERVER_URL=https://crmdemo.samset.net

Bước 2: Kiểm tra backend API hoạt động

curl http://localhost:3000/healthz

Bước 3: Kiểm tra Nginx config có proxy đúng không

cat /etc/nginx/sites-available/twenty

Cần có config như này:

server {
    listen 80;
    server_name crmdemo.samset.net;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

Bước 4: Restart lại containers sau khi sửa .env

cd ~/tourchaincrm/packages/twenty-docker
docker compose down
docker compose up -d

Bước 5: Reload Nginx

sudo nginx -t
sudo systemctl reload nginx

Paste kết quả của các lệnh kiểm tra ở Bước 1, 2, 3 vào đây để mình xem nhé.

eternal phoenix
#

root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dcd06ebd11cc twentycrm/twenty:latest "/app/entrypoint.sh …" 2 minutes ago Up About a minute twenty-worker-1
6303de642775 twentycrm/twenty:latest "/app/entrypoint.sh …" 2 minutes ago Up 2 minutes (healthy) 0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp twenty-server-1
7d31e26a370f postgres:16 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes (healthy) 5432/tcp twenty-db-1
338f7d5cfbd9 redis "docker-entrypoint.s…" 2 minutes ago Up 2 minutes (healthy) 6379/tcp twenty-redis-1
root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# cat .env | grep SERVER_URL
SERVER_URL=https://crmdemo.samset.net
root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# curl http://localhost:3000/healthz
{"status":"ok","info":{},"error":{},"details":{}}root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker#

green stormBOT
#

Backend đang hoạt động tốt ("status":"ok"). Vấn đề có thể do Nginx hoặc SSL.

Bước 1: Kiểm tra Nginx config

cat /etc/nginx/sites-available/twenty

Bước 2: Kiểm tra SSL đã cài chưa

sudo certbot certificates

Bước 3: Test API qua domain

curl https://crmdemo.samset.net/healthz

Paste kết quả 3 lệnh trên vào đây nhé. Khả năng cao là do SSL chưa được cấu hình đúng hoặc Nginx chưa proxy API endpoints.

eternal phoenix
#

root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# sudo certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log


No certificates found.


root@cs-linux-20260113172059287:~/tourchaincrm/packages/twenty-docker# cat /etc/nginx/sites-available/twenty
server {
listen 80;
server_name crmdemo.samset.net;

location / {
    proxy_pass http://localhost:3000;
    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;
}

}

green stormBOT
#

Thấy vấn đề rồi. SSL chưa được cài, nhưng SERVER_URL đang là https://. Có 2 cách sửa:

Cách 1: Cài SSL (Khuyên dùng)

sudo certbot --nginx -d crmdemo.samset.net

Sau khi cài xong, restart containers:

cd ~/tourchaincrm/packages/twenty-docker
docker compose down
docker compose up -d

Cách 2: Tạm thời dùng HTTP (nếu chưa muốn cài SSL)

Bước 1: Sửa .env

nano .env

Đổi thành:

SERVER_URL=http://crmdemo.samset.net

Bước 2: Restart containers

docker compose down
docker compose up -d

Thử cách 1 trước nhé. Nếu certbot báo lỗi gì thì paste vào đây.

eternal phoenix
#

oke lên rồi nè bạn, rồi như sau này mình muốn khi github thay đổi thì đưa thay đổi lên src, thì làm sao để docker biết để tự động build lại

green stormBOT
#

Trong CI/CD pipeline của bạn (GitHub Actions), thêm bước SSH vào server và rebuild:

GitHub Actions workflow (.github/workflows/deploy.yml)

name: Deploy Twenty CRM

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to VPS
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            cd ~/tourchaincrm
            git pull origin main
            cd packages/twenty-docker
            docker compose down
            docker compose up -d --build

Thêm Secrets trong GitHub repo

Vào Settings > Secrets and variables > Actions, thêm:

+---------------+-----------------------------------+
|  Secret Name  |              Giá trị              |
+---------------+-----------------------------------+
| `VPS_HOST`    | IP hoặc domain server của bạn     |
| `VPS_USER`    | `root` (hoặc user khác)           |
| `VPS_SSH_KEY` | Private SSH key để kết nối server |
+---------------+-----------------------------------+

Tạo SSH key (nếu chưa có)

Trên server:

ssh-keygen -t ed25519 -C "github-actions"
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys
cat ~/.ssh/id_ed25519

Copy nội dung id_ed25519 (private key) vào secret VPS_SSH_KEY.


Mỗi khi push code lên nhánh main, GitHub Actions sẽ tự động:

  1. SSH vào server
  2. Pull code mới
  3. Rebuild và restart containers

Bạn đang dùng GitHub Actions hay CI/CD tool khác?

eternal phoenix
#

Hiện tại file cd-deploy-main.yaml đang như này
name: CD deploy main

permissions:
contents: write

on:
push:
branches:
- main

jobs:
deploy-main:
timeout-minutes: 5
runs-on: self-hosted

steps:
  - name: Checkout code
    uses: actions/checkout@v4

  - name: Initialize and Sync Source Code
    run: |
      mkdir -p /root/tourchaincrm
      
      rsync -avz --exclude '.git' ./ /root/tourchaincrm/
      
      echo "Src code đã được đồng bộ vào /root/tourchaincrm thành công!"

  - name: Repository Dispatch
    uses: peter-evans/repository-dispatch@v2
    with:
      token: ${{ secrets.GITHUB_TOKEN }}
      repository: SamsetSolution/tourchaincrm
      event-type: auto-deploy-main
      client-payload: '{"github": ${{ toJson(github) }}}'
green stormBOT
#

Bạn đang dùng self-hosted runner trên chính server. Chỉ cần thêm bước rebuild Docker sau khi sync code:

Cập nhật cd-deploy-main.yaml

name: CD deploy main

permissions:
  contents: write

on:
  push:
    branches:
      - main

jobs:
  deploy-main:
    timeout-minutes: 10
    runs-on: self-hosted
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Initialize and Sync Source Code
        run: |
          mkdir -p /root/tourchaincrm
          
          rsync -avz --exclude '.git' ./ /root/tourchaincrm/
          
          echo "Src code đã được đồng bộ vào /root/tourchaincrm thành công!"

      - name: Rebuild and Restart Docker
        run: |
          cd /root/tourchaincrm/packages/twenty-docker
          docker compose down
          docker compose up -d --build
          echo "Docker đã rebuild và restart thành công!"

      - name: Repository Dispatch
        uses: peter-evans/repository-dispatch@v2
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          repository: SamsetSolution/tourchaincrm
          event-type: auto-deploy-main
          client-payload: '{"github": ${{ toJson(github) }}}'

Thay đổi chính:

  1. Thêm bước Rebuild and Restart Docker sau khi sync code
  2. Tăng timeout-minutes lên 10 vì build Docker có thể mất thời gian

Mỗi khi push code lên main:

  1. Checkout code
  2. Sync vào /root/tourchaincrm
  3. Rebuild Docker containers với code mới
  4. Dispatch event

Thử push một thay đổi nhỏ lên main để test nhé.

eternal phoenix
#

oke, giờ mình muốn đưa data từ máy local lên dùng cho server này thì sao

green stormBOT
#
Searched migrate data import export backup restore
#

Có 2 cách để đưa data từ local lên server:

Cách 1: Backup và Restore Database (Nhanh nhất)

Trên máy local - Tạo backup:

docker exec twenty-db-1 pg_dump -U postgres twenty > backup_local.sql

Copy file backup lên server:

scp backup_local.sql root@your-server-ip:~/tourchaincrm/packages/twenty-docker/

Trên server - Restore:

cd ~/tourchaincrm/packages/twenty-docker

# Dừng server và worker
docker compose stop server worker

# Restore database
docker exec -i twenty-db-1 psql -U postgres twenty < backup_local.sql

# Khởi động lại
docker compose up -d

Cách 2: Export/Import CSV (Nếu muốn chọn lọc data)

Trên máy local:

  1. Vào từng object (Companies, People, Opportunities...)
  2. Click ⋮ → Export view
  3. Lưu file CSV

Trên server:

  1. Truy cập https://crmdemo.samset.net
  2. Vào từng object
  3. Click ⋮ → Import records
  4. Upload file CSV

Thứ tự import quan trọng:

  1. Companies trước
  2. People sau (vì liên kết với Companies)
  3. Opportunities sau cùng

Lưu ý quan trọng

  • Cách 1 sẽ ghi đè toàn bộ data trên server
  • Cách 2 cho phép merge data, nhưng cần cẩn thận với duplicate

Bạn muốn dùng cách nào?

eternal phoenix
#

Cách 1 đi, mình có 1 server khác và đang chạy twentycrm version 1.11.0 mình tạo khoảng 20 object custom trên trực tiếp giao diện và hàng trăm data. Giờ làm đưa để đưa vào con server này chạy được data đó

green stormBOT
#
Searched migrate data backup restore database twenty crm
#

Vì bạn đang migrate từ server cũ (v1.11.0) sang server mới, cần làm theo các bước sau:

Lưu ý quan trọng

Vì bạn có 20 custom objectshàng trăm data, cần backup cẩn thận. Cả 2 server đều chạy Twenty nên có thể dùng pg_dump để migrate database.


Bước 1: Backup database từ server cũ (v1.11.0)

SSH vào server cũ và chạy:

docker exec twenty-db-1 pg_dump -U postgres twenty > backup_old_server.sql

Kiểm tra file backup không rỗng:

ls -la backup_old_server.sql
head -50 backup_old_server.sql

Bước 2: Copy file backup sang server mới

scp backup_old_server.sql root@your-new-server-ip:~/tourchaincrm/packages/twenty-docker/

Bước 3: Restore trên server mới

SSH vào server mới và chạy:

cd ~/tourchaincrm/packages/twenty-docker

# Dừng server và worker
docker compose stop server worker

# Restore database
docker exec -i twenty-db-1 psql -U postgres twenty < backup_old_server.sql

# Khởi động lại
docker compose up -d

Lưu ý về version

Vì server cũ chạy v1.11.0 và server mới có thể chạy version khác, cần kiểm tra:

# Kiểm tra version trên server mới
docker exec twenty-server-1 echo $APP_VERSION

Nếu version khác nhau nhiều, bạn có thể cần:

  1. Đảm bảo server mới cũng chạy v1.11.0 hoặc version tương thích
  2. Hoặc upgrade tuần tự theo Upgrade Guide

Cách thay đổi version (nếu cần)

Trong file .env trên server mới:

TAG=v1.11.0

Sau đó:

docker compose down
docker compose up -d

Bạn kiểm tra version trên cả 2 server trước nhé:

  • Server cũ: docker exec twenty-server-1 echo $APP_VERSION
  • Server mới: kiểm tra TAG trong .env

Paste kết quả vào đây để mình hướng dẫn tiếp.

eternal phoenix
#

root@cs-linux-20251025133135236:~/twenty# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fe8aaceb59b8 twentycrm/twenty:v1.11.5 "/app/entrypoint.sh …" 8 weeks ago Up 3 days twenty-worker-1
42aac80ddfae twentycrm/twenty:v1.11.5 "/app/entrypoint.sh …" 8 weeks ago Up 2 days (healthy) 0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp twenty-server-1
eab04c079a05 postgres:16 "docker-entrypoint.s…" 8 weeks ago Up 5 days (healthy) 5432/tcp twenty-db-1
69a19d792038 redis "docker-entrypoint.s…" 8 weeks ago Up 4 days (healthy) 6379/tcp twenty-redis-1
32daba8a387f jc21/nginx-proxy-manager:latest "/init" 2 months ago Up 5 days 0.0.0.0:80-81->80-81/tcp, [::]:80-81->80-81/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp npm-nginxproxymanager-1
Đây nè

green stormBOT
#

Error: {"success":false,"status":403}

eternal phoenix
#

hello