Skip to content

Commit ee00f0d

Browse files
feat: Add official docker support (calcom#24672)
* feat: Add official Docker support * Adding scarf data support * Comment out pushing the image for now * Getting env vars ported * Renamed the job to Release instead of Remote Release * Move the Dockerfile and docker-compose files to monorepo root * Remove Slack notifications for failures for now * Show database container status * Setting env directly for testing * Removing env var * Adding container logs * Change the volume * fixing file paths * Double-quotes wrecking things * Fixing /calcom paths * Update permission for scripts * Fixed the Slack notification * Updated Slack notification emojis * Checking the workflow_dispatch input for checkout * Commenting out the tag checkout for now since our new Docker files are not in main * Added .dockerignore * Remove the scarf data export * Removed extra empty line * refactor: Create reusable Docker build action for AMD64 and ARM support - Extract common Docker build logic into reusable composite action - Create separate workflows for AMD64 and ARM builds that run in parallel - Both workflows use the same reusable action with platform-specific parameters - ARM builds use ubuntu-24.04-arm runner and add -arm suffix to tags - AMD64 builds use buildjet-4vcpu-ubuntu-2204 runner - Remove old monolithic release-docker.yaml workflow Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * Revert "refactor: Create reusable Docker build action for AMD64 and ARM support" This reverts commit 66d2c17. * refactor: Add parallel AMD64 and ARM Docker builds using reusable action - Create reusable composite action in .github/actions/docker-build-and-test - Extract common Docker build, test, and push logic into the action - Update release-docker.yaml to have two parallel jobs: - release-amd64: Builds for linux/amd64 on buildjet-4vcpu-ubuntu-2204 - release-arm: Builds for arm64 on ubuntu-24.04-arm with -arm suffix - Both jobs use the same reusable action with platform-specific parameters - Maintains existing functionality while enabling parallel builds Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * Update the ARM action to run on buildjet 4vCPU ARM * Move the Dockerfile to apps/web * Revert "Move the Dockerfile to apps/web" This reverts commit fd91ebe. * Revert the arm machine back off build jet * Use node 20 * Set push to true * Remove Dockerfile.render * Removed commented Docker lines * Fixed read me * Updated README for Docker support --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent 246abe0 commit ee00f0d

9 files changed

Lines changed: 976 additions & 37 deletions

File tree

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
name: "Docker Build and Test"
2+
description: "Reusable action to build and test Docker images for Cal.com"
3+
4+
inputs:
5+
platform:
6+
description: "Target platform (linux/amd64 or arm64)"
7+
required: true
8+
platform-suffix:
9+
description: "Suffix to add to image tags (e.g., -arm)"
10+
required: false
11+
default: ""
12+
dockerhub-username:
13+
description: "Docker Hub username"
14+
required: true
15+
dockerhub-token:
16+
description: "Docker Hub token"
17+
required: true
18+
github-token:
19+
description: "GitHub token for GHCR"
20+
required: true
21+
postgres-user:
22+
description: "PostgreSQL user"
23+
required: true
24+
postgres-password:
25+
description: "PostgreSQL password"
26+
required: true
27+
postgres-db:
28+
description: "PostgreSQL database name"
29+
required: true
30+
database-host:
31+
description: "Database host"
32+
required: true
33+
push-image:
34+
description: "Whether to push the built image"
35+
required: false
36+
default: "false"
37+
38+
runs:
39+
using: "composite"
40+
steps:
41+
- name: Log in to the Docker Hub registry
42+
uses: docker/login-action@v3
43+
with:
44+
username: ${{ inputs.dockerhub-username }}
45+
password: ${{ inputs.dockerhub-token }}
46+
logout: true
47+
48+
- name: Log in to the Github Container registry
49+
uses: docker/login-action@v3
50+
with:
51+
registry: ghcr.io
52+
username: ${{ github.actor }}
53+
password: ${{ inputs.github-token }}
54+
55+
- name: Docker meta
56+
id: meta
57+
uses: docker/metadata-action@v5
58+
with:
59+
images: |
60+
docker.io/calendso/calendso
61+
docker.io/calcom/cal.com
62+
ghcr.io/calcom/cal.com
63+
flavor: |
64+
latest=${{ !github.event.release.prerelease }}
65+
suffix=${{ inputs.platform-suffix }}
66+
67+
- name: Copy env
68+
shell: bash
69+
run: |
70+
grep -o '^[^#]*' .env.example > .env
71+
cat .env >> $GITHUB_ENV
72+
echo "DATABASE_HOST=localhost:5432" >> $GITHUB_ENV
73+
eval $(sed -e '/^#/d' -e 's/^/export /' -e 's/$/;/' .env) ;
74+
75+
- name: Start database
76+
shell: bash
77+
run: |
78+
docker compose up -d database
79+
80+
- name: Show database logs and container status
81+
shell: bash
82+
run: |
83+
echo "--- Container Status ---"
84+
docker compose ps database
85+
86+
echo "--- Container Logs ---"
87+
docker compose logs database
88+
89+
- name: Set up Docker Buildx
90+
uses: docker/setup-buildx-action@v3
91+
with:
92+
driver-opts: |
93+
network=container:database
94+
buildkitd-flags: |
95+
--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
96+
97+
- name: Build image
98+
id: docker_build
99+
uses: docker/build-push-action@v6
100+
with:
101+
context: ./
102+
file: ./Dockerfile
103+
load: true
104+
push: false
105+
platforms: ${{ inputs.platform }}
106+
tags: ${{ steps.meta.outputs.tags }}
107+
labels: ${{ steps.meta.outputs.labels }}
108+
build-args: |
109+
NEXT_PUBLIC_WEBAPP_URL=http://localhost:3000
110+
NEXT_PUBLIC_API_V2_URL=http://localhost:5555/api/v2
111+
NEXT_PUBLIC_LICENSE_CONSENT=agree
112+
DATABASE_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@${{ inputs.database-host }}/${{ inputs.postgres-db }}
113+
DATABASE_DIRECT_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@${{ inputs.database-host }}/${{ inputs.postgres-db }}
114+
115+
- name: Test runtime
116+
shell: bash
117+
run: |
118+
tags="${{ steps.meta.outputs.tags }}"
119+
IFS=',' read -ra ADDR <<< "$tags"
120+
tag=${ADDR[0]}
121+
122+
docker run --rm --network stack \
123+
-p 3000:3000 \
124+
-e DATABASE_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@database/${{ inputs.postgres-db }} \
125+
-e DATABASE_DIRECT_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@database/${{ inputs.postgres-db }} \
126+
-e NEXTAUTH_SECRET=${{ env.NEXTAUTH_SECRET }} \
127+
-e CALENDSO_ENCRYPTION_KEY=${{ env.CALENDSO_ENCRYPTION_KEY }} \
128+
$tag &
129+
130+
server_pid=$!
131+
132+
echo "Waiting for the server to start..."
133+
sleep 120
134+
135+
echo http://localhost:3000/auth/login
136+
137+
for i in {1..60}; do
138+
echo "Checking server health ($i/60)..."
139+
response=$(curl -o /dev/null -s -w "%{http_code}" http://localhost:3000/auth/login)
140+
echo "HTTP Status Code: $response"
141+
if [[ "$response" == "200" ]] || [[ "$response" == "307" ]]; then
142+
echo "Server is healthy"
143+
kill $server_pid
144+
exit 0
145+
fi
146+
sleep 1
147+
done
148+
149+
echo "Server health check failed"
150+
kill $server_pid
151+
exit 1
152+
env:
153+
NEXTAUTH_SECRET: "EI4qqDpcfdvf4A+0aQEEx8JjHxHSy4uWiZw/F32K+pA="
154+
CALENDSO_ENCRYPTION_KEY: "0zfLtY99wjeLnsM7qsa8xsT+Q0oSgnOL"
155+
156+
- name: Push image
157+
id: docker_push
158+
uses: docker/build-push-action@v6
159+
if: ${{ inputs.push-image == 'true' && !github.event.release.prerelease }}
160+
with:
161+
context: ./
162+
file: ./Dockerfile
163+
push: true
164+
platforms: ${{ inputs.platform }}
165+
tags: ${{ steps.meta.outputs.tags }}
166+
labels: ${{ steps.meta.outputs.labels }}
167+
build-args: |
168+
NEXT_PUBLIC_WEBAPP_URL=http://localhost:3000
169+
NEXT_PUBLIC_API_V2_URL=http://localhost:5555/api/v2
170+
NEXT_PUBLIC_LICENSE_CONSENT=agree
171+
DATABASE_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@${{ inputs.database-host }}/${{ inputs.postgres-db }}
172+
DATABASE_DIRECT_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@${{ inputs.database-host }}/${{ inputs.postgres-db }}
173+
174+
- name: Image digest
175+
shell: bash
176+
run: echo ${{ steps.docker_build.outputs.digest }}
177+
178+
- name: Cleanup
179+
shell: bash
180+
if: always()
181+
run: |
182+
docker compose down
Lines changed: 90 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,110 @@
11
name: "Release Docker"
22

3-
on: # yamllint disable-line rule:truthy
4-
release:
5-
types:
6-
- created
7-
- published
3+
env:
4+
POSTGRES_USER: "unicorn_user"
5+
POSTGRES_PASSWORD: "magical_password"
6+
POSTGRES_DB: "calendso"
7+
DATABASE_HOST: "database:5432"
8+
9+
on:
10+
push:
11+
tags:
12+
- "v*"
813
# in case manual trigger is needed
914
workflow_dispatch:
1015
inputs:
1116
RELEASE_TAG:
1217
description: "v{Major}.{Minor}.{Patch}"
1318

1419
jobs:
15-
release:
16-
name: "Remote Release"
20+
release-amd64:
21+
name: "Release AMD64"
22+
runs-on: buildjet-4vcpu-ubuntu-2204
23+
steps:
24+
- name: checkout
25+
uses: actions/checkout@v4
26+
27+
- name: "Determine tag"
28+
run: 'echo "RELEASE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV'
1729

18-
runs-on: "ubuntu-latest"
30+
- name: Build and test Docker image
31+
uses: ./.github/actions/docker-build-and-test
32+
with:
33+
platform: "linux/amd64"
34+
platform-suffix: ""
35+
dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }}
36+
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
37+
github-token: ${{ secrets.GITHUB_TOKEN }}
38+
postgres-user: ${{ env.POSTGRES_USER }}
39+
postgres-password: ${{ env.POSTGRES_PASSWORD }}
40+
postgres-db: ${{ env.POSTGRES_DB }}
41+
database-host: ${{ env.DATABASE_HOST }}
42+
push-image: "true"
1943

