mirror of
https://github.com/twentyhq/twenty.git
synced 2024-11-22 03:17:40 +03:00
Begin moving to postgres spilo + adding pgvector (#8309)
We will remove the `twenty-postgres` image that was used for local development and only use `twenty-postgres-pilo` (which we use in prod), bringing the development environment closer to prod and avoiding having to maintain 2 images. Instead of provisioning the super user after the db initialization, we directly rely on the superuser provided by Spilo for simplicity. We also introduce a change that tries to create the right database (`default` or `test`) based on the context. How to test: ``` docker build -t twentycrm/twenty-postgres-spilo:latest -f ./packages/twenty-docker/twenty-postgres-spilo/Dockerfile . docker images --no-trunc | grep twenty-postgres-spilo postgres-on-docker: docker run \ --name twenty_pg \ -e PGUSER_SUPERUSER=twenty \ -e PGPASSWORD_SUPERUSER=twenty \ -e ALLOW_NOSSL=true \ -v twenty_db_data:/home/postgres/pgdata \ -p 5432:5432 \ REPLACE_WITH_IMAGE_ID ```
This commit is contained in:
parent
cfe3515aa6
commit
736635a94b
31
.github/workflows/ci-server.yaml
vendored
31
.github/workflows/ci-server.yaml
vendored
@ -18,12 +18,19 @@ jobs:
|
|||||||
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
|
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: twentycrm/twenty-postgres
|
image: twentycrm/twenty-postgres-spilo
|
||||||
env:
|
env:
|
||||||
POSTGRES_PASSWORD: postgres
|
PGUSER_SUPERUSER: postgres
|
||||||
POSTGRES_USER: postgres
|
PGPASSWORD_SUPERUSER: twenty
|
||||||
|
ALLOW_NOSSL: "true"
|
||||||
|
SPILO_PROVIDER: "local"
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
|
options: >-
|
||||||
|
--health-cmd pg_isready
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
redis:
|
redis:
|
||||||
image: redis
|
image: redis
|
||||||
ports:
|
ports:
|
||||||
@ -63,6 +70,11 @@ jobs:
|
|||||||
- name: Server / Write .env
|
- name: Server / Write .env
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
run: npx nx reset:env twenty-server
|
run: npx nx reset:env twenty-server
|
||||||
|
- name: Server / Create DB
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: |
|
||||||
|
PGPASSWORD=twenty psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "default";'
|
||||||
|
PGPASSWORD=twenty psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "test";'
|
||||||
- name: Worker / Run
|
- name: Worker / Run
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
run: npx nx run twenty-server:worker:ci
|
run: npx nx run twenty-server:worker:ci
|
||||||
@ -109,12 +121,19 @@ jobs:
|
|||||||
needs: server-setup
|
needs: server-setup
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: twentycrm/twenty-postgres
|
image: twentycrm/twenty-postgres-spilo
|
||||||
env:
|
env:
|
||||||
POSTGRES_PASSWORD: postgres
|
PGUSER_SUPERUSER: postgres
|
||||||
POSTGRES_USER: postgres
|
PGPASSWORD_SUPERUSER: twenty
|
||||||
|
ALLOW_NOSSL: "true"
|
||||||
|
SPILO_PROVIDER: "local"
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
|
options: >-
|
||||||
|
--health-cmd pg_isready
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
redis:
|
redis:
|
||||||
image: redis
|
image: redis
|
||||||
ports:
|
ports:
|
||||||
|
37
.github/workflows/ci-test-docker-compose.yaml
vendored
37
.github/workflows/ci-test-docker-compose.yaml
vendored
@ -8,7 +8,7 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
timeout-minutes: 10
|
timeout-minutes: 30
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@ -36,20 +36,42 @@ jobs:
|
|||||||
|
|
||||||
yq eval 'del(.services.db.image)' -i docker-compose.yml
|
yq eval 'del(.services.db.image)' -i docker-compose.yml
|
||||||
yq eval '.services.db.build.context = "../../"' -i docker-compose.yml
|
yq eval '.services.db.build.context = "../../"' -i docker-compose.yml
|
||||||
yq eval '.services.db.build.dockerfile = "./packages/twenty-docker/twenty-postgres/Dockerfile"' -i docker-compose.yml
|
yq eval '.services.db.build.dockerfile = "./packages/twenty-docker/twenty-postgres-spilo/Dockerfile"' -i docker-compose.yml
|
||||||
|
|
||||||
echo "Setting up .env file..."
|
echo "Setting up .env file..."
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
echo "Generating secrets..."
|
echo "Generating secrets..."
|
||||||
echo "# === Randomly generated secrets ===" >>.env
|
echo "# === Randomly generated secrets ===" >>.env
|
||||||
echo "APP_SECRET=$(openssl rand -base64 32)" >>.env
|
echo "APP_SECRET=$(openssl rand -base64 32)" >>.env
|
||||||
echo "POSTGRES_ADMIN_PASSWORD=$(openssl rand -base64 32)" >>.env
|
echo "PGPASSWORD_SUPERUSER=$(openssl rand -base64 32)" >>.env
|
||||||
|
|
||||||
echo "Starting server..."
|
echo "Docker compose up..."
|
||||||
docker compose up -d
|
docker compose up -d || {
|
||||||
|
echo "Docker compose failed to start"
|
||||||
|
docker compose logs
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
docker compose logs db server -f &
|
docker compose logs db server -f &
|
||||||
pid=$!
|
pid=$!
|
||||||
|
|
||||||
|
echo "Waiting for database to start..."
|
||||||
|
count=0
|
||||||
|
while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-db-1) = "healthy" ]; do
|
||||||
|
sleep 1;
|
||||||
|
count=$((count+1));
|
||||||
|
if [ $(docker inspect --format='{{.State.Status}}' twenty-db-1) = "exited" ]; then
|
||||||
|
echo "Database exited"
|
||||||
|
docker compose logs db
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ $count -gt 300 ]; then
|
||||||
|
echo "Failed to start database after 5 minutes"
|
||||||
|
docker compose logs db
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Still waiting for database... (${count}/60)"
|
||||||
|
done
|
||||||
|
|
||||||
echo "Waiting for server to start..."
|
echo "Waiting for server to start..."
|
||||||
count=0
|
count=0
|
||||||
while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-server-1) = "healthy" ]; do
|
while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-server-1) = "healthy" ]; do
|
||||||
@ -57,11 +79,14 @@ jobs:
|
|||||||
count=$((count+1));
|
count=$((count+1));
|
||||||
if [ $(docker inspect --format='{{.State.Status}}' twenty-server-1) = "exited" ]; then
|
if [ $(docker inspect --format='{{.State.Status}}' twenty-server-1) = "exited" ]; then
|
||||||
echo "Server exited"
|
echo "Server exited"
|
||||||
|
docker compose logs server
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [ $count -gt 300 ]; then
|
if [ $count -gt 300 ]; then
|
||||||
echo "Failed to start server"
|
echo "Failed to start server after 5 minutes"
|
||||||
|
docker compose logs server
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
echo "Still waiting for server... (${count}/300s)"
|
||||||
done
|
done
|
||||||
working-directory: ./packages/twenty-docker/
|
working-directory: ./packages/twenty-docker/
|
||||||
|
21
.github/workflows/ci-website.yaml
vendored
21
.github/workflows/ci-website.yaml
vendored
@ -17,12 +17,19 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: twentycrm/twenty-postgres
|
image: twentycrm/twenty-postgres-spilo
|
||||||
env:
|
env:
|
||||||
POSTGRES_PASSWORD: twenty
|
PGUSER_SUPERUSER: postgres
|
||||||
POSTGRES_USER: twenty
|
PGPASSWORD_SUPERUSER: twenty
|
||||||
|
ALLOW_NOSSL: "true"
|
||||||
|
SPILO_PROVIDER: "local"
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
|
options: >-
|
||||||
|
--health-cmd pg_isready
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@ -37,16 +44,20 @@ jobs:
|
|||||||
if: steps.changed-files.outputs.changed == 'true'
|
if: steps.changed-files.outputs.changed == 'true'
|
||||||
uses: ./.github/workflows/actions/yarn-install
|
uses: ./.github/workflows/actions/yarn-install
|
||||||
|
|
||||||
|
- name: Server / Create DB
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: PGPASSWORD=twenty psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "default";'
|
||||||
|
|
||||||
- name: Website / Run migrations
|
- name: Website / Run migrations
|
||||||
if: steps.changed-files.outputs.changed == 'true'
|
if: steps.changed-files.outputs.changed == 'true'
|
||||||
run: npx nx database:migrate twenty-website
|
run: npx nx database:migrate twenty-website
|
||||||
env:
|
env:
|
||||||
DATABASE_PG_URL: postgres://twenty:twenty@localhost:5432/default
|
DATABASE_PG_URL: postgres://postgres:twenty@localhost:5432/default
|
||||||
- name: Website / Build Website
|
- name: Website / Build Website
|
||||||
if: steps.changed-files.outputs.changed == 'true'
|
if: steps.changed-files.outputs.changed == 'true'
|
||||||
run: npx nx build twenty-website
|
run: npx nx build twenty-website
|
||||||
env:
|
env:
|
||||||
DATABASE_PG_URL: postgres://twenty:twenty@localhost:5432/default
|
DATABASE_PG_URL: postgres://postgres:twenty@localhost:5432/default
|
||||||
|
|
||||||
- name: Mark as VALID
|
- name: Mark as VALID
|
||||||
if: steps.changed-files.outputs.changed != 'true' # If no changes, mark as valid
|
if: steps.changed-files.outputs.changed != 'true' # If no changes, mark as valid
|
||||||
|
4
.vscode/twenty.code-workspace
vendored
4
.vscode/twenty.code-workspace
vendored
@ -24,10 +24,6 @@
|
|||||||
"name": "packages/twenty-emails",
|
"name": "packages/twenty-emails",
|
||||||
"path": "../packages/twenty-emails"
|
"path": "../packages/twenty-emails"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "packages/twenty-postgres",
|
|
||||||
"path": "../packages/twenty-postgres"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "packages/twenty-server",
|
"name": "packages/twenty-server",
|
||||||
"path": "../packages/twenty-server"
|
"path": "../packages/twenty-server"
|
||||||
|
22
Makefile
22
Makefile
@ -1,12 +1,20 @@
|
|||||||
postgres-on-docker:
|
postgres-on-docker:
|
||||||
docker run \
|
docker run -d \
|
||||||
--name twenty_postgres \
|
--name twenty_pg \
|
||||||
-e POSTGRES_USER=postgres \
|
-e PGUSER_SUPERUSER=postgres \
|
||||||
-e POSTGRES_PASSWORD=postgres \
|
-e PGPASSWORD_SUPERUSER=twenty \
|
||||||
-e POSTGRES_DB=default \
|
-e ALLOW_NOSSL=true \
|
||||||
-v twenty_db_data:/var/lib/postgresql/data \
|
-v twenty_db_data:/home/postgres/pgdata \
|
||||||
-p 5432:5432 \
|
-p 5432:5432 \
|
||||||
twentycrm/twenty-postgres:latest
|
twentycrm/twenty-postgres-spilo:latest
|
||||||
|
@echo "Waiting for PostgreSQL to be ready..."
|
||||||
|
@until PGPASSWORD=twenty psql -h localhost -p 5432 -U postgres -d postgres \
|
||||||
|
-c 'SELECT pg_is_in_recovery();' 2>/dev/null | grep -q 'f'; do \
|
||||||
|
sleep 1; \
|
||||||
|
done
|
||||||
|
PGPASSWORD=twenty psql -h localhost -p 5432 -U postgres -d postgres \
|
||||||
|
-c "CREATE DATABASE \"default\" WITH OWNER postgres;" \
|
||||||
|
-c "CREATE DATABASE \"test\" WITH OWNER postgres;"
|
||||||
|
|
||||||
redis-on-docker:
|
redis-on-docker:
|
||||||
docker run -d --name twenty_redis -p 6379:6379 redis/redis-stack-server:latest
|
docker run -d --name twenty_redis -p 6379:6379 redis/redis-stack-server:latest
|
@ -93,7 +93,7 @@ fi
|
|||||||
echo "# === Randomly generated secrets ===" >>.env
|
echo "# === Randomly generated secrets ===" >>.env
|
||||||
echo "APP_SECRET=$(openssl rand -base64 32)" >>.env
|
echo "APP_SECRET=$(openssl rand -base64 32)" >>.env
|
||||||
echo "" >>.env
|
echo "" >>.env
|
||||||
echo "POSTGRES_ADMIN_PASSWORD=$(openssl rand -base64 32)" >>.env
|
echo "PGPASSWORD_SUPERUSER=$(openssl rand -hex 16)" >>.env
|
||||||
|
|
||||||
echo -e "\t• .env configuration completed"
|
echo -e "\t• .env configuration completed"
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
TAG=latest
|
TAG=latest
|
||||||
|
|
||||||
# POSTGRES_ADMIN_PASSWORD=replace_me_with_a_strong_password
|
#PGUSER_SUPERUSER=postgres
|
||||||
|
#PGPASSWORD_SUPERUSER=replace_me_with_a_strong_password
|
||||||
|
|
||||||
PG_DATABASE_HOST=db:5432
|
PG_DATABASE_HOST=db:5432
|
||||||
REDIS_URL=redis://redis:6379
|
REDIS_URL=redis://redis:6379
|
||||||
|
@ -4,9 +4,6 @@ prod-build:
|
|||||||
prod-run:
|
prod-run:
|
||||||
@docker run -d -p 3000:3000 --name twenty twenty
|
@docker run -d -p 3000:3000 --name twenty twenty
|
||||||
|
|
||||||
prod-postgres-build:
|
|
||||||
@cd ../.. && docker build -f ./packages/twenty-docker/twenty-postgres/Dockerfile --tag twenty-postgres . && cd -
|
|
||||||
|
|
||||||
prod-postgres-run:
|
prod-postgres-run:
|
||||||
@docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres --name twenty-postgres twenty-postgres
|
@docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres --name twenty-postgres twenty-postgres
|
||||||
|
|
||||||
@ -15,11 +12,3 @@ prod-website-build:
|
|||||||
|
|
||||||
prod-website-run:
|
prod-website-run:
|
||||||
@docker run -d -p 3000:3000 --name twenty-website twenty-website
|
@docker run -d -p 3000:3000 --name twenty-website twenty-website
|
||||||
|
|
||||||
release-postgres:
|
|
||||||
@cd ../.. && docker buildx build \
|
|
||||||
--push \
|
|
||||||
--no-cache \
|
|
||||||
--platform linux/amd64,linux/arm64 \
|
|
||||||
-f ./packages/twenty-docker/twenty-postgres/Dockerfile -t twentycrm/twenty-postgres:$(version) -t twentycrm/twenty-postgres:latest . \
|
|
||||||
&& cd -
|
|
||||||
|
@ -22,10 +22,10 @@ services:
|
|||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
environment:
|
environment:
|
||||||
PORT: 3000
|
PORT: 3000
|
||||||
PG_DATABASE_URL: postgres://twenty:twenty@${PG_DATABASE_HOST}/default
|
PG_DATABASE_URL: postgres://${PGUSER_SUPERUSER:-postgres}:${PGPASSWORD_SUPERUSER:-twenty}@${PG_DATABASE_HOST:-db:5432}/default
|
||||||
SERVER_URL: ${SERVER_URL}
|
SERVER_URL: ${SERVER_URL}
|
||||||
FRONT_BASE_URL: ${FRONT_BASE_URL:-$SERVER_URL}
|
FRONT_BASE_URL: ${FRONT_BASE_URL:-$SERVER_URL}
|
||||||
REDIS_URL: ${REDIS_URL:-redis://localhost:6379}
|
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
|
||||||
|
|
||||||
ENABLE_DB_MIGRATIONS: "true"
|
ENABLE_DB_MIGRATIONS: "true"
|
||||||
|
|
||||||
@ -52,10 +52,10 @@ services:
|
|||||||
image: twentycrm/twenty:${TAG}
|
image: twentycrm/twenty:${TAG}
|
||||||
command: ["yarn", "worker:prod"]
|
command: ["yarn", "worker:prod"]
|
||||||
environment:
|
environment:
|
||||||
PG_DATABASE_URL: postgres://twenty:twenty@${PG_DATABASE_HOST}/default
|
PG_DATABASE_URL: postgres://${PGUSER_SUPERUSER:-postgres}:${PGPASSWORD_SUPERUSER:-twenty}@${PG_DATABASE_HOST:-db:5432}/default
|
||||||
SERVER_URL: ${SERVER_URL}
|
SERVER_URL: ${SERVER_URL}
|
||||||
FRONT_BASE_URL: ${FRONT_BASE_URL:-$SERVER_URL}
|
FRONT_BASE_URL: ${FRONT_BASE_URL:-$SERVER_URL}
|
||||||
REDIS_URL: ${REDIS_URL:-redis://localhost:6379}
|
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
|
||||||
|
|
||||||
ENABLE_DB_MIGRATIONS: "false" # it already runs on the server
|
ENABLE_DB_MIGRATIONS: "false" # it already runs on the server
|
||||||
|
|
||||||
@ -73,13 +73,16 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: twentycrm/twenty-postgres:${TAG}
|
image: twentycrm/twenty-postgres-spilo:${TAG}
|
||||||
volumes:
|
volumes:
|
||||||
- db-data:/bitnami/postgresql
|
- db-data:/home/postgres/pgdata
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_ADMIN_PASSWORD}
|
PGUSER_SUPERUSER: ${PGUSER_SUPERUSER:-postgres}
|
||||||
|
PGPASSWORD_SUPERUSER: ${PGPASSWORD_SUPERUSER:-twenty}
|
||||||
|
ALLOW_NOSSL: "true"
|
||||||
|
SPILO_PROVIDER: "local"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: pg_isready -U twenty -d default
|
test: pg_isready -U ${PGUSER_SUPERUSER:-postgres} -h localhost -d postgres
|
||||||
interval: 5s
|
interval: 5s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 10
|
retries: 10
|
||||||
|
@ -30,10 +30,10 @@ spec:
|
|||||||
image: twentycrm/twenty-postgres:latest
|
image: twentycrm/twenty-postgres:latest
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
env:
|
env:
|
||||||
- name: POSTGRES_PASSWORD
|
- name: PGUSER_SUPERUSER
|
||||||
|
value: "postgres"
|
||||||
|
- name: PGPASSWORD_SUPERUSER
|
||||||
value: "twenty"
|
value: "twenty"
|
||||||
- name: BITNAMI_DEBUG
|
|
||||||
value: "true"
|
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 5432
|
- containerPort: 5432
|
||||||
name: tcp
|
name: tcp
|
||||||
@ -48,7 +48,7 @@ spec:
|
|||||||
stdin: true
|
stdin: true
|
||||||
tty: true
|
tty: true
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /bitnami/postgresql
|
- mountPath: /home/postgres/pgdata
|
||||||
name: twentycrm-db-data
|
name: twentycrm-db-data
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
restartPolicy: Always
|
restartPolicy: Always
|
||||||
|
@ -40,7 +40,7 @@ spec:
|
|||||||
- name: FRONT_BASE_URL
|
- name: FRONT_BASE_URL
|
||||||
value: "https://crm.example.com:443"
|
value: "https://crm.example.com:443"
|
||||||
- name: "PG_DATABASE_URL"
|
- name: "PG_DATABASE_URL"
|
||||||
value: "postgres://twenty:twenty@twenty-db.twentycrm.svc.cluster.local/default"
|
value: "postgres://postgres:twenty@twenty-db.twentycrm.svc.cluster.local/default"
|
||||||
- name: "REDIS_URL"
|
- name: "REDIS_URL"
|
||||||
value: "redis://twentycrm-redis.twentycrm.svc.cluster.local:6379"
|
value: "redis://twentycrm-redis.twentycrm.svc.cluster.local:6379"
|
||||||
- name: ENABLE_DB_MIGRATIONS
|
- name: ENABLE_DB_MIGRATIONS
|
||||||
|
@ -31,7 +31,7 @@ spec:
|
|||||||
- name: FRONT_BASE_URL
|
- name: FRONT_BASE_URL
|
||||||
value: "https://crm.example.com:443"
|
value: "https://crm.example.com:443"
|
||||||
- name: PG_DATABASE_URL
|
- name: PG_DATABASE_URL
|
||||||
value: "postgres://twenty:twenty@twenty-db.twentycrm.svc.cluster.local/default"
|
value: "postgres://postgres:twenty@twenty-db.twentycrm.svc.cluster.local/default"
|
||||||
- name: ENABLE_DB_MIGRATIONS
|
- name: ENABLE_DB_MIGRATIONS
|
||||||
value: "false" # it already runs on the server
|
value: "false" # it already runs on the server
|
||||||
- name: STORAGE_TYPE
|
- name: STORAGE_TYPE
|
||||||
|
@ -51,7 +51,7 @@ To make configuration changes to how this doc is generated, see `./.terraform-do
|
|||||||
| <a name="input_twentycrm_app_hostname"></a> [twentycrm\_app\_hostname](#input\_twentycrm\_app\_hostname) | The protocol, DNS fully qualified hostname, and port used to access TwentyCRM in your environment. Ex: https://crm.example.com:443 | `string` | n/a | yes |
|
| <a name="input_twentycrm_app_hostname"></a> [twentycrm\_app\_hostname](#input\_twentycrm\_app\_hostname) | The protocol, DNS fully qualified hostname, and port used to access TwentyCRM in your environment. Ex: https://crm.example.com:443 | `string` | n/a | yes |
|
||||||
| <a name="input_twentycrm_pgdb_admin_password"></a> [twentycrm\_pgdb\_admin\_password](#input\_twentycrm\_pgdb\_admin\_password) | TwentyCRM password for postgres database. | `string` | n/a | yes |
|
| <a name="input_twentycrm_pgdb_admin_password"></a> [twentycrm\_pgdb\_admin\_password](#input\_twentycrm\_pgdb\_admin\_password) | TwentyCRM password for postgres database. | `string` | n/a | yes |
|
||||||
| <a name="input_twentycrm_app_name"></a> [twentycrm\_app\_name](#input\_twentycrm\_app\_name) | A friendly name prefix to use for every component deployed. | `string` | `"twentycrm"` | no |
|
| <a name="input_twentycrm_app_name"></a> [twentycrm\_app\_name](#input\_twentycrm\_app\_name) | A friendly name prefix to use for every component deployed. | `string` | `"twentycrm"` | no |
|
||||||
| <a name="input_twentycrm_db_image"></a> [twentycrm\_db\_image](#input\_twentycrm\_db\_image) | TwentyCRM image for database deployment. This defaults to latest. | `string` | `"twentycrm/twenty-postgres:latest"` | no |
|
| <a name="input_twentycrm_db_image"></a> [twentycrm\_db\_image](#input\_twentycrm\_db\_image) | TwentyCRM image for database deployment. This defaults to latest. | `string` | `"twentycrm/twenty-postgres-spilo:latest"` | no |
|
||||||
| <a name="input_twentycrm_db_pv_capacity"></a> [twentycrm\_db\_pv\_capacity](#input\_twentycrm\_db\_pv\_capacity) | Storage capacity provisioned for database persistent volume. | `string` | `"10Gi"` | no |
|
| <a name="input_twentycrm_db_pv_capacity"></a> [twentycrm\_db\_pv\_capacity](#input\_twentycrm\_db\_pv\_capacity) | Storage capacity provisioned for database persistent volume. | `string` | `"10Gi"` | no |
|
||||||
| <a name="input_twentycrm_db_pv_path"></a> [twentycrm\_db\_pv\_path](#input\_twentycrm\_db\_pv\_path) | Local path to use to store the physical volume if using local storage on nodes. | `string` | `""` | no |
|
| <a name="input_twentycrm_db_pv_path"></a> [twentycrm\_db\_pv\_path](#input\_twentycrm\_db\_pv\_path) | Local path to use to store the physical volume if using local storage on nodes. | `string` | `""` | no |
|
||||||
| <a name="input_twentycrm_db_pvc_requests"></a> [twentycrm\_db\_pvc\_requests](#input\_twentycrm\_db\_pvc\_requests) | Storage capacity reservation for database persistent volume claim. | `string` | `"10Gi"` | no |
|
| <a name="input_twentycrm_db_pvc_requests"></a> [twentycrm\_db\_pvc\_requests](#input\_twentycrm\_db\_pvc\_requests) | Storage capacity reservation for database persistent volume claim. | `string` | `"10Gi"` | no |
|
||||||
|
@ -29,7 +29,7 @@ variable "twentycrm_server_image" {
|
|||||||
|
|
||||||
variable "twentycrm_db_image" {
|
variable "twentycrm_db_image" {
|
||||||
type = string
|
type = string
|
||||||
default = "twentycrm/twenty-postgres:latest"
|
default = "twentycrm/twenty-postgres-spilo:latest"
|
||||||
description = "TwentyCRM image for database deployment. This defaults to latest."
|
description = "TwentyCRM image for database deployment. This defaults to latest."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,10 @@ ARG SPILO_VERSION=3.2-p1
|
|||||||
ARG WRAPPERS_VERSION=0.2.0
|
ARG WRAPPERS_VERSION=0.2.0
|
||||||
|
|
||||||
# Build the mysql_fdw extension
|
# Build the mysql_fdw extension
|
||||||
FROM debian:bookworm as build-mysql_fdw
|
FROM debian:bookworm AS build-mysql_fdw
|
||||||
ARG POSTGRES_VERSION
|
ARG POSTGRES_VERSION
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
RUN apt update && \
|
RUN apt update && \
|
||||||
apt install -y \
|
apt install -y \
|
||||||
build-essential \
|
build-essential \
|
||||||
@ -17,14 +17,14 @@ RUN apt update && \
|
|||||||
|
|
||||||
# Install mysql_fdw
|
# Install mysql_fdw
|
||||||
RUN git clone https://github.com/EnterpriseDB/mysql_fdw.git
|
RUN git clone https://github.com/EnterpriseDB/mysql_fdw.git
|
||||||
WORKDIR mysql_fdw
|
WORKDIR /mysql_fdw
|
||||||
RUN make USE_PGXS=1
|
RUN make USE_PGXS=1
|
||||||
|
|
||||||
|
|
||||||
# Build libssl for wrappers
|
# Build libssl for wrappers
|
||||||
FROM ubuntu:22.04 as build-libssl
|
FROM ubuntu:22.04 AS build-libssl
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
RUN apt update && \
|
RUN apt update && \
|
||||||
apt install -y \
|
apt install -y \
|
||||||
build-essential \
|
build-essential \
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
ARG IMAGE_TAG='15.5.0-debian-11-r15'
|
|
||||||
|
|
||||||
FROM bitnami/postgresql:${IMAGE_TAG}
|
|
||||||
|
|
||||||
ARG PG_MAIN_VERSION=15
|
|
||||||
ARG WRAPPERS_VERSION=0.2.0
|
|
||||||
ARG TARGETARCH
|
|
||||||
|
|
||||||
USER root
|
|
||||||
|
|
||||||
RUN set -eux; \
|
|
||||||
ARCH="$(dpkg --print-architecture)"; \
|
|
||||||
case "${ARCH}" in \
|
|
||||||
aarch64|arm64) \
|
|
||||||
TARGETARCH='arm64'; \
|
|
||||||
;; \
|
|
||||||
amd64|x86_64) \
|
|
||||||
TARGETARCH='amd64'; \
|
|
||||||
;; \
|
|
||||||
*) \
|
|
||||||
echo "Unsupported arch: ${ARCH}"; \
|
|
||||||
exit 1; \
|
|
||||||
;; \
|
|
||||||
esac;
|
|
||||||
|
|
||||||
RUN apt update && apt install build-essential git curl default-libmysqlclient-dev -y
|
|
||||||
|
|
||||||
# Install precompiled supabase wrappers extensions
|
|
||||||
RUN curl -L "https://github.com/supabase/wrappers/releases/download/v${WRAPPERS_VERSION}/wrappers-v${WRAPPERS_VERSION}-pg${PG_MAIN_VERSION}-${TARGETARCH}-linux-gnu.deb" -o wrappers.deb
|
|
||||||
RUN dpkg --install wrappers.deb
|
|
||||||
RUN cp /usr/share/postgresql/${PG_MAIN_VERSION}/extension/wrappers* /opt/bitnami/postgresql/share/extension/
|
|
||||||
RUN cp /usr/lib/postgresql/${PG_MAIN_VERSION}/lib/wrappers* /opt/bitnami/postgresql/lib/
|
|
||||||
|
|
||||||
RUN export PATH=/usr/local/pgsql/bin/:$PATH
|
|
||||||
RUN export PATH=/usr/local/mysql/bin/:$PATH
|
|
||||||
RUN git clone https://github.com/EnterpriseDB/mysql_fdw.git
|
|
||||||
WORKDIR mysql_fdw
|
|
||||||
RUN make USE_PGXS=1
|
|
||||||
RUN make USE_PGXS=1 install
|
|
||||||
|
|
||||||
COPY ./packages/twenty-docker/twenty-postgres/init.sql /docker-entrypoint-initdb.d/
|
|
||||||
|
|
||||||
USER 1001
|
|
||||||
ENTRYPOINT ["/opt/bitnami/scripts/postgresql/entrypoint.sh"]
|
|
||||||
CMD ["/opt/bitnami/scripts/postgresql/run.sh"]
|
|
@ -1,4 +0,0 @@
|
|||||||
CREATE DATABASE "default";
|
|
||||||
CREATE DATABASE "test";
|
|
||||||
CREATE USER twenty PASSWORD 'twenty';
|
|
||||||
ALTER ROLE twenty superuser;
|
|
@ -52,9 +52,10 @@ RUN apk add --no-cache curl jq
|
|||||||
|
|
||||||
RUN npm install -g tsx
|
RUN npm install -g tsx
|
||||||
|
|
||||||
|
RUN apk add --no-cache postgresql-client
|
||||||
|
|
||||||
COPY ./packages/twenty-docker/twenty/entrypoint.sh /app/entrypoint.sh
|
COPY ./packages/twenty-docker/twenty/entrypoint.sh /app/entrypoint.sh
|
||||||
RUN chmod +x /app/entrypoint.sh
|
RUN chmod +x /app/entrypoint.sh
|
||||||
|
|
||||||
WORKDIR /app/packages/twenty-server
|
WORKDIR /app/packages/twenty-server
|
||||||
|
|
||||||
ARG REACT_APP_SERVER_BASE_URL
|
ARG REACT_APP_SERVER_BASE_URL
|
||||||
|
@ -4,6 +4,14 @@
|
|||||||
if [ "${ENABLE_DB_MIGRATIONS}" = "true" ] && [ ! -f /app/docker-data/db_status ]; then
|
if [ "${ENABLE_DB_MIGRATIONS}" = "true" ] && [ ! -f /app/docker-data/db_status ]; then
|
||||||
echo "Running database setup and migrations..."
|
echo "Running database setup and migrations..."
|
||||||
|
|
||||||
|
# Creating the database if it doesn't exist
|
||||||
|
PGUSER=$(echo $PG_DATABASE_URL | awk -F '//' '{print $2}' | awk -F ':' '{print $1}')
|
||||||
|
PGPASS=$(echo $PG_DATABASE_URL | awk -F ':' '{print $3}' | awk -F '@' '{print $1}')
|
||||||
|
PGHOST=$(echo $PG_DATABASE_URL | awk -F '@' '{print $2}' | awk -F ':' '{print $1}')
|
||||||
|
PGPORT=$(echo $PG_DATABASE_URL | awk -F ':' '{print $4}' | awk -F '/' '{print $1}')
|
||||||
|
PGPASSWORD=${PGPASS} psql -h ${PGHOST} -p ${PGPORT} -U ${PGUSER} -d postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'default'" | grep -q 1 || \
|
||||||
|
PGPASSWORD=${PGPASS} psql -h ${PGHOST} -p ${PGPORT} -U ${PGUSER} -d postgres -c "CREATE DATABASE \"default\""
|
||||||
|
|
||||||
# Run setup and migration scripts
|
# Run setup and migration scripts
|
||||||
NODE_OPTIONS="--max-old-space-size=1500" tsx ./scripts/setup-db.ts
|
NODE_OPTIONS="--max-old-space-size=1500" tsx ./scripts/setup-db.ts
|
||||||
yarn database:migrate:prod
|
yarn database:migrate:prod
|
||||||
|
@ -3,7 +3,7 @@ import path from 'path';
|
|||||||
|
|
||||||
export const envVariables = (variables: string) => {
|
export const envVariables = (variables: string) => {
|
||||||
let payload = `
|
let payload = `
|
||||||
PG_DATABASE_URL=postgres://twenty:twenty@localhost:5432/default
|
PG_DATABASE_URL=postgres://postgres:twenty@localhost:5432/default
|
||||||
FRONT_BASE_URL=http://localhost:3001
|
FRONT_BASE_URL=http://localhost:3001
|
||||||
ACCESS_TOKEN_SECRET=replace_me_with_a_random_string_access
|
ACCESS_TOKEN_SECRET=replace_me_with_a_random_string_access
|
||||||
LOGIN_TOKEN_SECRET=replace_me_with_a_random_string_login
|
LOGIN_TOKEN_SECRET=replace_me_with_a_random_string_login
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Use this for local setup
|
# Use this for local setup
|
||||||
PG_DATABASE_URL=postgres://twenty:twenty@localhost:5432/default
|
PG_DATABASE_URL=postgres://postgres:twenty@localhost:5432/default
|
||||||
REDIS_URL=redis://localhost:6379
|
REDIS_URL=redis://localhost:6379
|
||||||
|
|
||||||
FRONT_BASE_URL=http://localhost:3001
|
FRONT_BASE_URL=http://localhost:3001
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
PG_DATABASE_URL=postgres://twenty:twenty@localhost:5432/test
|
PG_DATABASE_URL=postgres://postgres:twenty@localhost:5432/test
|
||||||
REDIS_URL=redis://localhost:6379
|
REDIS_URL=redis://localhost:6379
|
||||||
|
|
||||||
DEBUG_MODE=true
|
DEBUG_MODE=true
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
export PG_DATABASE_URL=postgres://twenty:twenty@$PG_DATABASE_HOST:$PG_DATABASE_PORT/default
|
export PG_DATABASE_URL=postgres://postgres:twenty@$PG_DATABASE_HOST:$PG_DATABASE_PORT/default
|
||||||
yarn database:init:prod
|
yarn database:init:prod
|
||||||
node dist/src/main
|
node dist/src/main
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
export PG_DATABASE_URL=postgres://twenty:twenty@$PG_DATABASE_HOST:$PG_DATABASE_PORT/default
|
export PG_DATABASE_URL=postgres://postgres:twenty@$PG_DATABASE_HOST:$PG_DATABASE_PORT/default
|
||||||
node dist/src/queue-worker/queue-worker
|
node dist/src/queue-worker/queue-worker
|
||||||
|
@ -7,6 +7,11 @@ import { camelToSnakeCase, performQuery } from './utils';
|
|||||||
rawDataSource
|
rawDataSource
|
||||||
.initialize()
|
.initialize()
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
|
await performQuery(
|
||||||
|
'CREATE EXTENSION IF NOT EXISTS "vector"',
|
||||||
|
'create extension "vector (pgvector)"',
|
||||||
|
);
|
||||||
|
|
||||||
await performQuery(
|
await performQuery(
|
||||||
'CREATE SCHEMA IF NOT EXISTS "public"',
|
'CREATE SCHEMA IF NOT EXISTS "public"',
|
||||||
'create schema "public"',
|
'create schema "public"',
|
||||||
@ -53,7 +58,7 @@ rawDataSource
|
|||||||
for (const wrapper of supabaseWrappers) {
|
for (const wrapper of supabaseWrappers) {
|
||||||
await performQuery(
|
await performQuery(
|
||||||
`
|
`
|
||||||
CREATE FOREIGN DATA WRAPPER "${wrapper.toLowerCase()}_fdw"
|
CREATE FOREIGN DATA WRAPPER IF NOT EXISTS "${wrapper.toLowerCase()}_fdw"
|
||||||
HANDLER "${camelToSnakeCase(wrapper)}_fdw_handler"
|
HANDLER "${camelToSnakeCase(wrapper)}_fdw_handler"
|
||||||
VALIDATOR "${camelToSnakeCase(wrapper)}_fdw_validator";
|
VALIDATOR "${camelToSnakeCase(wrapper)}_fdw_validator";
|
||||||
`,
|
`,
|
||||||
|
@ -21,6 +21,14 @@ async function dropSchemasSequentially() {
|
|||||||
// Iterate over each schema and drop it
|
// Iterate over each schema and drop it
|
||||||
// This is to avoid dropping all schemas at once, which would cause an out of shared memory error
|
// This is to avoid dropping all schemas at once, which would cause an out of shared memory error
|
||||||
for (const schema of schemas) {
|
for (const schema of schemas) {
|
||||||
|
if (
|
||||||
|
schema.schema_name === 'metric_helpers' ||
|
||||||
|
schema.schema_name === 'user_management' ||
|
||||||
|
schema.schema_name === 'public'
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
await performQuery(
|
await performQuery(
|
||||||
`
|
`
|
||||||
DROP SCHEMA IF EXISTS "${schema.schema_name}" CASCADE;
|
DROP SCHEMA IF EXISTS "${schema.schema_name}" CASCADE;
|
||||||
|
@ -392,7 +392,7 @@ resource "azurerm_container_app" "twenty_db" {
|
|||||||
max_replicas = 1
|
max_replicas = 1
|
||||||
container {
|
container {
|
||||||
name = local.db_app_name
|
name = local.db_app_name
|
||||||
image = "docker.io/twentycrm/twenty-postgres:${local.db_tag}"
|
image = "docker.io/twentycrm/twenty-postgres-spilo:${local.db_tag}"
|
||||||
cpu = local.cpu
|
cpu = local.cpu
|
||||||
memory = local.memory
|
memory = local.memory
|
||||||
|
|
||||||
@ -402,16 +402,12 @@ resource "azurerm_container_app" "twenty_db" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
env {
|
env {
|
||||||
name = "POSTGRES_USER"
|
name = "PGUSER_SUPERUSER"
|
||||||
value = "postgres"
|
value = "postgres"
|
||||||
}
|
}
|
||||||
env {
|
env {
|
||||||
name = "POSTGRES_PASSWORD"
|
name = "PGPASSWORD_SUPERUSER"
|
||||||
value = "postgres"
|
value = "twenty"
|
||||||
}
|
|
||||||
env {
|
|
||||||
name = "POSTGRES_DB"
|
|
||||||
value = "default"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,10 +66,10 @@ Follow these steps for a manual setup.
|
|||||||
|
|
||||||
4. **Set the Postgres Password**
|
4. **Set the Postgres Password**
|
||||||
|
|
||||||
Update the `POSTGRES_ADMIN_PASSWORD` value in the .env file with a strong password.
|
Update the `PGPASSWORD_SUPERUSER` value in the .env file with a strong password.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
POSTGRES_ADMIN_PASSWORD=my_strong_password
|
PGPASSWORD_SUPERUSER=my_strong_password
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Obtain the Docker Compose File
|
### Step 2: Obtain the Docker Compose File
|
||||||
|
@ -81,5 +81,3 @@ services:
|
|||||||
value: postgres
|
value: postgres
|
||||||
- key: POSTGRES_PASSWORD
|
- key: POSTGRES_PASSWORD
|
||||||
value: postgres
|
value: postgres
|
||||||
- key: POSTGRES_DB
|
|
||||||
value: default
|
|
||||||
|
Loading…
Reference in New Issue
Block a user