twenty/packages/twenty-docker/docker-compose.yml

135 lines
5.2 KiB
YAML
Raw Normal View History

name: twenty
services:
server:
image: twentycrm/twenty:${TAG:-latest}
volumes:
Refactor: Improve Docker volume permission handling and remove run-once service (#11405) **Problem:** The previous `docker-compose.yml` included a `change-vol-ownership` service. This service was designed to run once upon startup to `chown` the `server-local-data` and `docker-data` volumes to user/group `1000:1000`. This was necessary because: 1. The main `server` and `worker` containers run as the non-root user `1000` for security. 2. Docker typically creates/mounts named volumes initially owned by `root`. 3. The application needs write access to these volumes. However, this run-once service pattern causes problems in certain deployment environments (like Coolify) that don't gracefully handle services designed to exit after completing their task. This can lead to deployment failures or warnings. **Solution:** This PR refactors the Docker setup to address the volume permission issue directly within the Docker image build process, eliminating the need for the run-once service. **Changes:** 1. **`packages/twenty-docker/docker-compose.yml`:** * Removed the `change-vol-ownership` service definition entirely. * Removed the `depends_on: change-vol-ownership` condition from the `server` service definition. * **Proposed Change:** Removed the `${STORAGE_LOCAL_PATH}` environment variable from the `server-local-data` volume mounts for both `server` and `worker` services. The path is now hardcoded to `/app/packages/twenty-server/.local-storage`. (See Reasoning below). 2. **`packages/twenty-docker/twenty/Dockerfile`:** * In the final stage, *before* the `USER 1000` command, added lines to: * Create the necessary directories: `RUN mkdir -p /app/packages/twenty-server/.local-storage /app/docker-data` (and also `/app/.local-storage` for safety, though it's likely unused by volumes). * Set the correct ownership: `RUN chown -R 1000:1000 /app/.local-storage /app/packages/twenty-server/.local-storage /app/docker-data`. 3. **`packages/twenty-docker/twenty/entrypoint.sh`:** * Added a check near the beginning of the script for the presence of the now-potentially-unused `STORAGE_LOCAL_PATH` environment variable. * If the variable is set, a warning message is printed to standard output, informing the user that the variable might be deprecated and ignored if the hardcoded path change in `docker-compose.yml` is accepted. **Reasoning:** By creating the target directories (`/app/packages/twenty-server/.local-storage` and `/app/docker-data`) within the Docker image *and* setting their ownership to `1000:1000` during the build (while still running as root), we leverage Docker's volume initialization behavior. When a named volume is mounted to a non-empty directory in the container image, Docker copies the content and ownership from the image directory into the volume. This ensures that when the `server` and `worker` containers start (running as user `1000`), the volumes they mount already have the correct permissions, eliminating the need for the separate `change-vol-ownership` service. **Regarding `STORAGE_LOCAL_PATH`:** The `docker-compose.yml` previously allowed configuring the path for local storage via the `STORAGE_LOCAL_PATH` variable, defaulting to `.local-storage`. Since the Dockerfile now explicitly creates and sets permissions for `/app/packages/twenty-server/.local-storage`, maintaining this configuration might be unnecessary or could potentially lead to permission errors if a user sets it to a path *not* prepared in the Dockerfile. This PR proposes hardcoding the path in `docker-compose.yml` to `/app/packages/twenty-server/.local-storage` to align with the Dockerfile changes and simplify configuration. Is this acceptable, or is there a specific use case for retaining the `STORAGE_LOCAL_PATH` variable that needs to be considered? If retained, the Dockerfile would need further changes to dynamically handle permissions based on this variable. **Impact:** * Improves compatibility with deployment platforms that struggle with run-once containers. * Simplifies the `docker-compose.yml` setup (potentially, pending discussion on `STORAGE_LOCAL_PATH`). * Fixes volume permissions at the source (image build) rather than relying on a runtime fix. * Adds a warning for users who might have the potentially deprecated variable set. **Testing:** The changes have been tested locally using `docker compose up`. The services start correctly, the application is accessible, and the warning message for the potentially deprecated variable appears as expected when the variable is set. --------- Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-19 22:14:33 +00:00
- server-local-data:/app/packages/twenty-server/.local-storage
ports:
- "3000:3000"
environment:
NODE_PORT: 3000
PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default
SERVER_URL: ${SERVER_URL}
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
DISABLE_DB_MIGRATIONS: ${DISABLE_DB_MIGRATIONS}
DISABLE_CRON_JOBS_REGISTRATION: ${DISABLE_CRON_JOBS_REGISTRATION}
STORAGE_TYPE: ${STORAGE_TYPE}
STORAGE_S3_REGION: ${STORAGE_S3_REGION}
STORAGE_S3_NAME: ${STORAGE_S3_NAME}
STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT}
APP_SECRET: ${APP_SECRET:-replace_me_with_a_random_string}
# MESSAGING_PROVIDER_GMAIL_ENABLED: ${MESSAGING_PROVIDER_GMAIL_ENABLED}
# CALENDAR_PROVIDER_GOOGLE_ENABLED: ${CALENDAR_PROVIDER_GOOGLE_ENABLED}
# AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID}
# AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET}
# AUTH_GOOGLE_CALLBACK_URL: ${AUTH_GOOGLE_CALLBACK_URL}
# AUTH_GOOGLE_APIS_CALLBACK_URL: ${AUTH_GOOGLE_APIS_CALLBACK_URL}
# CALENDAR_PROVIDER_MICROSOFT_ENABLED: ${CALENDAR_PROVIDER_MICROSOFT_ENABLED}
# MESSAGING_PROVIDER_MICROSOFT_ENABLED: ${MESSAGING_PROVIDER_MICROSOFT_ENABLED}
# AUTH_MICROSOFT_ENABLED: ${AUTH_MICROSOFT_ENABLED}
# AUTH_MICROSOFT_CLIENT_ID: ${AUTH_MICROSOFT_CLIENT_ID}
# AUTH_MICROSOFT_CLIENT_SECRET: ${AUTH_MICROSOFT_CLIENT_SECRET}
# AUTH_MICROSOFT_CALLBACK_URL: ${AUTH_MICROSOFT_CALLBACK_URL}
# AUTH_MICROSOFT_APIS_CALLBACK_URL: ${AUTH_MICROSOFT_APIS_CALLBACK_URL}
# EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-contact@yourdomain.com}
# EMAIL_FROM_NAME: ${EMAIL_FROM_NAME:-"John from YourDomain"}
# EMAIL_DRIVER: ${EMAIL_DRIVER:-smtp}
# EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST:-smtp.gmail.com}
# EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT:-465}
# EMAIL_SMTP_USER: ${EMAIL_SMTP_USER:-}
# EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD:-}
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: curl --fail http://localhost:3000/healthz
interval: 5s
timeout: 5s
fix(docker-compose): increase retry for server service (#11883) ## Background I'm trying to self-host twenty using [official 1-Click w/ Docker Compose guide](https://twenty.com/developers/section/self-hosting/docker-compose) on AWS EC2 (using `t3.small` instance type). ## What happened I used the one-line script but it failed with ``` [skipped] server-1 | Successfuly migrated DB! dependency failed to start: container twenty-server-1 is unhealthy ``` Then I tried manual steps, and it failed again with same issue as above. No configuration changed, everything default used. I re-run manual steps multiple times with `docker compose down -v` and `docker compose up`, everything time it failed with `server` unhealthy as it seems server takes longer than configured health check duration (which is 50 seconds) Here's the `time` summary running it: ``` [skipped] server-1 | Successfuly migrated DB! dependency failed to start: container twenty-server-1 is unhealthy ________________________________________________________ Executed in 58.26 secs fish external usr time 661.43 millis 362.00 micros 661.07 millis sys time 646.10 millis 212.00 micros 645.89 millis root@ip-10-0-10-43 ~/twenty [1]# ``` ## Why it happend My hunch (new to twenty, just used it yesterday) is that server service takes much longer to become healthy with DB migration and etc, that configured health check retries is not sufficient. ## What solution worked Increased the retry for server service from 10 to 20, and it worked and service came up healthy (everytime). The increase wasn't needed for db or worker service, just server service. If this all makes sense, please feel free to merge this, so it'll be smoother experience for others new to self-hosting twenty.
2025-05-19 22:04:38 +00:00
retries: 20
restart: always
worker:
image: twentycrm/twenty:${TAG:-latest}
volumes:
Fix inconsistent volume path in docker-compose.yml (#12479) *Title:* Align volume mount path for `server-local-data` in `docker-compose.yml` **Description:** This pull request resolves a configuration inconsistency in the `docker-compose.yml` file related to the `server-local-data` volume used by the `server` and `worker` services. ### Background The `server` and `worker` services are both configured to use a shared volume named `server-local-data`. However, the volume mount paths differ: * The `server` service uses a hardcoded mount path: ```yaml - server-local-data:/app/packages/twenty-server/.local-storage ``` * The `worker` service uses a path that supports an environment variable override: ```yaml - server-local-data:/app/packages/twenty-server/${STORAGE_LOCAL_PATH:-.local-storage} ``` This discrepancy can result in the two services referencing different filesystem locations, especially when `STORAGE_LOCAL_PATH` is set. This may lead to runtime errors or unexpected behavior when accessing local storage. ### Proposed Change This PR standardizes the volume mount path in the `worker` service to use the same environment variable-based path as the `server` service: ```yaml - server-local-data:/app/packages/twenty-server/.local-storage ``` ### Rationale * Ensures consistent and predictable volume mount behavior across services. * Prevents potential data inconsistencies or access issues arising from differing mount points. ### Impact * No breaking changes expected if `STORAGE_LOCAL_PATH` is not defined. * Services will now operate on the same volume path, whether or not the environment variable is set.
2025-06-16 14:04:21 +00:00
- server-local-data:/app/packages/twenty-server/.local-storage
command: ["yarn", "worker:prod"]
environment:
PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default
SERVER_URL: ${SERVER_URL}
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
DISABLE_DB_MIGRATIONS: "true" # it already runs on the server
DISABLE_CRON_JOBS_REGISTRATION: "true" # 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}
APP_SECRET: ${APP_SECRET:-replace_me_with_a_random_string}
# MESSAGING_PROVIDER_GMAIL_ENABLED: ${MESSAGING_PROVIDER_GMAIL_ENABLED}
# CALENDAR_PROVIDER_GOOGLE_ENABLED: ${CALENDAR_PROVIDER_GOOGLE_ENABLED}
# AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID}
# AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET}
# AUTH_GOOGLE_CALLBACK_URL: ${AUTH_GOOGLE_CALLBACK_URL}
# AUTH_GOOGLE_APIS_CALLBACK_URL: ${AUTH_GOOGLE_APIS_CALLBACK_URL}
# CALENDAR_PROVIDER_MICROSOFT_ENABLED: ${CALENDAR_PROVIDER_MICROSOFT_ENABLED}
# MESSAGING_PROVIDER_MICROSOFT_ENABLED: ${MESSAGING_PROVIDER_MICROSOFT_ENABLED}
# AUTH_MICROSOFT_ENABLED: ${AUTH_MICROSOFT_ENABLED}
# AUTH_MICROSOFT_CLIENT_ID: ${AUTH_MICROSOFT_CLIENT_ID}
# AUTH_MICROSOFT_CLIENT_SECRET: ${AUTH_MICROSOFT_CLIENT_SECRET}
# AUTH_MICROSOFT_CALLBACK_URL: ${AUTH_MICROSOFT_CALLBACK_URL}
# AUTH_MICROSOFT_APIS_CALLBACK_URL: ${AUTH_MICROSOFT_APIS_CALLBACK_URL}
# EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-contact@yourdomain.com}
# EMAIL_FROM_NAME: ${EMAIL_FROM_NAME:-"John from YourDomain"}
# EMAIL_DRIVER: ${EMAIL_DRIVER:-smtp}
# EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST:-smtp.gmail.com}
# EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT:-465}
# EMAIL_SMTP_USER: ${EMAIL_SMTP_USER:-}
# EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD:-}
Refactor: Improve Docker volume permission handling and remove run-once service (#11405) **Problem:** The previous `docker-compose.yml` included a `change-vol-ownership` service. This service was designed to run once upon startup to `chown` the `server-local-data` and `docker-data` volumes to user/group `1000:1000`. This was necessary because: 1. The main `server` and `worker` containers run as the non-root user `1000` for security. 2. Docker typically creates/mounts named volumes initially owned by `root`. 3. The application needs write access to these volumes. However, this run-once service pattern causes problems in certain deployment environments (like Coolify) that don't gracefully handle services designed to exit after completing their task. This can lead to deployment failures or warnings. **Solution:** This PR refactors the Docker setup to address the volume permission issue directly within the Docker image build process, eliminating the need for the run-once service. **Changes:** 1. **`packages/twenty-docker/docker-compose.yml`:** * Removed the `change-vol-ownership` service definition entirely. * Removed the `depends_on: change-vol-ownership` condition from the `server` service definition. * **Proposed Change:** Removed the `${STORAGE_LOCAL_PATH}` environment variable from the `server-local-data` volume mounts for both `server` and `worker` services. The path is now hardcoded to `/app/packages/twenty-server/.local-storage`. (See Reasoning below). 2. **`packages/twenty-docker/twenty/Dockerfile`:** * In the final stage, *before* the `USER 1000` command, added lines to: * Create the necessary directories: `RUN mkdir -p /app/packages/twenty-server/.local-storage /app/docker-data` (and also `/app/.local-storage` for safety, though it's likely unused by volumes). * Set the correct ownership: `RUN chown -R 1000:1000 /app/.local-storage /app/packages/twenty-server/.local-storage /app/docker-data`. 3. **`packages/twenty-docker/twenty/entrypoint.sh`:** * Added a check near the beginning of the script for the presence of the now-potentially-unused `STORAGE_LOCAL_PATH` environment variable. * If the variable is set, a warning message is printed to standard output, informing the user that the variable might be deprecated and ignored if the hardcoded path change in `docker-compose.yml` is accepted. **Reasoning:** By creating the target directories (`/app/packages/twenty-server/.local-storage` and `/app/docker-data`) within the Docker image *and* setting their ownership to `1000:1000` during the build (while still running as root), we leverage Docker's volume initialization behavior. When a named volume is mounted to a non-empty directory in the container image, Docker copies the content and ownership from the image directory into the volume. This ensures that when the `server` and `worker` containers start (running as user `1000`), the volumes they mount already have the correct permissions, eliminating the need for the separate `change-vol-ownership` service. **Regarding `STORAGE_LOCAL_PATH`:** The `docker-compose.yml` previously allowed configuring the path for local storage via the `STORAGE_LOCAL_PATH` variable, defaulting to `.local-storage`. Since the Dockerfile now explicitly creates and sets permissions for `/app/packages/twenty-server/.local-storage`, maintaining this configuration might be unnecessary or could potentially lead to permission errors if a user sets it to a path *not* prepared in the Dockerfile. This PR proposes hardcoding the path in `docker-compose.yml` to `/app/packages/twenty-server/.local-storage` to align with the Dockerfile changes and simplify configuration. Is this acceptable, or is there a specific use case for retaining the `STORAGE_LOCAL_PATH` variable that needs to be considered? If retained, the Dockerfile would need further changes to dynamically handle permissions based on this variable. **Impact:** * Improves compatibility with deployment platforms that struggle with run-once containers. * Simplifies the `docker-compose.yml` setup (potentially, pending discussion on `STORAGE_LOCAL_PATH`). * Fixes volume permissions at the source (image build) rather than relying on a runtime fix. * Adds a warning for users who might have the potentially deprecated variable set. **Testing:** The changes have been tested locally using `docker compose up`. The services start correctly, the application is accessible, and the warning message for the potentially deprecated variable appears as expected when the variable is set. --------- Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-19 22:14:33 +00:00
depends_on:
db:
condition: service_healthy
server:
condition: service_healthy
restart: always
db:
image: postgres:16
volumes:
- db-data:/var/lib/postgresql/data
environment:
POSTGRES_DB: ${PG_DATABASE_NAME:-default}
POSTGRES_PASSWORD: ${PG_DATABASE_PASSWORD:-postgres}
POSTGRES_USER: ${PG_DATABASE_USER:-postgres}
healthcheck:
test: pg_isready -U ${PG_DATABASE_USER:-postgres} -h localhost -d postgres
interval: 5s
timeout: 5s
retries: 10
restart: always
redis:
image: redis
restart: always
command: ["--maxmemory-policy", "noeviction"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 10
volumes:
db-data:
server-local-data: