Deploy skeleton-app
Build and Deploy / build-and-push (push) Successful in 1m4s
Details
Build and Deploy / build-and-push (push) Successful in 1m4s
Details
This commit is contained in:
parent
083982814f
commit
d649f3c87c
|
|
@ -18,7 +18,7 @@ jobs:
|
|||
username: ${{ gitea.actor }}
|
||||
password: ${{ secrets.CI_TOKEN }}
|
||||
|
||||
- name: Build and Pushz
|
||||
- name: Build and Push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
|
|
@ -28,5 +28,6 @@ jobs:
|
|||
- name: Deploy to Server
|
||||
run: |
|
||||
# Here we tell the server to pull the new image and restart
|
||||
echo "${{ secrets.CI_TOKEN }}" | docker login git.ludops.com -u ${{ gitea.actor }} --password-stdin
|
||||
docker compose -f docker-compose.prod.yml pull
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
|
|
|
|||
43
Dockerfile
43
Dockerfile
|
|
@ -1,36 +1,37 @@
|
|||
# --- STAGE 1: Base & Dependencies ---
|
||||
FROM node:20-alpine AS base
|
||||
# --- STAGE 1: Base ---
|
||||
FROM node:24-alpine AS base
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
WORKDIR /app
|
||||
|
||||
# Copy lockfiles and workspace configs
|
||||
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json turbo.json ./
|
||||
# Copy all package.jsons to allow pnpm to link workspaces
|
||||
COPY apps/api/package.json ./apps/api/
|
||||
COPY apps/web/package.json ./apps/web/
|
||||
COPY packages/shared/package.json ./packages/shared/
|
||||
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# --- STAGE 2: Build ---
|
||||
# --- STAGE 2: Build everything ---
|
||||
FROM base AS build
|
||||
COPY . .
|
||||
# This runs 'turbo run build' which should create 'dist' in both apps
|
||||
RUN pnpm install --frozen-lockfile
|
||||
RUN pnpm turbo run build
|
||||
|
||||
# --- STAGE 3: Runner (The tiny production image) ---
|
||||
FROM node:20-alpine AS runner
|
||||
# --- STAGE 3: Extract for Production ---
|
||||
# This "flattens" the api and its node_modules into a standalone folder
|
||||
RUN pnpm deploy --filter=api --prod /prod/api
|
||||
|
||||
# --- STAGE 4: Runner ---
|
||||
FROM node:24-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
# IMPORTANT: We copy from 'build' stage, not 'base'
|
||||
# We check if the folders exist before copying to avoid the error you saw
|
||||
COPY --from=build /app/apps/api/dist ./api
|
||||
# Copy the standalone API (includes its own local node_modules)
|
||||
COPY --from=build /prod/api .
|
||||
|
||||
# Copy the web dist into the location the API expects
|
||||
# Based on your code, it looks for ../web-dist or ./web-dist
|
||||
COPY --from=build /app/apps/web/dist ./web-dist
|
||||
COPY --from=build /app/node_modules ./node_modules
|
||||
|
||||
# We need the shared package if the API imports it directly as source
|
||||
# But pnpm deploy usually handles the shared package if it's built
|
||||
COPY --from=build /app/packages/shared ./packages/shared
|
||||
|
||||
EXPOSE 3000
|
||||
# Update this path to wherever your compiled Fastify entry point is
|
||||
CMD ["node", "api/src/index.ts"]
|
||||
ENV NODE_ENV=production
|
||||
|
||||
# Since we are now inside the "api" folder essentially:
|
||||
CMD ["node", "dist/index.js"]
|
||||
|
|
@ -11,26 +11,26 @@ const fastify = Fastify({ logger: true });
|
|||
|
||||
// API Route
|
||||
fastify.get('/api/status', async (): Promise<AppStatus> => {
|
||||
return { status: 'OK', version: '1.0.0', database: true };
|
||||
return { status: 'OK', version: '1.0.0', database: true };
|
||||
});
|
||||
|
||||
// Serve Frontend (Vite Dist)
|
||||
const webDistPath = process.env.NODE_ENV === 'production'
|
||||
? path.join(__dirname, '../web-dist')
|
||||
: path.join(__dirname, '../../web/dist');
|
||||
? path.join(__dirname, '../web-dist') // Adjusted for the flattened Docker structure
|
||||
: path.join(__dirname, '../../web/dist');
|
||||
|
||||
fastify.register(fastifyStatic, {
|
||||
root: webDistPath,
|
||||
prefix: '/',
|
||||
root: webDistPath,
|
||||
prefix: '/',
|
||||
});
|
||||
|
||||
// SPA Routing: Redirect everything else to index.html
|
||||
fastify.setNotFoundHandler((req, reply) => {
|
||||
if (req.url.startsWith('/api')) {
|
||||
reply.code(404).send({ error: 'Not Found' });
|
||||
} else {
|
||||
reply.sendFile('index.html');
|
||||
}
|
||||
if (req.url.startsWith('/api')) {
|
||||
reply.code(404).send({ error: 'Not Found' });
|
||||
} else {
|
||||
reply.sendFile('index.html');
|
||||
}
|
||||
});
|
||||
|
||||
fastify.listen({ port: 3000, host: '0.0.0.0' });
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
services:
|
||||
skeleton-app:
|
||||
image: git.ludops.com/ludops/ludops-skeleton:latest
|
||||
container_name: ludops-skeleton-app
|
||||
restart: always
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- PORT=3000
|
||||
# We point to the shared DB we set up earlier
|
||||
- DATABASE_URL=postgres://gitea:gitea@ludops-postgres:5432/skeleton_db
|
||||
networks:
|
||||
- proxy-tier # For NPM to find us
|
||||
- infrastructure_infra-network # For us to find the Postgres DB
|
||||
|
||||
networks:
|
||||
proxy-tier:
|
||||
external: true
|
||||
infrastructure_infra-network:
|
||||
external: true
|
||||
|
|
@ -3,6 +3,7 @@ lockfileVersion: '9.0'
|
|||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
injectWorkspacePackages: true
|
||||
|
||||
importers:
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue