feat: add docker
This commit is contained in:
60
docker/Dockerfile
Normal file
60
docker/Dockerfile
Normal file
@ -0,0 +1,60 @@
|
||||
# docker/Dockerfile
|
||||
|
||||
# ==============================================================================
|
||||
# STAGE 1: Build
|
||||
# ==============================================================================
|
||||
FROM rust:1.85-alpine AS builder
|
||||
|
||||
# Install the minimal C toolchain required by the `ring` crate (a dependency of `rustls`).
|
||||
RUN apk add --no-cache musl-dev gcc
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# 1. Create a dummy binary project.
|
||||
RUN mkdir src
|
||||
RUN echo "fn main() {}" > src/main.rs
|
||||
|
||||
# 2. Copy the dependency manifests.
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
|
||||
# 3. Build the dependencies. This will compile all dependencies from
|
||||
# Cargo.lock and the empty main.rs.
|
||||
RUN cargo build --release
|
||||
|
||||
# 4. Now, copy the actual application source code.
|
||||
COPY src ./src
|
||||
|
||||
# 5. Build the real application. This will be very fast as all dependencies
|
||||
# are already compiled and cached.
|
||||
RUN cargo build --release
|
||||
|
||||
# ==============================================================================
|
||||
# STAGE 2: Create the final, minimal production image
|
||||
# ==============================================================================
|
||||
FROM alpine:3.22 AS final
|
||||
|
||||
# Set default environment variables
|
||||
ENV CRON_SCHEDULE="10 2 * * *"
|
||||
ENV PUID=1000
|
||||
ENV PGID=1000
|
||||
|
||||
# Install runtime dependencies.
|
||||
RUN apk add --no-cache ca-certificates tzdata su-exec busybox
|
||||
|
||||
# Create a non-root user and group for the application to run as
|
||||
RUN addgroup -S -g ${PGID} app && \
|
||||
adduser -S -u ${PUID} -G app -h /app app
|
||||
|
||||
# Copy the compiled binary from the builder stage
|
||||
COPY --from=builder /app/target/release/sb-ruleset-sync /usr/local/bin/ruleset-sync
|
||||
|
||||
# Copy the entrypoint script
|
||||
COPY ./docker/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
|
||||
# Create necessary directories and set ownership
|
||||
RUN mkdir -p /config /rules && \
|
||||
chown -R app:app /rules
|
||||
|
||||
# Set the entrypoint for the container
|
||||
ENTRYPOINT ["entrypoint.sh"]
|
33
docker/entrypoint.sh
Normal file
33
docker/entrypoint.sh
Normal file
@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e # Exit immediately if a command exits with a non-zero status.
|
||||
|
||||
# Define the command to be executed by cron or manually
|
||||
APP_CMD="/usr/local/bin/ruleset-sync -i /config/template.json -o /rules"
|
||||
|
||||
# === Manual Run ===
|
||||
# If the first argument is "manual", run the sync once and exit.
|
||||
if [ "$1" = "manual" ]; then
|
||||
echo "[$(date +"%Y-%m-%d %H:%M:%S")] Running one-time manual sync..."
|
||||
# Execute the command as the non-root 'app' user
|
||||
su-exec app:app ${APP_CMD}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# === Cron Setup ===
|
||||
# This section runs as root to set up the cron job.
|
||||
|
||||
echo "Setting up cron job with schedule: ${CRON_SCHEDULE}"
|
||||
|
||||
# Remove any existing crontab
|
||||
crontab -d || true
|
||||
|
||||
# Add the new cron job. It will run the command as the 'app' user
|
||||
# and redirect stdout/stderr to the container's log stream.
|
||||
echo "${CRON_SCHEDULE} su-exec app:app ${APP_CMD} > /proc/1/fd/1 2>/proc/1/fd/2" | crontab -
|
||||
|
||||
# Start the cron daemon in the foreground.
|
||||
# This keeps the container running and handles executing the scheduled jobs.
|
||||
# Logs from crond itself and the script's output will go to Docker logs.
|
||||
echo "Starting cron daemon..."
|
||||
exec crond -f -l 8
|
Reference in New Issue
Block a user