diff --git a/.drone.yml b/.drone.yml index a4b1e3f..4fc6dc2 100644 --- a/.drone.yml +++ b/.drone.yml @@ -27,3 +27,46 @@ steps: commands: - npm ci - npm run check_format + +--- + +kind: pipeline +type: docker +name: deploy_server + +steps: + - name: upload_to_registry + image: plugins/docker + settings: + registry: gitea.gilmour109.de + repo: gitea.gilmour109.de/Gilmour109/calchat-server + dockerfile: apps/server/docker/Dockerfile + tags: + - latest + - main + username: + from_secret: gitea_username + password: + from_secret: gitea_password + + - name: ssh + image: appleboy/drone-ssh + settings: + host: + - 10.0.0.1 + username: root + password: + from_secret: vps_ssh_password + envs: + - gitea_username + - gitea_password + port: 22 + command_timeout: 2m + script: + - docker login -u $GITEA_USERNAME -p $GITEA_PASSWORD gitea.gilmour109.de + - docker pull gitea.gilmour109.de/gilmour109/calchat-server:latest + - docker compose -f /root/calchat-mongo/docker-compose.yml up -d + +depends_on: + - server_build_and_test + - check_for_formatting diff --git a/CLAUDE.md b/CLAUDE.md index 21b2fc8..1f53de4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -62,7 +62,7 @@ npm run test -w @calchat/server # Run Jest unit tests | | ical.js | iCalendar parsing/generation | | Testing | Jest / ts-jest | Server unit tests | | Deployment | Docker | Server containerization (multi-stage build) | -| | Drone CI | CI/CD pipelines (build, test, format check) | +| | Drone CI | CI/CD pipelines (build, test, format check, deploy) | | Planned | iCalendar | Event export/import | ## Architecture @@ -544,13 +544,11 @@ docker compose up -d # Start Radicale CalDAV server ### Server Docker Image ```bash -# Build (clones from Gitea, no local context needed): +# Build (requires local build context): docker build -f apps/server/docker/Dockerfile -t calchat-server . -# Build from a specific branch: -docker build -f apps/server/docker/Dockerfile --build-arg BRANCH=feature-x -t calchat-server . -docker run -p 3000:3000 --env-file apps/server/.env calchat-server +docker run -p 3001:3001 --env-file apps/server/.env calchat-server ``` -Multi-stage build: clones the repo from Gitea (`git clone --depth 1`) in the build stage using a `BRANCH` build arg (default: `main`), compiles shared + server, then copies only `dist/` and production dependencies to the runtime stage. No local source context required — the image can be built on any machine with Docker. +Multi-stage COPY-based build: copies `package.json` files first for layer caching, then source code. Compiles shared + server, then copies only `dist/` and production dependencies to the runtime stage. Exposes port 3001. In CI, the `plugins/docker` Drone plugin builds and pushes the image automatically. ### Environment Variables Server requires `.env` file in `apps/server/`: @@ -700,10 +698,11 @@ This uses the `preview` profile from `eas.json` which builds an APK with: ## CI/CD (Drone) -The project uses Drone CI (`.drone.yml`) with two pipelines: +The project uses Drone CI (`.drone.yml`) with three pipelines: 1. **`server_build_and_test`**: Builds the server (`npm ci` + `npm run build`) and runs Jest tests (`npm run test`) 2. **`check_for_formatting`**: Checks Prettier formatting across all workspaces (`npm run check_format`) +3. **`deploy_server`**: Builds Docker image, pushes to Gitea Container Registry (`gitea.gilmour109.de/Gilmour109/calchat-server`), then SSHs into VPS (`10.0.0.1`) to pull and restart via `docker compose`. Depends on both pipelines above passing first. ## Testing diff --git a/apps/server/docker/Dockerfile b/apps/server/docker/Dockerfile index 6e58758..359ac49 100644 --- a/apps/server/docker/Dockerfile +++ b/apps/server/docker/Dockerfile @@ -1,15 +1,17 @@ FROM node:alpine AS build -RUN apk add --no-cache git - -ARG BRANCH=main WORKDIR /app -RUN git clone --branch ${BRANCH} --depth 1 https://gitea.gilmour109.de/Gilmour109/calchat.git . -RUN npm ci --workspace=@calchat/server --workspace=@calchat/shared --include-workspace-root +COPY package.json package-lock.json ./ +COPY packages/shared/package.json ./packages/shared/ +COPY apps/server/package.json ./apps/server/ -RUN npm run build --workspace=@calchat/shared && \ - npm run build --workspace=@calchat/server +RUN npm ci -w @calchat/server -w @calchat/shared --include-workspace-root + +COPY packages/shared/ packages/shared/ +COPY apps/server/ apps/server/ + +RUN npm run build -w @calchat/shared && npm run build -w @calchat/server FROM node:alpine @@ -19,11 +21,11 @@ COPY --from=build /app/package.json /app/package-lock.json ./ COPY --from=build /app/packages/shared/package.json packages/shared/ COPY --from=build /app/apps/server/package.json apps/server/ -RUN npm ci --omit=dev --workspace=@calchat/server --workspace=@calchat/shared --include-workspace-root +RUN npm ci --omit=dev -w @calchat/server -w @calchat/shared COPY --from=build /app/packages/shared/dist/ packages/shared/dist/ COPY --from=build /app/apps/server/dist/ apps/server/dist/ -EXPOSE 3000 +EXPOSE 3001 CMD ["node", "apps/server/dist/app.js"]