44+
- name: Notify Slack on Success
45+
if: success()
46+
uses: slackapi/slack-github-action@v1.24.0
47+
with:
48+
payload: |
49+
{
50+
"text": ":large_green_circle: Workflow *${{ github.workflow }}* (AMD64) succeeded in job *${{ github.job }}*.\nSee: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
51+
}
52+
env:
53+
SLACK_WEBHOOK_URL: ${{ secrets.CI_SLACK_WEBHOOK_URL }}
54+
55+
- name: Notify Slack on Failure
56+
if: failure()
57+
uses: slackapi/slack-github-action@v1.24.0
58+
with:
59+
payload: |
60+
{
61+
"text": ":red_circle: Workflow *${{ github.workflow }}* (AMD64) failed in job *${{ github.job }}*.\nSee: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
62+
}
63+
env:
64+
SLACK_WEBHOOK_URL: ${{ secrets.CI_SLACK_WEBHOOK_URL }}
65+
66+
release-arm:
67+
name: "Release ARM"
68+
runs-on: ubuntu-24.04-arm
2069
steps:
2170
- name: checkout
2271
uses: actions/checkout@v4
2372

2473
- name: "Determine tag"
2574
run: 'echo "RELEASE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV'
2675

27-
- name: "Run remote release workflow"
28-
uses: "actions/github-script@v6"
76+
- name: Build and test Docker image
77+
uses: ./.github/actions/docker-build-and-test
78+
with:
79+
platform: "arm64"
80+
platform-suffix: "-arm"
81+
dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }}
82+
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
83+
github-token: ${{ secrets.GITHUB_TOKEN }}
84+
postgres-user: ${{ env.POSTGRES_USER }}
85+
postgres-password: ${{ env.POSTGRES_PASSWORD }}
86+
postgres-db: ${{ env.POSTGRES_DB }}
87+
database-host: ${{ env.DATABASE_HOST }}
88+
push-image: "true"
89+
90+
- name: Notify Slack on Success
91+
if: success()
92+
uses: slackapi/slack-github-action@v1.24.0
93+
with:
94+
payload: |
95+
{
96+
"text": ":large_green_circle: Workflow *${{ github.workflow }}* (ARM) succeeded in job *${{ github.job }}*.\nSee: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
97+
}
98+
env:
99+
SLACK_WEBHOOK_URL: ${{ secrets.CI_SLACK_WEBHOOK_URL }}
100+
101+
- name: Notify Slack on Failure
102+
if: failure()
103+
uses: slackapi/slack-github-action@v1.24.0
29104
with:
30-
# Requires a personal access token with Actions Read and write permissions on calcom/docker.
31-
github-token: "${{ secrets.DOCKER_REPO_ACCESS_TOKEN }}"
32-
script: |
33-
try {
34-
const response = await github.rest.actions.createWorkflowDispatch({
35-
owner: context.repo.owner,
36-
repo: 'docker',
37-
workflow_id: 'create-release.yaml',
38-
ref: 'main',
39-
inputs: {
40-
"RELEASE_TAG": process.env.RELEASE_TAG
41-
},
42-
});
43-
44-
console.log(response);
45-
} catch (error) {
46-
console.error(error);
47-
core.setFailed(error.message);
105+
payload: |
106+
{
107+
"text": ":red_circle: Workflow *${{ github.workflow }}* (ARM) failed in job *${{ github.job }}*.\nSee: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
48108
}
109+
env:
110+
SLACK_WEBHOOK_URL: ${{ secrets.CI_SLACK_WEBHOOK_URL }}

0 commit comments

Comments
 (0)