mirror of
https://github.com/thegeneralist01/archivr
synced 2026-07-21 18:55:36 +02:00
chore: add Dockerfile, docker-compose, and Docker hosting docs (#12)
* chore: add Dockerfile, docker-compose, and Docker docs - Multi-stage Dockerfile: Rust builder stage + debian:bookworm-slim runtime with Chromium, Node/single-file-cli, Python venv (yt-dlp + twitter-api-client) - docker-compose.yml: wires ARCHIVR_BIND, config volume, and persistent data volume - docker/config.example.toml: annotated TOML template for Docker deployments - docs/README.md: add Hosting with Docker section; add ARCHIVR_BIND and ARCHIVR_STATIC_DIR to the Environment Variables reference * fix: address code review issues with Docker setup - .gitignore: whitelist Dockerfile, docker-compose.yml, docker/ so they are actually tracked (the * catch-all was silently dropping them) - Dockerfile: build and ship the archivr CLI alongside archivr-server so users can run `archivr init` inside the container on first setup - docker/config.example.toml: fix archive_path to point at the .archivr subdirectory that archivr init creates (not the parent directory), which is what read_archive_paths expects - docs/README.md: replace the bare mkdir quickstart step with `archivr init`, explain why mkdir is insufficient; add a callout that auth_db_path must be set explicitly to a writable path when the config mount is read-only * fix: address second round of Docker review issues Chromium sandbox (P2): - singlefile.rs: add ARCHIVR_CHROME_ARGS env var (space-separated flags appended to Chromium's --browser-args JSON array); Dockerfile sets it to --no-sandbox because Chromium refuses to start as root without it Store-path outside volume (P1): - README: pass explicit absolute store-path as the second positional arg to `archivr init` so the blob store lands on /data instead of the container layer (CLI default is ./.archivr/store, resolved from cwd, which is / with no WORKDIR set) ENTRYPOINT vs CMD (P2): - Dockerfile: switch from ENTRYPOINT to CMD so `docker compose run archivr archivr init …` overrides the full command instead of being appended to the server invocation ffmpeg missing (P2): - Dockerfile: add ffmpeg to the apt-get install block (required by yt-dlp --merge-output-format mp4 for bestvideo+bestaudio streams) Node version (P2): - Dockerfile: replace Debian bookworm's nodejs (18.x) with Node 20 via the NodeSource setup script (single-file-cli declares engines.node >=20) Build context secrets (P2): - Add .dockerignore excluding config/ and docker/ from the build context so runtime secrets (e.g. twitter-cookies.txt) are never sent to the builder - Whitelist .dockerignore in .gitignore docs: - README: document ARCHIVR_CHROME_ARGS in the Environment Variables section * fix: third round of Docker review issues Rust toolchain (P1): - Dockerfile: bump builder from rust:1.87 to rust:1.88; time@0.3.51, time-core@0.1.9, and time-macros@0.2.30 (present in Cargo.lock) all require MSRV 1.88, so the real cargo build --release step was failing single-file-cli wait mode (P2): - singlefile.rs: replace --browser-wait-until=networkidle2 with networkAlmostIdle; the single-file-cli option only accepts InteractiveTime/networkIdle/networkAlmostIdle/load/domContentLoaded (verified in options.js); networkidle2 is a Puppeteer concept that the CLI does not recognise, causing silent fallback to the earliest state and incomplete captures. networkAlmostIdle is the closest equivalent (<=2 open connections, matching Puppeteer's networkidle2 semantics) Build context size (P3): - .dockerignore: add target/, frontend/node_modules/, frontend/dist/; these can reach 1.4G+ after a local dev build and are never read by the Dockerfile, so sending them to the builder wastes time and memory
This commit is contained in:
parent
685b6cc7ea
commit
2414acf0df
7 changed files with 279 additions and 8 deletions
|
|
@ -68,18 +68,30 @@ fn save_with(
|
|||
// without a writable user-data-dir. Using a subdirectory of temp_dir
|
||||
// keeps it isolated and it gets cleaned up with the rest of the temp dir.
|
||||
let chrome_data_dir = temp_dir.join("chrome-data");
|
||||
let browser_args = format!(
|
||||
"[\"--disable-web-security\",\"--user-data-dir={}\"]",
|
||||
chrome_data_dir.display()
|
||||
);
|
||||
// Build the browser-args JSON array. Start with the flags always required,
|
||||
// then append any extra flags from ARCHIVR_CHROME_ARGS (space-separated).
|
||||
// Docker containers running as root need "--no-sandbox" here because
|
||||
// Chromium refuses to start as root without it.
|
||||
let mut chrome_flags = vec![
|
||||
"--disable-web-security".to_string(),
|
||||
format!("--user-data-dir={}", chrome_data_dir.display()),
|
||||
];
|
||||
if let Ok(extra) = std::env::var("ARCHIVR_CHROME_ARGS") {
|
||||
chrome_flags.extend(extra.split_whitespace().filter(|s| !s.is_empty()).map(str::to_string));
|
||||
}
|
||||
let quoted: Vec<String> = chrome_flags
|
||||
.iter()
|
||||
.map(|f| format!("\"{}\"", f.replace('\\', "\\\\").replace('"', "\\\"")))
|
||||
.collect();
|
||||
let browser_args = format!("[{}]", quoted.join(","));
|
||||
|
||||
let out = Command::new(single_file)
|
||||
.arg(url)
|
||||
.arg(&out_file)
|
||||
.arg(format!("--browser-executable-path={chrome}"))
|
||||
.arg("--browser-headless")
|
||||
.arg("--browser-wait-until=networkidle2")
|
||||
// Extra delay after networkidle2: Cloudflare Fonts injects @font-face
|
||||
.arg("--browser-wait-until=networkAlmostIdle")
|
||||
// Extra delay after networkAlmostIdle: Cloudflare Fonts injects @font-face
|
||||
// CSS after HTML parse, so the font hook needs more time to see it.
|
||||
.arg("--browser-wait-delay=2000")
|
||||
// Realistic UA: some origins block headless Chrome's default UA string.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue