Docker Deployment
Deploy from GHCR with Compose, port binding, and optional reverse proxy examples.
Docker Deployment
BoxBox builds into one container: Bun compiles the SvelteKit frontend, Go embeds those static files, and the runtime image starts one HTTP server on port 80.
Prerequisites
- Docker 24+ or a recent Docker Engine.
- Docker Compose v2 if using
docker-compose.yml. - A Linux host if you want accurate system drive discovery and mount propagation.
Preferred Deployment
Deploy BoxBox with Docker Compose using the published GitHub Container Registry image. This is the recommended path for servers because it does not require cloning the repository and keeps updates simple.
Download the deployment files, edit the environment, then start the published image:
mkdir -p boxbox
cd boxbox
curl -fsSLO https://raw.githubusercontent.com/jR4dh3y/BoxBox/master/docker-compose.yml
curl -fsSLO https://raw.githubusercontent.com/jR4dh3y/BoxBox/master/.env.example
mkdir -p backend
curl -fsSL https://raw.githubusercontent.com/jR4dh3y/BoxBox/master/backend/config.yaml -o backend/config.yaml
cp .env.example .env
$EDITOR .env
docker compose pull
docker compose up -d
Set these values in .env before starting:
FM_JWT_SECRET=generate-a-long-random-secret
FM_USERS_admin=replace-this-password
HOST_PORT=8080
HOME_PATH=/home/your-user
BOXBOX_IMAGE=ghcr.io/jr4dh3y/boxbox:latest
Open http://localhost:8080, or use the host and port you configured with HOST_PORT.
Published Images
Release images are published to GitHub Container Registry:
docker pull ghcr.io/jr4dh3y/boxbox:latest
The publish workflow runs when a v* git tag is pushed. It publishes the tag name and updates latest.
git tag v0.1.0
git push origin v0.1.0
Optional: Reverse Proxy or Traefik
The default compose file uses normal host port binding and does not require Traefik. If you want to put BoxBox behind Traefik, remove the ports entry, attach the service to your Traefik network, and add labels for your router.
services:
filemanager:
labels:
- "traefik.enable=true"
- "traefik.http.routers.boxbox.rule=Host(`boxbox.example.test`)"
- "traefik.http.routers.boxbox.entrypoints=web"
- "traefik.http.services.boxbox.loadbalancer.server.port=80"
networks:
- proxy
networks:
proxy:
external: true
For public or semi-public access, put TLS and access controls on your reverse proxy before exposing BoxBox beyond a trusted network.
Alternative: Simple Local Container
Use this path when you want a quick local test without Compose. It still uses the published GHCR image.
mkdir -p boxbox
cd boxbox
cat > config.yaml <<'EOF'
port: 80
host: "0.0.0.0"
jwt_secret: "replace-this-with-a-long-random-secret"
mount_points:
- name: "home"
path: "/home/user"
read_only: false
EOF
docker pull ghcr.io/jr4dh3y/boxbox:latest
docker run -d \
--name boxbox \
-p 8080:80 \
-e FM_JWT_SECRET="$(openssl rand -base64 32)" \
-e FM_USERS_admin="replace-this-password" \
-v "$PWD/config.yaml:/app/config.yaml:ro" \
-v "$HOME:/home/user" \
-v boxbox-data:/data \
-v boxbox-temp:/tmp/filemanager \
ghcr.io/jr4dh3y/boxbox:latest
Open http://localhost:8080 and sign in as admin with the password you set in FM_USERS_admin.
Alternative: Local Source Builds
Cloning the repository is supported, but it is not the preferred deployment method. Use this path only when you want to build the image from source instead of pulling the published GHCR image.
git clone https://github.com/jR4dh3y/BoxBox.git
cd BoxBox
docker build -t boxbox:local .
For compose, set BOXBOX_IMAGE=boxbox:local in .env, then run docker compose up -d.
Volumes
The default compose file mounts:
| Host path | Container path | Why |
|---|---|---|
./backend/config.yaml |
/app/config.yaml |
Runtime configuration. |
/media/devmon |
/media/devmon |
Auto-discovered removable drives. |
/ |
/host_root |
Host root browsing. High blast radius. |
${HOME_PATH} |
/home/user |
User home directory browsing. |
filemanager-temp |
/tmp/filemanager |
Chunked upload assembly. |
filemanager-data |
/data |
Persistent app data, including custom drive names. |
Use :ro on a volume or read_only: true in config.yaml when a path should never be modified through BoxBox.
Mount Propagation
The compose file uses rslave for host mount paths so new host mounts can appear inside the container. This matters for removable drives and some NAS/rclone mounts.
volumes:
- /media/devmon:/media/devmon:rslave
- /:/host_root:rslave
Updating
docker compose pull
docker compose up -d
For local source builds:
git pull
docker build --no-cache -t boxbox:local .
docker compose up -d
For a docker run deployment:
docker pull ghcr.io/jr4dh3y/boxbox:latest
docker stop boxbox
docker rm boxbox
# Re-run the docker run command with the same volumes and env values.
Health and Logs
curl http://localhost:8080/health
docker compose ps
docker compose logs -f filemanager
The health response is:
{"status":"ok"}
Permission Notes
The container runs with a small set of Linux capabilities in compose so it can read and manage a variety of host-owned files without full privileged mode. If a path still returns permission errors, check the host path permissions and consider narrowing BoxBox to directories owned by a consistent user or group.