How to zip to 7z for linux & container engineers
- Step 1Confirm TAR.GZ is what you need (it is, here) — For Docker build contexts, Helm packaging, and tar-based deploys you want
.tar.gz— not native 7Z. This tool's output is exactly that, so the '7Z' in the name is a non-issue for container work. - Step 2Convert the incoming ZIP — Open zip-to-7z, drop the
.zip, download the.tar.gz. It is one archive at a time, no options — fflate extracts and re-GZIPs at level 6. - Step 3Check the entry count and tree — The metrics panel shows the entry count. Cross-check it against the ZIP — remember empty directories are dropped, so a count that is short by exactly the number of empty folders is expected, not corruption.
- Step 4Validate before feeding the pipeline — Run
tar -tzf out.tar.gzto list contents and confirm paths are relative (no leading/). If the ZIP had a wrapping top-level folder you do not want in the build context, strip it with path-prefix-remover on the ZIP first. - Step 5Wire it into the build — Use the
.tar.gzdirectly:ADD out.tar.gz /appin a Dockerfile auto-extracts it;tar -xzf out.tar.gz -C ./contextfor a manual build context; or hand it tohelm package-adjacent tooling that expects a gzipped tar. - Step 6Normalise timestamps if the image must be reproducible — Because the TAR header uses the current time, two conversions of the same ZIP produce different mtimes, which can bust Docker layer caching or reproducible-build hashes. If that matters, normalise with timestamp-normalizer before converting.
Where the TAR.GZ output fits in container workflows
The output is a standard gzipped ustar tar. These are the common consumers and whether the raw output drops straight in.
| Consumer | Expects | Drops in directly? | Caveat |
|---|---|---|---|
Dockerfile ADD x.tar.gz /dir | Gzipped tar (auto-extracted) | Yes | Strip wrapping folder first if you don't want it nested |
Manual build context (tar -xzf) | Gzipped tar | Yes | Check paths are relative with tar -tzf |
helm package source dir | A directory of chart files | After tar -xzf | Extract first; Helm wants a dir, not a tarball |
kubectl cp into a pod | Any file; tar for trees | Yes (as a file) | Pod-side tar extracts it |
| Artifact store (Nexus/Artifactory) | Versioned tarball | Yes | Original ZIP timestamps are not carried over |
| Reproducible image build | Stable mtimes | Not as-is | TAR uses 'now'; normalise timestamps first |
ZIP vs the TAR.GZ output for Linux pipelines
Why the conversion is worth it. Verified against the conversion handler's real behaviour.
| Property | Incoming ZIP | Converted TAR.GZ |
|---|---|---|
| Native to Linux tooling | Needs unzip | Native tar -xzf |
Dockerfile ADD auto-extract | No (ZIP not auto-extracted) | Yes (gzipped tar is) |
| File contents | Original | Byte-identical |
| Empty directories | Present as entries | Dropped |
| File timestamps | From ZIP | Set to conversion time |
| Compression algorithm | DEFLATE (ZIP) | DEFLATE (GZIP level 6) |
Cookbook
Pipeline-shaped recipes. Commands assume a Linux host; the conversion itself happens in the browser before any of this.
Windows ZIP into a Docker build context
A teammate sends app-src.zip. Your Dockerfile wants a gzipped tar it can ADD. Convert in the browser, then ADD.
Browser: app-src.zip -> app-src.tar.gz (zip-to-7z) Dockerfile: FROM node:20 ADD app-src.tar.gz /app/ WORKDIR /app RUN npm ci # ADD auto-extracts the .tar.gz into /app — no unzip needed.
List and verify before using as a build input
Always confirm the tree and that paths are relative (no leading slash, which tar would refuse to extract cleanly).
$ tar -tzf app-src.tar.gz | head src/index.ts src/server.ts package.json # Good: relative paths, no leading '/'. Safe to extract.
Strip a wrapping top-level folder
Many ZIPs nest everything under one folder (app-src/...). For a clean build context you often want that gone. Do it on the ZIP first, then convert.
Before: app-src/src/index.ts (everything under app-src/) Step 1: path-prefix-remover on the ZIP -> strips 'app-src/' Step 2: zip-to-7z -> tar.gz with src/index.ts at the root ADD app-src.tar.gz /app -> /app/src/index.ts (not /app/app-src/...)
Reproducible build: normalise timestamps first
The TAR header stamps 'now', so re-converting busts Docker layer caches. Pin timestamps before converting so the same input yields the same tar.
Problem: same app-src.zip -> different mtimes each conversion -> cache miss Step 1: timestamp-normalizer on app-src.zip (set 1980-01-01) Step 2: zip-to-7z -> tar.gz Note: the TAR header still writes conversion time per entry, so for fully reproducible tar, normalise after extraction in CI too.
Convert on a host with no unzip
A hardened bastion has tar but not unzip. Do the ZIP-to-TAR.GZ in the browser on your laptop, scp the result, and the bastion handles it natively.
Laptop browser: build.zip -> build.tar.gz (zip-to-7z) $ scp build.tar.gz bastion:/tmp/ bastion$ tar -xzf /tmp/build.tar.gz -C /opt/app # no unzip required
Edge cases and what actually happens
Empty directories vanish from the build context
Not preservedZIP directory entries (ending in /) are dropped on extraction, so an empty logs/ or tmp/ folder will not exist in the TAR.GZ. If your container expects that directory to pre-exist, create it in the Dockerfile with RUN mkdir -p logs rather than relying on the archive.
Timestamps reset to conversion time
Not preservedThe TAR header writes the current time for every entry. This can bust Docker layer caching and break reproducible-build hashes that depend on mtimes. Normalise with timestamp-normalizer and/or re-normalise after extraction in CI.
Leading-slash or absolute paths in the ZIP
Check before extractIf a ZIP somehow contains absolute paths, tar -xzf may refuse or warn. List with tar -tzf first. The conversion preserves whatever paths the ZIP held; it does not sanitise them. Use filename-sanitizer or path-prefix-remover on the ZIP if needed.
File permissions are not preserved
Defaults appliedZIP and the TAR builder do not carry Unix mode bits the way you might expect — entries are written with default permissions (0644). An executable script in the ZIP will extract without its +x bit, so add RUN chmod +x in the Dockerfile or chmod after extraction.
Archive exceeds the tier cap on a big build context
Rejected (limit)A large monorepo build context can blow past 50 MB (Free) or even 500 MB (Pro). Caps are 50 MB / 500 MB / 2 GB / 2 GB by tier, plus an entry-count cap (500 / 50,000 / 500,000). Split with archive-splitter or upgrade tier.
Symlinks in the source ZIP
FlattenedZIP rarely stores true symlinks, and the TAR builder writes regular-file entries (type '0') only. Any symlink semantics are lost — the target's content (if present) is stored as a plain file. Re-create symlinks in the Dockerfile if your build relies on them.
Encrypted ZIP from a security tool
FailsA password-protected ZIP cannot be converted — this tool has no password field. Decrypt and extract with multi-format-extractor, re-zip the plaintext, then convert.
Expecting a .7z for an artifact store that requires it
By designThe output is .tar.gz, never .7z. For container pipelines that is what you want, but if an artifact store specifically requires 7Z, this tool cannot produce it — use a native 7-Zip on a build agent instead.
Frequently asked questions
I need TAR.GZ for my pipeline — does this tool give me that?
Yes. Despite the 'ZIP to 7Z' name, the output is a standard .tar.gz (TAR + GZIP level 6) — exactly what Docker build contexts, Helm packaging, and tar-based deploys expect. The '7Z' is just the search term people use; the real output is TAR.GZ.
Can a Dockerfile ADD the output directly?
Yes. ADD out.tar.gz /dir auto-extracts a gzipped tar into /dir — no unzip step needed. That is one of the main reasons converting the incoming ZIP to TAR.GZ first is worth it.
Are empty directories preserved?
No. ZIP directory entries are dropped during extraction, so empty folders disappear from the TAR.GZ. If your container needs a directory to pre-exist, create it with RUN mkdir -p in the Dockerfile.
Will file timestamps survive for reproducible builds?
No — the TAR header stamps every entry with the conversion time, not the original ZIP mtime. For reproducible images, normalise with timestamp-normalizer and re-normalise mtimes in CI after extraction.
Does it preserve the +x bit on scripts?
No. Entries are written with default 0644 permissions, so an executable script loses its execute bit. Add RUN chmod +x path/to/script in the Dockerfile or chmod after extraction.
Can I avoid installing unzip on a hardened host?
Yes — convert on your laptop's browser before transferring. The host then only needs tar (which it almost certainly has) to handle the resulting .tar.gz. No unzip/zip required on the host.
Is the content guaranteed unchanged?
Yes — the conversion is byte-lossless on file contents. Verify build inputs with checksum-generator on the extracted files; the hashes match the originals.
What about symlinks?
Symlinks are not preserved. The TAR builder writes regular-file entries only, so any symlink semantics are flattened. Re-create needed symlinks in your Dockerfile or post-extract script.
Does the archive leave my machine?
No. The conversion runs entirely in the browser with fflate — proprietary build inputs in the ZIP never get uploaded. This matters when the archive contains internal source or secrets-adjacent config.
How do I strip a wrapping top-level folder before building?
Run path-prefix-remover on the ZIP to strip the leading app-src/-style prefix, then convert. The resulting TAR.GZ has files at the root, so ADD lands them where you expect without an extra nesting level.
What's the size limit for a big monorepo context?
Free caps at 50 MB / 500 entries, Pro at 500 MB / 50,000, Pro-media and Developer at 2 GB / 500,000. A large build context may need an upgrade or a split with archive-splitter.
Is there a reverse tool for incoming TAR.GZ from Windows users?
Yes — tar-gz-to-zip converts the other way for colleagues who need a ZIP. For mixed conversions use archive-format-converter.
Privacy first
Every JAD Archive tool runs entirely in your browser using fflate, @zip.js/zip.js, and the libarchive WASM bridge. Your archives never leave your device — verified by zero outbound network requests during processing.