twenty and dify

This commit is contained in:
serban-alexandru
2024-07-26 17:00:47 +03:00
parent 5f0672aaf1
commit 03e9670915
56 changed files with 3198 additions and 1 deletions
+4
View File
@@ -0,0 +1,4 @@
# Twenty
- copied from https://github.com/twentyhq/twenty
- removed `ports`
+25
View File
@@ -0,0 +1,25 @@
TAG=latest
# POSTGRES_ADMIN_PASSWORD=replace_me_with_a_strong_password
PG_DATABASE_HOST=db:5432
SERVER_URL=http://localhost:3000
# Uncoment if you are serving your front on another server than the API (eg. bucket)
# FRONT_BASE_URL=http://localhost:3000
# Use openssl rand -base64 32 for each secret
# ACCESS_TOKEN_SECRET=replace_me_with_a_random_string_access
# LOGIN_TOKEN_SECRET=replace_me_with_a_random_string_login
# REFRESH_TOKEN_SECRET=replace_me_with_a_random_string_refresh
# FILE_TOKEN_SECRET=replace_me_with_a_random_string_refresh
SIGN_IN_PREFILLED=true
STORAGE_TYPE=local
# STORAGE_S3_REGION=eu-west3
# STORAGE_S3_NAME=my-bucket
# STORAGE_S3_ENDPOINT=
MESSAGE_QUEUE_TYPE=pg-boss
+50
View File
@@ -0,0 +1,50 @@
dev-build:
@docker compose -f dev/docker-compose.yml down -v
@docker compose -f dev/docker-compose.yml build
dev-up:
@docker compose -f dev/docker-compose.yml up -d
dev-start:
@docker compose -f dev/docker-compose.yml start
dev-stop:
@docker compose -f dev/docker-compose.yml stop
dev-down:
@docker compose -f dev/docker-compose.yml down -v
dev-sh:
@docker compose -f dev/docker-compose.yml exec twenty-dev sh
dev-postgres-build:
@docker stop twenty_postgres || true
@docker rm twenty_postgres || true
@docker volume rm twenty_db_data || true
@docker compose -f dev/docker-compose.yml up --build postgres -d
prod-build:
@cd ../.. && docker build -f ./packages/twenty-docker/twenty/Dockerfile --tag twenty . && cd -
prod-run:
@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:
@docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres --name twenty-postgres twenty-postgres
prod-website-build:
@cd ../.. && docker build -f ./packages/twenty-docker/twenty-website/Dockerfile --tag twenty-website . && cd -
prod-website-run:
@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 -
+93
View File
@@ -0,0 +1,93 @@
version: "3.9"
name: twenty
services:
change-vol-ownership:
image: ubuntu
user: root
volumes:
- server-local-data:/tmp/server-local-data
- docker-data:/tmp/docker-data
command: >
bash -c "
chown -R 1000:1000 /tmp/server-local-data
&& chown -R 1000:1000 /tmp/docker-data"
server:
image: twentycrm/twenty:${TAG}
volumes:
- server-local-data:/app/packages/twenty-server/${STORAGE_LOCAL_PATH:-.local-storage}
- docker-data:/app/docker-data
environment:
PORT: 3000
PG_DATABASE_URL: postgres://twenty:twenty@${PG_DATABASE_HOST}/default
SERVER_URL: ${SERVER_URL}
FRONT_BASE_URL: ${FRONT_BASE_URL:-$SERVER_URL}
MESSAGE_QUEUE_TYPE: ${MESSAGE_QUEUE_TYPE}
ENABLE_DB_MIGRATIONS: "true"
SIGN_IN_PREFILLED: ${SIGN_IN_PREFILLED}
STORAGE_TYPE: ${STORAGE_TYPE}
STORAGE_S3_REGION: ${STORAGE_S3_REGION}
STORAGE_S3_NAME: ${STORAGE_S3_NAME}
STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT}
ACCESS_TOKEN_SECRET: ${ACCESS_TOKEN_SECRET}
LOGIN_TOKEN_SECRET: ${LOGIN_TOKEN_SECRET}
REFRESH_TOKEN_SECRET: ${REFRESH_TOKEN_SECRET}
FILE_TOKEN_SECRET: ${FILE_TOKEN_SECRET}
depends_on:
change-vol-ownership:
condition: service_completed_successfully
db:
condition: service_healthy
healthcheck:
test: curl --fail http://localhost:3000/healthz
interval: 5s
timeout: 5s
retries: 10
restart: always
worker:
image: twentycrm/twenty:${TAG}
command: ["yarn", "worker:prod"]
environment:
PG_DATABASE_URL: postgres://twenty:twenty@${PG_DATABASE_HOST}/default
SERVER_URL: ${SERVER_URL}
FRONT_BASE_URL: ${FRONT_BASE_URL:-$SERVER_URL}
MESSAGE_QUEUE_TYPE: ${MESSAGE_QUEUE_TYPE}
ENABLE_DB_MIGRATIONS: "false" # it already runs on the server
STORAGE_TYPE: ${STORAGE_TYPE}
STORAGE_S3_REGION: ${STORAGE_S3_REGION}
STORAGE_S3_NAME: ${STORAGE_S3_NAME}
STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT}
ACCESS_TOKEN_SECRET: ${ACCESS_TOKEN_SECRET}
LOGIN_TOKEN_SECRET: ${LOGIN_TOKEN_SECRET}
REFRESH_TOKEN_SECRET: ${REFRESH_TOKEN_SECRET}
FILE_TOKEN_SECRET: ${FILE_TOKEN_SECRET}
depends_on:
db:
condition: service_healthy
server:
condition: service_healthy
restart: always
db:
image: twentycrm/twenty-postgres:${TAG}
volumes:
- db-data:/bitnami/postgresql
environment:
POSTGRES_PASSWORD: ${POSTGRES_ADMIN_PASSWORD}
healthcheck:
test: pg_isready -U twenty -d default
interval: 5s
timeout: 5s
retries: 10
restart: always
volumes:
docker-data:
db-data:
server-local-data:
+113
View File
@@ -0,0 +1,113 @@
# README
## Overview
This repository contains Kubernetes manifests and Terraform files to help you deploy and manage the TwentyCRM application. The files are located in the `packages/twenty-docker/k8s` directory.
## Prerequisites
Before using these files, ensure you have the following installed and configured on your system:
- Kubernetes cluster (e.g., Minikube, EKS, GKE)
- kubectl
- Terraform
- Docker
## Setup Instructions
### Step 1: Clone the Repository
Clone the repository to your local machine:
``` bash
git clone https://github.com/twentyhq/twenty.git
cd twentycrm/packages/twenty-docker/k8s
```
### Step 2: Customize the Manifests and Terraform Files
**Important:** These files require customization for your specific implementation. Update the placeholders and configurations according to your environment and requirements.
### Step 3: Deploy with Terraform
1. Navigate to the Terraform directory:
```bash
cd terraform
```
2. Initialize Terraform:
```bash
terraform init
```
3. Plan the deployment:
```bash
terraform plan
```
4. Apply the deployment:
```bash
terraform apply
```
## OR
### Step 3: Deploy with Kubernetes Manifests
1. Navigate to the Kubernetes manifests directory:
```bash
cd ../k8s
```
2. Create Server Secret
``` bash
kubectl create secret generic -n twentycrm tokens --from-literal accessToken=changeme --from-literal loginToken="changeme" --from-literal refreshToken="changeme" --from-literal fileToken="changeme"
```
3. Apply the manifests:
```bash
kubectl apply -f .
```
## Customization
### Kubernetes Manifests
- **Namespace:** Update the `namespace` in the manifests as needed.
- **Resource Limits:** Adjust the resource limits and requests according to your application's requirements.
- **Environment Variables:** Configure server tokens in the `Secret` command above.
### Terraform Files
- **Variables:** Update the variables in the `variables.tf` file to match your environment.
- **Locals:** Update the locals in the `main.tf` file to match your environment.
- **Providers:** Ensure the provider configurations (e.g., AWS, GCP) are correct for your setup.
- **Resources:** Modify the resource definitions as needed to fit your infrastructure.
## Troubleshooting
### Common Issues
- **Connectivity:** Ensure your Kubernetes cluster is accessible and configured correctly.
- **Permissions:** Verify that you have the necessary permissions to deploy resources in your cloud provider.
- **Resource Limits:** Adjust resource limits if you encounter issues related to insufficient resources.
### Logs and Debugging
- Use `kubectl logs` to check the logs of your Kubernetes pods.
- Use `terraform show` and `terraform state` to inspect your Terraform state and configurations.
## Conclusion
This setup provides a basic structure for deploying the TwentyCRM application using Kubernetes and Terraform. Ensure you thoroughly customize the manifests and Terraform files to suit your specific needs. For any issues or questions, please refer to the official documentation of Kubernetes and Terraform or seek support from your cloud provider.
---
Feel free to contribute and improve this repository by submitting pull requests or opening issues. Happy deploying!
@@ -0,0 +1,54 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: twentycrm-db
name: twentycrm-db
namespace: twentycrm
spec:
progressDeadlineSeconds: 600
replicas: 1
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
selector:
matchLabels:
app: twentycrm-db
template:
metadata:
labels:
app: twentycrm-db
spec:
volumes:
- name: twentycrm-db-data
persistentVolumeClaim:
claimName: twentycrm-db-pvc
containers:
- env:
- name: POSTGRES_PASSWORD
value: "twenty"
- name: BITNAMI_DEBUG
value: "true"
- image: twentycrm/twenty-postgres:latest
imagePullPolicy: Always
name: twentycrm
ports:
- containerPort: 5432
name: tcp
protocol: TCP
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1024Mi"
cpu: "1000m"
stdin: true
tty: true
volumeMounts:
- mountPath: /bitnami/postgresql
name: twentycrm-db-data
dnsPolicy: ClusterFirst
restartPolicy: Always
@@ -0,0 +1,82 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: twentycrm-server
name: twentycrm-server
namespace: twentycrm
spec:
progressDeadlineSeconds: 600
replicas: 1
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
selector:
matchLabels:
app: twentycrm-server
template:
metadata:
labels:
app: twentycrm-server
spec:
volumes:
- name: twentycrm-server-data
persistentVolumeClaim:
claimName: twentycrm-server-pvc
containers:
- env:
- name: PORT
value: 3000
- name: SERVER_URL
value: "https://crm.example.com:443"
- name: PG_DATABASE_URL
value: "postgres://twenty:twenty@twenty-db.twentycrm.svc.cluster.local/default"
- name: ENABLE_DB_MIGRATIONS
value: "true"
- name: SIGN_IN_PREFILLED
value: "true"
- name: STORAGE_TYPE
value: "local"
- name: ACCESS_TOKEN_SECRET
valueFrom:
secretKeyRef:
name: tokens
key: accessToken
- name: LOGIN_TOKEN_SECRET
valueFrom:
secretKeyRef:
name: tokens
key: loginToken
- name: REFRESH_TOKEN_SECRET
valueFrom:
secretKeyRef:
name: tokens
key: refreshToken
- name: FILE_TOKEN_SECRET
valueFrom:
secretKeyRef:
name: tokens
key: fileToken
- image: twentycrm/twenty:latest
imagePullPolicy: Always
name: twentycrm
ports:
- containerPort: 3000
name: http-tcp
protocol: TCP
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1024Mi"
cpu: "1000m"
stdin: true
tty: true
volumeMounts:
- mountPath: /app/.local-storage
name: twentycrm-server-data
dnsPolicy: ClusterFirst
restartPolicy: Always
+24
View File
@@ -0,0 +1,24 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: twentycrm
namespace: twentycrm
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Forwarded-For $http_x_forwarded_for";
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
rules:
- host: crm.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: twentycrm-server
port:
name: http-tcp
+11
View File
@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: twentycrm-db-pv
spec:
storageClassName: default
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
+12
View File
@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: twentycrm-server-pv
namespace: twentycrm
spec:
storageClassName: default
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
+13
View File
@@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: twentycrm-db-pvc
namespace: twentycrm
spec:
storageClassName: default
volumeName: twentycrm-db-pv
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
+13
View File
@@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: twentycrm-server-pvc
namespace: twentycrm
spec:
storageClassName: default
volumeName: twentycrm-server-pv
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
+18
View File
@@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: twentycrm-db
namespace: twentycrm
spec:
internalTrafficPolicy: Cluster
ports:
- port: 5432
protocol: TCP
targetPort: 5432
selector:
app: twentycrm-db
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
type: ClusterIP
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: twentycrm-server
namespace: twentycrm
spec:
internalTrafficPolicy: Cluster
ports:
- name: http-tcp
port: 3000
protocol: TCP
targetPort: 3000
selector:
app: twentycrm-server
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
type: ClusterIP
@@ -0,0 +1,90 @@
resource "kubernetes_deployment" "twentycrm_db" {
metadata {
name = "${local.twentycrm_app_name}-db"
namespace = kubernetes_namespace.twentycrm.metadata.0.name
labels = {
app = "${local.twentycrm_app_name}-db"
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "${local.twentycrm_app_name}-db"
}
}
strategy {
type = "RollingUpdate"
rolling_update {
max_surge = "1"
max_unavailable = "1"
}
}
template {
metadata {
labels = {
app = "${local.twentycrm_app_name}-db"
}
}
spec {
# security_context {
# fs_group = 0
# }
container {
image = local.twentycrm_db_image
name = local.twentycrm_app_name
stdin = true
tty = true
security_context {
allow_privilege_escalation = true
}
env {
name = "POSTGRES_PASSWORD"
value = "twenty"
}
env {
name = "BITNAMI_DEBUG"
value = true
}
port {
container_port = 5432
protocol = "TCP"
}
resources {
requests = {
cpu = "250m"
memory = "256Mi"
}
limits = {
cpu = "1000m"
memory = "1024Mi"
}
}
volume_mount {
name = "nfs-twentycrm-db-data"
mount_path = "/bitnami/postgresql"
}
}
volume {
name = "nfs-twentycrm-db-data"
persistent_volume_claim {
claim_name = "nfs-twentycrm-db-data-pvc"
}
}
dns_policy = "ClusterFirst"
restart_policy = "Always"
}
}
}
}
@@ -0,0 +1,169 @@
resource "kubernetes_deployment" "twentycrm_server" {
metadata {
name = "${local.twentycrm_app_name}-server"
namespace = kubernetes_namespace.twentycrm.metadata.0.name
labels = {
app = "${local.twentycrm_app_name}-server"
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "${local.twentycrm_app_name}-server"
}
}
strategy {
type = "RollingUpdate"
rolling_update {
max_surge = "1"
max_unavailable = "1"
}
}
template {
metadata {
labels = {
app = "${local.twentycrm_app_name}-server"
}
}
spec {
container {
image = local.twentycrm_server_image
name = local.twentycrm_app_name
stdin = true
tty = true
security_context {
allow_privilege_escalation = true
privileged = true
run_as_user = 1000
}
env {
name = "PORT"
value = "3000"
}
env {
name = "DEBUG_MODE"
value = false
}
env {
name = "SERVER_URL"
value = "https://crm.example.com:443"
}
env {
name = "FRONT_BASE_URL"
value = "https://crm.example.com:443"
}
env {
name = "BACKEND_SERVER_URL"
value = "https://crm.example.com:443"
}
env {
name = "PG_DATABASE_URL"
value = "postgres://twenty:twenty@twentycrm-db.twentycrm.svc.cluster.local/default"
}
env {
name = "ENABLE_DB_MIGRATIONS"
value = "true"
}
env {
name = "SIGN_IN_PREFILLED"
value = "true"
}
env {
name = "STORAGE_TYPE"
value = "local"
}
env {
name = "ACCESS_TOKEN_SECRET"
value_from {
secret_key_ref {
name = "tokens"
key = "accessToken"
}
}
}
env {
name = "LOGIN_TOKEN_SECRET"
value_from {
secret_key_ref {
name = "tokens"
key = "loginToken"
}
}
}
env {
name = "REFRESH_TOKEN_SECRET"
value_from {
secret_key_ref {
name = "tokens"
key = "refreshToken"
}
}
}
env {
name = "FILE_TOKEN_SECRET"
value_from {
secret_key_ref {
name = "tokens"
key = "fileToken"
}
}
}
port {
container_port = 3000
protocol = "TCP"
}
resources {
requests = {
cpu = "250m"
memory = "256Mi"
}
limits = {
cpu = "1000m"
memory = "1024Mi"
}
}
volume_mount {
name = "nfs-twentycrm-server-data"
mount_path = "/app/.local-storage"
}
}
volume {
name = "nfs-twentycrm-server-data"
persistent_volume_claim {
claim_name = "nfs-twentycrm-server-data-pvc"
}
}
dns_policy = "ClusterFirst"
restart_policy = "Always"
}
}
}
depends_on = [
kubernetes_deployment.twentycrm_db,
kubernetes_secret.twentycrm_tokens
]
}
+30
View File
@@ -0,0 +1,30 @@
resource "kubernetes_ingress" "twentycrm" {
wait_for_load_balancer = true
metadata {
name = "${local.twentycrm_app_name}-ingress"
namespace = kubernetes_namespace.twentycrm.metadata.0.name
annotations = {
"kubernetes.io/ingress.class" = "nginx"
"nginx.ingress.kubernetes.io/configuration-snippet" = <<EOF
more_set_headers "X-Forwarded-For $http_x_forwarded_for";
EOF
"nginx.ingress.kubernetes.io/force-ssl-redirect" = "false"
"nginx.ingress.kubernetes.io/backend-protocol" = "HTTP"
}
}
spec {
ingress_class_name = "nginx"
rule {
host = local.twentycrm_app_hostname
http {
path {
path = "/*"
backend {
service_name = kubernetes_service.twentycrm_server.metadata.0.name
service_port = kubernetes_service.twentycrm_server.spec.0.port.0.port
}
}
}
}
}
}
+36
View File
@@ -0,0 +1,36 @@
#############
# Providers #
#############
provider "kubernetes" {
config_path = "~/.kube/config"
}
#################
# Global Locals #
#################
locals {
twentycrm_app_name = "twentycrm"
twentycrm_app_hostname = "crm.example.com"
twentycrm_server_image = "twentycrm/twenty:v0.10.4"
twentycrm_db_image = "twentycrm/twenty-postgres:v0.10.4"
twentycrm_db_pv_path = "/path/to/mystorage"
twentycrm_db_pv_capacity = "10Gi"
twentycrm_db_pvc_requests = "10Gi"
twentycrm_server_pv_path = "/path/to/mystorage"
twentycrm_server_pv_capacity = "10Gi"
twentycrm_server_pvc_requests = "10Gi"
}
####################
# Terraform Config #
####################
terraform {
required_version = ">= 1.7.4"
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.23.0"
}
}
}
+9
View File
@@ -0,0 +1,9 @@
resource "kubernetes_namespace" "twentycrm" {
metadata {
annotations = {
name = "twentycrm"
}
name = "twentycrm"
}
}
+19
View File
@@ -0,0 +1,19 @@
resource "kubernetes_persistent_volume" "db" {
metadata {
name = "${local.twentycrm_app_name}-db-pv"
}
spec {
storage_class_name = "default"
capacity = {
storage = local.twentycrm_db_pv_capacity
}
access_modes = ["ReadWriteOnce"]
# refer to Terraform Docs for your specific implementation requirements
# https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume
persistent_volume_source {
local {
path = local.twentycrm_db_pv_path
}
}
}
}
+19
View File
@@ -0,0 +1,19 @@
resource "kubernetes_persistent_volume" "server" {
metadata {
name = "${local.twentycrm_app_name}-server-pv"
}
spec {
storage_class_name = "default"
capacity = {
storage = local.twentycrm_server_pv_capacity
}
access_modes = ["ReadWriteOnce"]
# refer to Terraform Docs for your specific implementation requirements
# https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume
persistent_volume_source {
local {
path = local.twentycrm_server_pv_path
}
}
}
}
+15
View File
@@ -0,0 +1,15 @@
resource "kubernetes_persistent_volume_claim" "db" {
metadata {
name = "${local.twentycrm_app_name}-db-pvc"
namespace = kubernetes_namespace.twentycrm.metadata.0.name
}
spec {
access_modes = ["ReadWriteOnce"]
resources {
requests = {
storage = local.twentycrm_db_pvc_requests
}
}
volume_name = kubernetes_persistent_volume.db.metadata.0.name
}
}
+15
View File
@@ -0,0 +1,15 @@
resource "kubernetes_persistent_volume_claim" "server" {
metadata {
name = "${local.twentycrm_app_name}-server-pvc"
namespace = kubernetes_namespace.twentycrm.metadata.0.name
}
spec {
access_modes = ["ReadWriteOnce"]
resources {
requests = {
storage = local.twentycrm_server_pvc_requests
}
}
volume_name = kubernetes_persistent_volume.server.metadata.0.name
}
}
+15
View File
@@ -0,0 +1,15 @@
resource "kubernetes_secret" "twentycrm_tokens" {
metadata {
name = "tokens"
namespace = kubernetes_namespace.twentycrm.metadata.0.name
}
data = {
accessToken = var.twentycrm_token_accessToken
loginToken = var.twentycrm_token_loginToken
refreshToken = var.twentycrm_token_refreshToken
fileToken = var.twentycrm_token_fileToken
}
# type = "kubernetes.io/basic-auth"
}
+18
View File
@@ -0,0 +1,18 @@
resource "kubernetes_service" "twentycrm_db" {
metadata {
name = "${local.twentycrm_app_name}-db"
namespace = kubernetes_namespace.twentycrm.metadata.0.name
}
spec {
selector = {
app = "${local.twentycrm_app_name}-db"
}
session_affinity = "ClientIP"
port {
port = 5432
target_port = 5432
}
type = "ClusterIP"
}
}
@@ -0,0 +1,19 @@
resource "kubernetes_service" "twentycrm_server" {
metadata {
name = "${local.twentycrm_app_name}-server"
namespace = kubernetes_namespace.twentycrm.metadata.0.name
}
spec {
selector = {
app = "${local.twentycrm_app_name}-server"
}
session_affinity = "ClientIP"
port {
name = "http-tcp"
port = 3000
target_port = 3000
}
type = "ClusterIP"
}
}
+24
View File
@@ -0,0 +1,24 @@
variable "twentycrm_token_accessToken" {
type = string
description = "TwentyCRM access Token"
}
variable "twentycrm_token_loginToken" {
type = string
description = "TwentyCRM login Token"
}
variable "twentycrm_token_refreshToken" {
type = string
description = "TwentyCRM refresh Token"
}
variable "twentycrm_token_fileToken" {
type = string
description = "TwentyCRM file Token"
}
variable "twentycrm_pgdb_admin_password" {
type = string
description = "TwentyCRM password for postgres database"
}
@@ -0,0 +1,78 @@
ARG POSTGRES_VERSION=15
ARG SPILO_VERSION=3.2-p1
ARG PG_GRAPHQL_VERSION=1.5.6
ARG WRAPPERS_VERSION=0.2.0
# Build the mysql_fdw extension
FROM debian:bookworm as build-mysql_fdw
ARG POSTGRES_VERSION
ENV DEBIAN_FRONTEND noninteractive
RUN apt update && \
apt install -y \
build-essential \
git \
postgresql-server-dev-${POSTGRES_VERSION} \
default-libmysqlclient-dev && \
rm -rf /var/lib/apt/lists/*
# Install mysql_fdw
RUN git clone https://github.com/EnterpriseDB/mysql_fdw.git
WORKDIR mysql_fdw
RUN make USE_PGXS=1
# Build libssl for wrappers
FROM ubuntu:22.04 as build-libssl
ENV DEBIAN_FRONTEND noninteractive
RUN apt update && \
apt install -y \
build-essential \
git && \
rm -rf /var/lib/apt/lists/*
WORKDIR /build
RUN git clone --branch OpenSSL_1_1_1-stable https://github.com/openssl/openssl.git
WORKDIR /build/openssl
RUN ./config && make && make install
# Extend the Spilo image with the pg_graphql and mysql_fdw extensions
FROM ghcr.io/zalando/spilo-${POSTGRES_VERSION}:${SPILO_VERSION}
ARG POSTGRES_VERSION
ARG PG_GRAPHQL_VERSION
ARG WRAPPERS_VERSION
ARG TARGETARCH
# Install precompiled supabase wrappers extensions
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 default-libmysqlclient-dev -y && rm -rf /var/lib/apt/lists/*
RUN curl -L "https://github.com/supabase/wrappers/releases/download/v${WRAPPERS_VERSION}/wrappers-v${WRAPPERS_VERSION}-pg${POSTGRES_VERSION}-${TARGETARCH}-linux-gnu.deb" -o wrappers.deb && \
dpkg --install wrappers.deb && \
rm wrappers.deb
COPY --from=build-libssl /usr/local/lib/libssl* /usr/local/lib/libcrypto* /usr/lib/
COPY --from=build-libssl /usr/local/lib/engines-1.1 /usr/lib/engines-1.1
# Copy pg_graphql
COPY ./packages/twenty-postgres/linux/${TARGETARCH}/${POSTGRES_VERSION}/pg_graphql/${PG_GRAPHQL_VERSION}/pg_graphql--${PG_GRAPHQL_VERSION}.sql \
/usr/share/postgresql/${POSTGRES_VERSION}/extension
COPY ./packages/twenty-postgres/linux/${TARGETARCH}/${POSTGRES_VERSION}/pg_graphql/${PG_GRAPHQL_VERSION}/pg_graphql.control \
/usr/share/postgresql/${POSTGRES_VERSION}/extension
COPY ./packages/twenty-postgres/linux/${TARGETARCH}/${POSTGRES_VERSION}/pg_graphql/${PG_GRAPHQL_VERSION}/pg_graphql.so \
/usr/lib/postgresql/${POSTGRES_VERSION}/lib/pg_graphql.so
# Copy mysql_fdw
COPY --from=build-mysql_fdw /mysql_fdw/mysql_fdw.so \
/usr/lib/postgresql/${POSTGRES_VERSION}/lib/mysql_fdw.so
COPY --from=build-mysql_fdw /mysql_fdw/mysql_fdw*.sql /mysql_fdw/mysql_fdw.control /mysql_fdw/mysql_fdw_pushdown.config \
/usr/share/postgresql/${POSTGRES_VERSION}/extension/
+54
View File
@@ -0,0 +1,54 @@
ARG IMAGE_TAG='15.5.0-debian-11-r15'
FROM bitnami/postgresql:${IMAGE_TAG}
ARG PG_MAIN_VERSION=15
ARG PG_GRAPHQL_VERSION=1.5.6
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 pg_graphql extensions
COPY ./packages/twenty-postgres/linux/${TARGETARCH}/${PG_MAIN_VERSION}/pg_graphql/${PG_GRAPHQL_VERSION}/pg_graphql--${PG_GRAPHQL_VERSION}.sql \
/opt/bitnami/postgresql/share/extension/
COPY ./packages/twenty-postgres/linux/${TARGETARCH}/${PG_MAIN_VERSION}/pg_graphql/${PG_GRAPHQL_VERSION}/pg_graphql.control \
/opt/bitnami/postgresql/share/extension/
COPY ./packages/twenty-postgres/linux/${TARGETARCH}/${PG_MAIN_VERSION}/pg_graphql/${PG_GRAPHQL_VERSION}/pg_graphql.so \
/opt/bitnami/postgresql/lib/
# 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"]
+4
View File
@@ -0,0 +1,4 @@
CREATE DATABASE "default";
CREATE DATABASE "test";
CREATE USER twenty PASSWORD 'twenty';
ALTER ROLE twenty superuser;
+29
View File
@@ -0,0 +1,29 @@
FROM node:18.17.1-alpine as twenty-website-build
WORKDIR /app
COPY ./package.json .
COPY ./yarn.lock .
COPY ./.yarnrc.yml .
COPY ./.yarn/releases /app/.yarn/releases
COPY ./tools/eslint-rules /app/tools/eslint-rules
COPY ./packages/twenty-website/package.json /app/packages/twenty-website/package.json
RUN yarn
COPY ./packages/twenty-website /app/packages/twenty-website
RUN npx nx build twenty-website
FROM node:18.17.1-alpine as twenty-website
WORKDIR /app/packages/twenty-website
COPY --from=twenty-website-build /app /app
WORKDIR /app/packages/twenty-website
LABEL org.opencontainers.image.source=https://github.com/twentyhq/twenty
LABEL org.opencontainers.image.description="This image provides a consistent and reproducible environment for the website."
CMD ["/bin/sh", "-c", "npx nx start"]
+79
View File
@@ -0,0 +1,79 @@
# Base image for common dependencies
FROM node:18.17.1-alpine as common-deps
WORKDIR /app
# Copy only the necessary files for dependency resolution
COPY ./package.json ./yarn.lock ./.yarnrc.yml ./tsconfig.base.json ./nx.json /app/
COPY ./.yarn/releases /app/.yarn/releases
COPY ./packages/twenty-emails/package.json /app/packages/twenty-emails/
COPY ./packages/twenty-server/package.json /app/packages/twenty-server/
COPY ./packages/twenty-server/patches /app/packages/twenty-server/patches
COPY ./packages/twenty-ui/package.json /app/packages/twenty-ui/
COPY ./packages/twenty-front/package.json /app/packages/twenty-front/
# Install all dependencies
RUN yarn && yarn cache clean && npx nx reset
# Build the back
FROM common-deps as twenty-server-build
# Copy sourcecode after installing dependences to accelerate subsequents builds
COPY ./packages/twenty-emails /app/packages/twenty-emails
COPY ./packages/twenty-server /app/packages/twenty-server
RUN npx nx run twenty-server:build
RUN mv /app/packages/twenty-server/dist /app/packages/twenty-server/build
RUN npx nx run twenty-server:build:packageJson
RUN mv /app/packages/twenty-server/dist/package.json /app/packages/twenty-server/package.json
RUN rm -rf /app/packages/twenty-server/dist
RUN mv /app/packages/twenty-server/build /app/packages/twenty-server/dist
RUN yarn workspaces focus --production twenty-emails twenty-server
# Build the front
FROM common-deps as twenty-front-build
ARG REACT_APP_SERVER_BASE_URL
COPY ./packages/twenty-front /app/packages/twenty-front
COPY ./packages/twenty-ui /app/packages/twenty-ui
RUN npx nx build twenty-front
# Final stage: Run the application
FROM node:18.17.1-alpine as twenty
# Used to run healthcheck in docker
RUN apk add --no-cache curl jq
COPY ./packages/twenty-docker/twenty/entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh
WORKDIR /app/packages/twenty-server
ARG REACT_APP_SERVER_BASE_URL
ENV REACT_APP_SERVER_BASE_URL $REACT_APP_SERVER_BASE_URL
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE $SENTRY_RELEASE
# Copy built applications from previous stages
COPY --chown=1000 --from=twenty-server-build /app /app
COPY --chown=1000 --from=twenty-server-build /app/packages/twenty-server /app/packages/twenty-server
COPY --chown=1000 --from=twenty-front-build /app/packages/twenty-front/build /app/packages/twenty-server/dist/front
# Set metadata and labels
LABEL org.opencontainers.image.source=https://github.com/twentyhq/twenty
LABEL org.opencontainers.image.description="This image provides a consistent and reproducible environment for the backend and frontend, ensuring it deploys faster and runs the same way regardless of the deployment environment."
RUN mkdir /app/.local-storage
RUN chown -R 1000 /app
# Use non root user with uid 1000
USER 1000
CMD ["node", "dist/src/main"]
ENTRYPOINT ["/app/entrypoint.sh"]
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
# Check if the initialization has already been done and that we enabled automatic migration
if [ "${ENABLE_DB_MIGRATIONS}" = "true" ] && [ ! -f /app/docker-data/db_status ]; then
echo "Running database setup and migrations..."
# Run setup and migration scripts
NODE_OPTIONS="--max-old-space-size=1500" npx ts-node ./scripts/setup-db.ts
yarn database:migrate:prod
# Mark initialization as done
echo "Successfuly migrated DB!"
touch /app/docker-data/db_status
fi
# Continue with the original Docker command
exec "$@"
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
if [ ! -d "./repo" ]; then
git clone --depth 1 --branch main --single-branch git@github.com:twentyhq/twenty.git repo
else
cd repo
git pull
cd ..
fi
cp -r ./repo/packages/twenty-docker/. ./code