Skip to content

Commit d08a681

Browse files
authored
feat: easy to self host (#96)
* fix: dragonfly * feat: shell script * fix: review feedback * fix: further refinements * fix: deploy prompts * fix: migrations * feat: node 24 bookworm-slim * chore: just single db superuser * fix: ci check * fix: workflow * fix: build * fix: localhost * feat: finalize deploy script * fix: pr reviews * fix: address pr review * fix: healthcheck
1 parent 79f17e2 commit d08a681

17 files changed

Lines changed: 1111 additions & 160 deletions

File tree

.github/workflows/docker-publish.yml

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Build and Publish Docker Image
1+
name: Build and Publish Docker Images
22

33
on:
44
workflow_dispatch:
@@ -9,10 +9,11 @@ on:
99
type: string
1010

1111
env:
12-
IMAGE: sweetr/sweetr
12+
API_IMAGE: sweetr/api
13+
WEB_IMAGE: sweetr/web
1314

1415
jobs:
15-
validate:
16+
validate-api:
1617
runs-on: ubuntu-latest
1718
permissions:
1819
contents: read
@@ -33,6 +34,10 @@ jobs:
3334
--health-retries 5
3435
dragonfly:
3536
image: docker.dragonflydb.io/dragonflydb/dragonfly
37+
env:
38+
DFLY_cluster_mode: emulated
39+
DFLY_lock_on_hashtags: "true"
40+
3641
ports:
3742
- 6379:6379
3843
options: >-
@@ -48,18 +53,18 @@ jobs:
4853
- name: Set up Docker Buildx
4954
uses: docker/setup-buildx-action@v3
5055

51-
- name: Build image
56+
- name: Build API image
5257
uses: docker/build-push-action@v6
5358
with:
5459
context: .
5560
file: ./apps/api/Dockerfile
5661
push: false
5762
load: true
58-
tags: ${{ env.IMAGE }}:test
63+
tags: ${{ env.API_IMAGE }}:test
5964
cache-from: type=gha
6065
cache-to: type=gha,mode=max
6166

62-
- name: Start container
67+
- name: Start API container
6368
run: |
6469
docker run -d --name sweetr-api --network host \
6570
-e PORT=8000 \
@@ -74,7 +79,7 @@ jobs:
7479
-e GITHUB_APP_ID=test \
7580
-e GITHUB_APP_PRIVATE_KEY=test \
7681
-e GITHUB_WEBHOOK_SECRET=test \
77-
${{ env.IMAGE }}:test
82+
${{ env.API_IMAGE }}:test
7883
7984
- name: Wait for API to be ready
8085
run: |
@@ -90,8 +95,53 @@ jobs:
9095
docker logs sweetr-api
9196
exit 1
9297
98+
validate-web:
99+
runs-on: ubuntu-latest
100+
permissions:
101+
contents: read
102+
103+
steps:
104+
- name: Checkout repository
105+
uses: actions/checkout@v4
106+
107+
- name: Set up Docker Buildx
108+
uses: docker/setup-buildx-action@v3
109+
110+
- name: Build Web image
111+
uses: docker/build-push-action@v6
112+
with:
113+
context: .
114+
file: ./apps/web/Dockerfile
115+
push: false
116+
load: true
117+
tags: ${{ env.WEB_IMAGE }}:test
118+
cache-from: type=gha
119+
cache-to: type=gha,mode=max
120+
121+
- name: Start Web container
122+
run: |
123+
docker run -d --name sweetr-web -p 8080:80 \
124+
-e API_ENDPOINT=http://localhost:8000 \
125+
-e AUTH_COOKIE_DOMAIN=localhost \
126+
-e GITHUB_APP=test \
127+
${{ env.WEB_IMAGE }}:test
128+
129+
- name: Wait for Web to be ready
130+
run: |
131+
for i in $(seq 1 15); do
132+
if curl -sf http://localhost:8080/env-config.js > /dev/null 2>&1; then
133+
echo "Web is healthy"
134+
exit 0
135+
fi
136+
echo "Waiting for Web... (attempt $i/15)"
137+
sleep 2
138+
done
139+
echo "Web failed to start. Container logs:"
140+
docker logs sweetr-web
141+
exit 1
142+
93143
publish:
94-
needs: validate
144+
needs: [validate-api, validate-web]
95145
runs-on: ubuntu-latest
96146
permissions:
97147
contents: read
@@ -109,14 +159,26 @@ jobs:
109159
username: ${{ secrets.DOCKERHUB_USERNAME }}
110160
password: ${{ secrets.DOCKERHUB_TOKEN }}
111161

112-
- name: Build and push
162+
- name: Build and push API image
113163
uses: docker/build-push-action@v6
114164
with:
115165
context: .
116166
file: ./apps/api/Dockerfile
117167
push: true
118168
tags: |
119-
${{ env.IMAGE }}:${{ inputs.version }}
120-
${{ env.IMAGE }}:latest
169+
${{ env.API_IMAGE }}:${{ inputs.version }}
170+
${{ env.API_IMAGE }}:latest
171+
cache-from: type=gha
172+
cache-to: type=gha,mode=max
173+
174+
- name: Build and push Web image
175+
uses: docker/build-push-action@v6
176+
with:
177+
context: .
178+
file: ./apps/web/Dockerfile
179+
push: true
180+
tags: |
181+
${{ env.WEB_IMAGE }}:${{ inputs.version }}
182+
${{ env.WEB_IMAGE }}:latest
121183
cache-from: type=gha
122184
cache-to: type=gha,mode=max

apps/api/Dockerfile

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:20-bullseye AS base
1+
FROM node:24-bookworm-slim AS base
22

33
FROM base AS builder
44
WORKDIR /app
@@ -8,19 +8,23 @@ RUN npx turbo prune api --docker
88

99
FROM base AS installer
1010
WORKDIR /app
11+
RUN apt-get update && apt-get install -y build-essential python3 --no-install-recommends && rm -rf /var/lib/apt/lists/*
1112

1213
COPY --from=builder /app/out/json/ .
1314
RUN npm install
1415
COPY --from=builder /app/out/full/ .
1516
RUN npm run build
1617

17-
FROM base AS runner
18+
FROM node:24-bookworm-slim AS runner
1819
WORKDIR /app
1920

21+
RUN apt-get update && apt-get install -y openssl curl --no-install-recommends && rm -rf /var/lib/apt/lists/*
22+
2023
RUN addgroup --system --gid 1001 apiuser
2124
RUN adduser --system --uid 1001 apiuser
22-
USER apiuser
2325

24-
COPY --from=installer /app .
26+
COPY --from=installer --chown=apiuser:apiuser /app .
27+
28+
USER apiuser
2529

2630
CMD npm run prisma:migrate:production --workspace api && npm run start

0 commit comments

Comments
 (0)