refactor: update paths and structure for server services in Docker and documentation (#7333)

- Changed references from 'apiserver' to 'apps/server' in Docker configurations and environment setup.
- Updated contributing documentation to reflect the new service structure.
- Adjusted setup script to accommodate the new directory layout.
- Removed obsolete files related to the previous structure.
This commit is contained in:
Nikhil 2025-07-03 18:42:14 +05:30 committed by GitHub
parent 1de95ef0d0
commit 805cfed1a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 105 additions and 94 deletions

View file

@ -6,7 +6,7 @@ on:
types: ["opened", "synchronize", "ready_for_review"] types: ["opened", "synchronize", "ready_for_review"]
jobs: jobs:
lint-apiserver: lint-server:
if: github.event.pull_request.draft == false if: github.event.pull_request.draft == false
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -17,10 +17,10 @@ jobs:
python-version: "3.x" # Specify the Python version you need python-version: "3.x" # Specify the Python version you need
- name: Install Pylint - name: Install Pylint
run: python -m pip install ruff run: python -m pip install ruff
- name: Install Apiserver Dependencies - name: Install Server Dependencies
run: cd apiserver && pip install -r requirements.txt run: cd apps/server && pip install -r requirements.txt
- name: Lint apiserver - name: Lint apps/server
run: ruff check --fix apiserver run: ruff check --fix apps/server
lint-admin: lint-admin:
if: github.event.pull_request.draft == false if: github.event.pull_request.draft == false

View file

@ -25,6 +25,7 @@ When opening a new issue, please use a clear and concise title that follows this
- For documentation: `📘 Docs: [short description]` - For documentation: `📘 Docs: [short description]`
**Examples:** **Examples:**
- `🐛 Bug: API token expiry time not saving correctly` - `🐛 Bug: API token expiry time not saving correctly`
- `📘 Docs: Clarify RAM requirement for local setup` - `📘 Docs: Clarify RAM requirement for local setup`
- `🚀 Feature: Allow custom time selection for token expiration` - `🚀 Feature: Allow custom time selection for token expiration`
@ -47,7 +48,7 @@ This helps us triage and manage issues more efficiently.
The project is a monorepo, with backend api and frontend in a single repo. The project is a monorepo, with backend api and frontend in a single repo.
The backend is a django project which is kept inside apiserver The backend is a django project which is kept inside apps/server
1. Clone the repo 1. Clone the repo
@ -105,11 +106,13 @@ To ensure consistency throughout the source code, please keep these rules in min
- **Improve documentation** - fix incomplete or missing [docs](https://docs.plane.so/), bad wording, examples or explanations. - **Improve documentation** - fix incomplete or missing [docs](https://docs.plane.so/), bad wording, examples or explanations.
## Contributing to language support ## Contributing to language support
This guide is designed to help contributors understand how to add or update translations in the application. This guide is designed to help contributors understand how to add or update translations in the application.
### Understanding translation structure ### Understanding translation structure
#### File organization #### File organization
Translations are organized by language in the locales directory. Each language has its own folder containing JSON files for translations. Here's how it looks: Translations are organized by language in the locales directory. Each language has its own folder containing JSON files for translations. Here's how it looks:
``` ```
@ -122,7 +125,9 @@ packages/i18n/src/locales/
└── [language]/ └── [language]/
└── translations.json └── translations.json
``` ```
#### Nested structure #### Nested structure
To keep translations organized, we use a nested structure for keys. This makes it easier to manage and locate specific translations. For example: To keep translations organized, we use a nested structure for keys. This makes it easier to manage and locate specific translations. For example:
```json ```json
@ -137,32 +142,37 @@ To keep translations organized, we use a nested structure for keys. This makes i
``` ```
### Translation formatting guide ### Translation formatting guide
We use [IntlMessageFormat](https://formatjs.github.io/docs/intl-messageformat/) to handle dynamic content, such as variables and pluralization. Here's how to format your translations: We use [IntlMessageFormat](https://formatjs.github.io/docs/intl-messageformat/) to handle dynamic content, such as variables and pluralization. Here's how to format your translations:
#### Examples #### Examples
- **Simple variables** - **Simple variables**
```json
{ ```json
{
"greeting": "Hello, {name}!" "greeting": "Hello, {name}!"
} }
``` ```
- **Pluralization** - **Pluralization**
```json ```json
{ {
"items": "{count, plural, one {Work item} other {Work items}}" "items": "{count, plural, one {Work item} other {Work items}}"
} }
``` ```
### Contributing guidelines ### Contributing guidelines
#### Updating existing translations #### Updating existing translations
1. Locate the key in `locales/<language>/translations.json`. 1. Locate the key in `locales/<language>/translations.json`.
2. Update the value while ensuring the key structure remains intact. 2. Update the value while ensuring the key structure remains intact.
3. Preserve any existing ICU formats (e.g., variables, pluralization). 3. Preserve any existing ICU formats (e.g., variables, pluralization).
#### Adding new translation keys #### Adding new translation keys
1. When introducing a new key, ensure it is added to **all** language files, even if translations are not immediately available. Use English as a placeholder if needed. 1. When introducing a new key, ensure it is added to **all** language files, even if translations are not immediately available. Use English as a placeholder if needed.
2. Keep the nesting structure consistent across all languages. 2. Keep the nesting structure consistent across all languages.
@ -170,48 +180,50 @@ We use [IntlMessageFormat](https://formatjs.github.io/docs/intl-messageformat/)
3. If the new key requires dynamic content (e.g., variables or pluralization), ensure the ICU format is applied uniformly across all languages. 3. If the new key requires dynamic content (e.g., variables or pluralization), ensure the ICU format is applied uniformly across all languages.
### Adding new languages ### Adding new languages
Adding a new language involves several steps to ensure it integrates seamlessly with the project. Follow these instructions carefully: Adding a new language involves several steps to ensure it integrates seamlessly with the project. Follow these instructions carefully:
1. **Update type definitions** 1. **Update type definitions**
Add the new language to the TLanguage type in the language definitions file: Add the new language to the TLanguage type in the language definitions file:
```typescript ```typescript
// types/language.ts // types/language.ts
export type TLanguage = "en" | "fr" | "your-lang"; export type TLanguage = "en" | "fr" | "your-lang";
``` ```
2. **Add language configuration** 2. **Add language configuration**
Include the new language in the list of supported languages: Include the new language in the list of supported languages:
```typescript ```typescript
// constants/language.ts // constants/language.ts
export const SUPPORTED_LANGUAGES: ILanguageOption[] = [ export const SUPPORTED_LANGUAGES: ILanguageOption[] = [
{ label: "English", value: "en" }, { label: "English", value: "en" },
{ label: "Your Language", value: "your-lang" } { label: "Your Language", value: "your-lang" }
]; ];
``` ```
3. **Create translation files** 3. **Create translation files**
1. Create a new folder for your language under locales (e.g., `locales/your-lang/`). 1. Create a new folder for your language under locales (e.g., `locales/your-lang/`).
2. Add a `translations.json` file inside the folder. 2. Add a `translations.json` file inside the folder.
3. Copy the structure from an existing translation file and translate all keys. 3. Copy the structure from an existing translation file and translate all keys.
4. **Update import logic** 4. **Update import logic**
Modify the language import logic to include your new language: Modify the language import logic to include your new language:
```typescript ```typescript
private importLanguageFile(language: TLanguage): Promise<any> { private importLanguageFile(language: TLanguage): Promise<any> {
switch (language) { switch (language) {
case "your-lang": case "your-lang":
return import("../locales/your-lang/translations.json"); return import("../locales/your-lang/translations.json");
// ... // ...
} }
} }
``` ```
### Quality checklist ### Quality checklist
Before submitting your contribution, please ensure the following: Before submitting your contribution, please ensure the following:
- All translation keys exist in every language file. - All translation keys exist in every language file.
@ -222,6 +234,7 @@ Before submitting your contribution, please ensure the following:
- There are no missing or untranslated keys. - There are no missing or untranslated keys.
#### Pro tips #### Pro tips
- When in doubt, refer to the English translations for context. - When in doubt, refer to the English translations for context.
- Verify pluralization works with different numbers. - Verify pluralization works with different numbers.
- Ensure dynamic values (e.g., `{name}`) are correctly interpolated. - Ensure dynamic values (e.g., `{name}`) are correctly interpolated.

View file

@ -36,7 +36,7 @@ USE_MINIO=1
NGINX_PORT=80 NGINX_PORT=80
``` ```
## {PROJECT_FOLDER}/apiserver/.env ## {PROJECT_FOLDER}/apps/server/.env
``` ```
# Backend # Backend
@ -63,8 +63,6 @@ AWS_S3_ENDPOINT_URL="http://plane-minio:9000"
AWS_S3_BUCKET_NAME="uploads" AWS_S3_BUCKET_NAME="uploads"
# Maximum file upload limit # Maximum file upload limit
FILE_SIZE_LIMIT=5242880 FILE_SIZE_LIMIT=5242880
# Settings related to Docker
DOCKERIZED=1 # deprecated
# set to 1 If using the pre-configured minio setup # set to 1 If using the pre-configured minio setup
USE_MINIO=1 USE_MINIO=1
# Nginx Configuration # Nginx Configuration
@ -78,11 +76,15 @@ ADMIN_BASE_URL=
SPACE_BASE_URL= SPACE_BASE_URL=
APP_BASE_URL= APP_BASE_URL=
SECRET_KEY="gxoytl7dmnc1y37zahah820z5iq3iozu38cnfjtu3yaau9cd9z" SECRET_KEY="gxoytl7dmnc1y37zahah820z5iq3iozu38cnfjtu3yaau9cd9z"
# RabbitMQ Settings
RABBITMQ_HOST="plane-mq"
RABBITMQ_PORT="5672"
RABBITMQ_USER="plane"
RABBITMQ_PASSWORD="plane"
RABBITMQ_VHOST="plane"
AMQP_URL=""
# Authentication Settings
ENABLE_SIGNUP=1
ENABLE_EMAIL_PASSWORD=1
ENABLE_MAGIC_LINK_LOGIN=0
``` ```
## Updates
- The naming convention for containers and images has been updated.
- The plane-worker image will no longer be maintained, as it has been merged with plane-backend.
- The Tiptap pro-extension dependency has been removed, eliminating the need for Tiptap API keys.
- The image name for Plane deployment has been changed to plane-space.

View file

@ -70,18 +70,18 @@ ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1 ENV PYTHONUNBUFFERED=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1 ENV PIP_DISABLE_PIP_VERSION_CHECK=1
COPY apiserver/requirements.txt ./api/ COPY apps/server/requirements.txt ./api/
COPY apiserver/requirements ./api/requirements COPY apps/server/requirements ./api/requirements
RUN pip install -r ./api/requirements.txt --compile --no-cache-dir RUN pip install -r ./api/requirements.txt --compile --no-cache-dir
# Add in Django deps and generate Django's static files # Add in Django deps and generate Django's static files
COPY apiserver/manage.py ./api/manage.py COPY apps/server/manage.py ./api/manage.py
COPY apiserver/plane ./api/plane/ COPY apps/server/plane ./api/plane/
COPY apiserver/templates ./api/templates/ COPY apps/server/templates ./api/templates/
COPY package.json ./api/package.json COPY package.json ./api/package.json
COPY apiserver/bin ./api/bin/ COPY apps/server/bin ./api/bin/
RUN chmod +x ./api/bin/* RUN chmod +x ./api/bin/*
RUN chmod -R 777 ./api/ RUN chmod -R 777 ./api/

View file

@ -1,3 +0,0 @@
web: gunicorn -w 4 -k uvicorn.workers.UvicornWorker plane.asgi:application --bind 0.0.0.0:$PORT --max-requests 10000 --max-requests-jitter 1000 --access-logfile -
worker: celery -A plane worker -l info
beat: celery -A plane beat -l INFO

View file

@ -1 +0,0 @@
python-3.12.6

View file

@ -20,7 +20,7 @@ services:
api: api:
image: ${DOCKERHUB_USER:-local}/plane-backend:${APP_RELEASE:-latest} image: ${DOCKERHUB_USER:-local}/plane-backend:${APP_RELEASE:-latest}
build: build:
context: ./apiserver context: ./apps/server
dockerfile: ./Dockerfile.api dockerfile: ./Dockerfile.api
proxy: proxy:

View file

@ -122,7 +122,7 @@ services:
api: api:
build: build:
context: ./apiserver context: ./apps/server
dockerfile: Dockerfile.dev dockerfile: Dockerfile.dev
args: args:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1
@ -130,10 +130,10 @@ services:
networks: networks:
- dev_env - dev_env
volumes: volumes:
- ./apiserver:/code - ./apps/server:/code
command: ./bin/docker-entrypoint-api-local.sh command: ./bin/docker-entrypoint-api-local.sh
env_file: env_file:
- ./apiserver/.env - ./apps/server/.env
depends_on: depends_on:
- plane-db - plane-db
- plane-redis - plane-redis
@ -143,7 +143,7 @@ services:
worker: worker:
build: build:
context: ./apiserver context: ./apps/server
dockerfile: Dockerfile.dev dockerfile: Dockerfile.dev
args: args:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1
@ -151,10 +151,10 @@ services:
networks: networks:
- dev_env - dev_env
volumes: volumes:
- ./apiserver:/code - ./apps/server:/code
command: ./bin/docker-entrypoint-worker.sh command: ./bin/docker-entrypoint-worker.sh
env_file: env_file:
- ./apiserver/.env - ./apps/server/.env
depends_on: depends_on:
- api - api
- plane-db - plane-db
@ -162,7 +162,7 @@ services:
beat-worker: beat-worker:
build: build:
context: ./apiserver context: ./apps/server
dockerfile: Dockerfile.dev dockerfile: Dockerfile.dev
args: args:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1
@ -170,10 +170,10 @@ services:
networks: networks:
- dev_env - dev_env
volumes: volumes:
- ./apiserver:/code - ./apps/server:/code
command: ./bin/docker-entrypoint-beat.sh command: ./bin/docker-entrypoint-beat.sh
env_file: env_file:
- ./apiserver/.env - ./apps/server/.env
depends_on: depends_on:
- api - api
- plane-db - plane-db
@ -181,7 +181,7 @@ services:
migrator: migrator:
build: build:
context: ./apiserver context: ./apps/server
dockerfile: Dockerfile.dev dockerfile: Dockerfile.dev
args: args:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1
@ -189,10 +189,10 @@ services:
networks: networks:
- dev_env - dev_env
volumes: volumes:
- ./apiserver:/code - ./apps/server:/code
command: ./bin/docker-entrypoint-migrator.sh --settings=plane.settings.local command: ./bin/docker-entrypoint-migrator.sh --settings=plane.settings.local
env_file: env_file:
- ./apiserver/.env - .env
depends_on: depends_on:
- plane-db - plane-db
- plane-redis - plane-redis

View file

@ -40,14 +40,14 @@ services:
api: api:
container_name: api container_name: api
build: build:
context: ./apiserver context: ./apps/server
dockerfile: Dockerfile.api dockerfile: Dockerfile.api
args: args:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1
restart: always restart: always
command: ./bin/docker-entrypoint-api.sh command: ./bin/docker-entrypoint-api.sh
env_file: env_file:
- ./apiserver/.env - ./apps/server/.env
depends_on: depends_on:
- plane-db - plane-db
- plane-redis - plane-redis
@ -55,14 +55,14 @@ services:
worker: worker:
container_name: bgworker container_name: bgworker
build: build:
context: ./apiserver context: ./apps/server
dockerfile: Dockerfile.api dockerfile: Dockerfile.api
args: args:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1
restart: always restart: always
command: ./bin/docker-entrypoint-worker.sh command: ./bin/docker-entrypoint-worker.sh
env_file: env_file:
- ./apiserver/.env - ./apps/server/.env
depends_on: depends_on:
- api - api
- plane-db - plane-db
@ -71,14 +71,14 @@ services:
beat-worker: beat-worker:
container_name: beatworker container_name: beatworker
build: build:
context: ./apiserver context: ./apps/server
dockerfile: Dockerfile.api dockerfile: Dockerfile.api
args: args:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1
restart: always restart: always
command: ./bin/docker-entrypoint-beat.sh command: ./bin/docker-entrypoint-beat.sh
env_file: env_file:
- ./apiserver/.env - ./apps/server/.env
depends_on: depends_on:
- api - api
- plane-db - plane-db
@ -87,14 +87,14 @@ services:
migrator: migrator:
container_name: plane-migrator container_name: plane-migrator
build: build:
context: ./apiserver context: ./apps/server
dockerfile: Dockerfile.api dockerfile: Dockerfile.api
args: args:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1
restart: no restart: no
command: ./bin/docker-entrypoint-migrator.sh command: ./bin/docker-entrypoint-migrator.sh
env_file: env_file:
- ./apiserver/.env - ./apps/server/.env
depends_on: depends_on:
- plane-db - plane-db
- plane-redis - plane-redis

View file

@ -1,3 +0,0 @@
build:
docker:
web: deploy/heroku/Dockerfile

View file

@ -44,20 +44,23 @@ export LC_CTYPE=C
echo -e "${YELLOW}Setting up environment files...${NC}" echo -e "${YELLOW}Setting up environment files...${NC}"
# Copy all environment example files # Copy all environment example files
services=("" "web" "apiserver" "space" "admin" "live") services=("" "web" "server" "space" "admin" "live")
success=true success=true
for service in "${services[@]}"; do for service in "${services[@]}"; do
prefix="./" if [ "$service" == "" ]; then
if [ "$service" != "" ]; then # Handle root .env file
prefix="./$service/" prefix="./"
else
# Handle service .env files in apps folder
prefix="./apps/$service/"
fi fi
copy_env_file "${prefix}.env.example" "${prefix}.env" || success=false copy_env_file "${prefix}.env.example" "${prefix}.env" || success=false
done done
# Generate SECRET_KEY for Django # Generate SECRET_KEY for Django
if [ -f "./apiserver/.env" ]; then if [ -f "./apps/server/.env" ]; then
echo -e "\n${YELLOW}Generating Django SECRET_KEY...${NC}" echo -e "\n${YELLOW}Generating Django SECRET_KEY...${NC}"
SECRET_KEY=$(tr -dc 'a-z0-9' < /dev/urandom | head -c50) SECRET_KEY=$(tr -dc 'a-z0-9' < /dev/urandom | head -c50)
@ -66,11 +69,11 @@ if [ -f "./apiserver/.env" ]; then
echo -e "${RED}Ensure 'tr' and 'head' commands are available on your system.${NC}" echo -e "${RED}Ensure 'tr' and 'head' commands are available on your system.${NC}"
success=false success=false
else else
echo -e "SECRET_KEY=\"$SECRET_KEY\"" >> ./apiserver/.env echo -e "SECRET_KEY=\"$SECRET_KEY\"" >> ./apps/server/.env
echo -e "${GREEN}${NC} Added SECRET_KEY to apiserver/.env" echo -e "${GREEN}${NC} Added SECRET_KEY to apps/server/.env"
fi fi
else else
echo -e "${RED}${NC} apiserver/.env not found. SECRET_KEY not added." echo -e "${RED}${NC} apps/server/.env not found. SECRET_KEY not added."
success=false success=false
fi fi