bundle frontend too

This commit is contained in:
WaveringAna 2025-01-27 16:24:31 -05:00
parent 850d977e8e
commit 660da70666
6 changed files with 162 additions and 9 deletions

3
.env.example Normal file
View file

@ -0,0 +1,3 @@
DATABASE_URL=postgresql://user:password@localhost/dbname
SERVER_HOST=127.0.0.1
SERVER_PORT=8080

7
.gitignore vendored
View file

@ -2,5 +2,8 @@
**/node_modules **/node_modules
node_modules node_modules
.env .env
.env.* /static
/static /target
/release
release.tar.gz
*.log

View file

@ -1,5 +1,21 @@
# Build stage # Frontend build stage
FROM rust:latest as builder FROM oven/bun:latest AS frontend-builder
WORKDIR /usr/src/frontend
# Copy frontend files
COPY frontend/package*.json ./
RUN bun install
COPY frontend/ ./
# Build frontend with production configuration
ARG API_URL=http://localhost:8080
ENV VITE_API_URL=${API_URL}
RUN bun run build
# Rust build stage
FROM rust:latest AS backend-builder
# Install PostgreSQL client libraries and SSL dependencies # Install PostgreSQL client libraries and SSL dependencies
RUN apt-get update && \ RUN apt-get update && \
@ -16,7 +32,10 @@ COPY src/ src/
COPY migrations/ migrations/ COPY migrations/ migrations/
COPY .sqlx/ .sqlx/ COPY .sqlx/ .sqlx/
# Build your application # Create static directory and copy frontend build
COPY --from=frontend-builder /usr/src/frontend/dist/ static/
# Build the application
RUN cargo build --release RUN cargo build --release
# Runtime stage # Runtime stage
@ -30,9 +49,13 @@ RUN apt-get update && \
WORKDIR /app WORKDIR /app
# Copy the binary from builder # Copy the binary from builder
COPY --from=builder /usr/src/app/target/release/simplelink /app/simplelink COPY --from=backend-builder /usr/src/app/target/release/simplelink /app/simplelink
# Copy migrations folder for SQLx # Copy migrations folder for SQLx
COPY --from=builder /usr/src/app/migrations /app/migrations COPY --from=backend-builder /usr/src/app/migrations /app/migrations
# Copy static files
COPY --from=backend-builder /usr/src/app/static /app/static
# Expose the port (this is just documentation) # Expose the port (this is just documentation)
EXPOSE 8080 EXPOSE 8080
@ -42,4 +65,4 @@ ENV SERVER_HOST=0.0.0.0
ENV SERVER_PORT=8080 ENV SERVER_PORT=8080
# Run the binary # Run the binary
CMD ["./simplelink"] CMD ["./simplelink"]

87
build.sh Executable file
View file

@ -0,0 +1,87 @@
#!/bin/bash
# Default values
API_URL="http://localhost:8080"
RELEASE_MODE=false
# Parse command line arguments
for arg in "$@"
do
case $arg in
api-domain=*)
API_URL="${arg#*=}"
shift
;;
--release)
RELEASE_MODE=true
shift
;;
esac
done
echo "Building project with API_URL: $API_URL"
echo "Release mode: $RELEASE_MODE"
# Check if cargo is installed
if ! command -v cargo &> /dev/null; then
echo "cargo is not installed. Please install Rust and cargo first."
exit 1
fi
# Check if npm is installed
if ! command -v npm &> /dev/null; then
echo "npm is not installed. Please install Node.js and npm first."
exit 1
fi
# Build frontend
echo "Building frontend..."
# Create .env file for Vite
echo "VITE_API_URL=$API_URL" > frontend/.env
# Install frontend dependencies and build
cd frontend
npm install
npm run build
cd ..
# Create static directory if it doesn't exist
mkdir -p static
# Clean existing static files
rm -rf static/*
# Copy built files to static directory
cp -r frontend/dist/* static/
# Build Rust project
echo "Building Rust project..."
if [ "$RELEASE_MODE" = true ]; then
cargo build --release
# Create release directory
mkdir -p release
# Copy binary and static files to release directory
cp target/release/simplelink release/
cp -r static release/
cp .env.example release/.env
# Create a tar archive
tar -czf release.tar.gz release/
echo "Release archive created: release.tar.gz"
else
cargo build
fi
echo "Build complete!"
echo "To run the project:"
if [ "$RELEASE_MODE" = true ]; then
echo "1. Extract release.tar.gz"
echo "2. Configure .env file"
echo "3. Run ./simplelink"
else
echo "1. Configure .env file"
echo "2. Run 'cargo run'"
fi

View file

@ -16,7 +16,42 @@ services:
interval: 5s interval: 5s
timeout: 5s timeout: 5s
retries: 5 retries: 5
networks:
- shortener-network
app:
build:
context: .
dockerfile: Dockerfile
args:
- API_URL=${API_URL:-http://localhost:8080}
container_name: shortener-app
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgresql://shortener:shortener123@db:5432/shortener
- SERVER_HOST=0.0.0.0
- SERVER_PORT=8080
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- shortener-network
deploy:
restart_policy:
condition: on-failure
max_attempts: 3
window: 120s
networks:
shortener-network:
driver: bridge
volumes: volumes:
shortener-data: shortener-data:

View file

@ -1,4 +1,5 @@
use actix_cors::Cors; use actix_cors::Cors;
use actix_files as fs;
use actix_web::{web, App, HttpServer}; use actix_web::{web, App, HttpServer};
use anyhow::Result; use anyhow::Result;
use simplelink::{handlers, AppState}; use simplelink::{handlers, AppState};
@ -61,6 +62,7 @@ async fn main() -> Result<()> {
.route("/health", web::get().to(handlers::health_check)), .route("/health", web::get().to(handlers::health_check)),
) )
.service(web::resource("/{short_code}").route(web::get().to(handlers::redirect_to_url))) .service(web::resource("/{short_code}").route(web::get().to(handlers::redirect_to_url)))
.service(fs::Files::new("/", "./static").index_file("index.html"))
}) })
.workers(2) .workers(2)
.backlog(10_000) .backlog(10_000)