Compare commits

...

9 commits

Author SHA1 Message Date
D. Scott Boggs 39903bc9f1 remove redundant parentheses 2025-05-08 08:53:13 -04:00
D. Scott Boggs 8cb7b672d6 Repo is deployment dir
Rather than putting the source repo in a build dir and having a mount dir next to that, the
source repo itself is the deployment dir, with the mount dir inside of it. We do not want
to commit the contents of the database to the repo obviously
2025-05-08 08:52:01 -04:00
D. Scott Boggs a94bc545aa Fix Next config to match example Dockerfile expectations 2025-05-08 08:50:30 -04:00
D. Scott Boggs 94e700d2e7 UID/GID 1000 was in use 2025-05-08 08:49:36 -04:00
D. Scott Boggs c3cdc0073c Password files must be trimmed of newlines 2025-05-08 08:49:02 -04:00
D. Scott Boggs 3debc5609a Updated dependencies require a newer version of libssl; use a newer debian 2025-05-08 08:48:29 -04:00
D. Scott Boggs 1fede2034e Fix volume spec syntax error 2025-05-08 08:47:47 -04:00
D. Scott Boggs ef79078b06 Fix networks 2025-05-08 08:47:13 -04:00
D. Scott Boggs 76fb9b22ff Secrets can't have spaces 2025-05-08 08:46:32 -04:00
7 changed files with 41 additions and 21 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
**/*.pw
**/*.secret
mounts/

View file

@ -16,7 +16,13 @@ RUN --mount=type=cache,target=/usr/local/cargo,from=rust:latest,source=/usr/loca
cargo build --release --features $adaptor && mv ./target/release/crabfit-api ./api
# Runtime image
FROM debian:bullseye-slim
FROM debian:bookworm-slim
# install libssl3
RUN apt-get update &&\
apt-get install -yq libssl3 &&\
apt-get clean &&\
rm -rf /var/cache/apt/lists/*
# Run as "app" user
RUN useradd -ms /bin/bash app

View file

@ -188,11 +188,14 @@ fn get_connection_string() -> String {
if let Some(password_file_location) = env::var_os("DATABASE_PASSWORD_FILE") {
// The password can be left out of the URL, we add it from the specified
// file (presumably under /run/secrets/)
let password = fs::read(&password_file_location).unwrap_or_else(|err| {
let password = fs::read(&password_file_location)
.unwrap_or_else(|err| {
panic!("could not read database password from {password_file_location:?}\n\t{err:?}")
});
let password = String::from(String::from_utf8_lossy(password.as_slice()));
let password = password.trim_end();
let mut url = Url::parse(&connection_string).expect("invalid connection string");
url.set_password(Some(String::from_utf8_lossy(password.as_slice()).as_ref()))
url.set_password(Some(password))
.unwrap_or_else(|_| panic!("invalid database URL: {connection_string:?}"));
url.to_string()
} else {

View file

@ -35,7 +35,7 @@ pub async fn cleanup<A: Adaptor>(
println!("Error reading CRON_KEY_FILE at {path:?}");
return Err(ApiError::NotAuthorized);
};
String::from_utf8_lossy(key.as_slice()).into()
String::from_utf8_lossy(key.as_slice()).to_owned().trim_end().to_string()
} else {
Default::default()
};

View file

@ -6,51 +6,57 @@ services:
# adaptor: sql-adaptor (default) | memory-adaptor | datastore-adaptor
# # datastore is for Google Datastore
secrets:
- crabfit database password
- crabfit cron key
- crabfit-database-password
- crabfit-cron-key
environment:
DATABASE_PASSWORD_FILE: /run/secrets/crabfit database password
DATABASE_URL: psql://crabfit@crabfit-database:5432/crabfit
DATABASE_PASSWORD_FILE: /run/secrets/crabfit-database-password
DATABASE_URL: postgresql://crabfit@crabfit-database:5432/crabfit
FRONTEND_URL: https://availability.techwork.zone
CRON_KEY_FILE: /run/secrets/crabfit cron key
CRON_KEY_FILE: /run/secrets/crabfit-cron-key
labels:
traefik.enable: true
traefik.http.routers.crabfit-api.rule: Host(`api.a10y.techwork.zone`)
traefik.http.routers.crabfit-api.tls: true
traefik.http.routers.crabfit-api.tls.certresolver: letsencrypt_standalone
networks:
- crabfit-internal
- crabfit
- public
crabfit-database:
image: postgres:17
secrets: [ 'crabfit database password' ]
secrets: [ 'crabfit-database-password' ]
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/crabfit database password
POSTGRES_PASSWORD_FILE: /run/secrets/crabfit-database-password
POSTGRES_USER: crabfit
POSTGRES_DB: crabfit
volumes:
./mounts/database:/var/lib/postgresql/data
- ./mounts/database:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready"]
interval: 30s
timeout: 20s
retries: 3
networks: [ crabfit-internal ]
networks: [ crabfit ]
crabfit-frontend:
build:
context: ./frontend
labels:
traefik.enable: true
traefik.http.routers.crabfit-frontend.rule: (Host(`a10y.techwork.zone`) || Host(`availability.techwork.zone`))
traefik.http.routers.crabfit-frontend.rule: Host(`a10y.techwork.zone`) || Host(`availability.techwork.zone`)
traefik.http.routers.crabfit-frontend.tls: true
traefik.http.routers.crabfit-frontend.tls.certresolver: letsencrypt_standalone
environment:
NEXT_PUBLIC_API_URL: https://api.a10y.techwork.zone
networks: [ public ]
networks:
crabfit:
internal: true
secrets:
crabfit database password:
crabfit-database-password:
file: ./postgres.pw
crabfit cron key:
crabfit-cron-key:
file: ./cron.secret

View file

@ -33,8 +33,8 @@ ENV NODE_ENV=production
# Uncomment the following line in case you want to disable telemetry during runtime.
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1000 nodejs
RUN adduser --system --uid 1000 nextjs
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public

4
frontend/next.config.js Normal file
View file

@ -0,0 +1,4 @@
/** @type {import('next').NextConfig} */
module.exports = {
output: 'standalone'
}