Docker image for FastBCP, a high-performance bulk copy tool
5.4K
Minimal, production‑ready container image to run FastBCP (parallel export CLI), a high-performance bulk copy utility designed for data integration and automation workflows.
This setup targets FastBCP ≥ 0.28.0, which supports passing the license inline via --license "<content>".
debian:trixie-slim/usr/local/bin/FastBCPFor custom builds
The FastBCP binary is not distributed in this repository. Request the Linux x64 build here:
FastBCP trial. Unzip and place it at the repository root (next to theDockerfile), then build your own custom image.
FastBCP_Settings.json to mount/copy into /config for custom logging settingsfastbcp and ensure it is executable if testing locally:
chmod +x fastbcp
Dockerfile).docker build -t fastbcp:latest .
docker run --rm fastbcp:latest --version
This container has ENTRYPOINT set to the fastbcp binary. Any arguments you pass to docker run are forwarded to FastBCP.
docker run --rm fastbcp:latest --help
You can use a prebuilt image from DockerHub that already includes the FastBCP binary. You must provide your own license at runtime.
DockerHub repository: arpeio/fastbcp
v0.28.3)latest tag always points to the most recent FastBCP versionv0.28.8 (latest of 0.28.x branch), it gets security updates even after v0.29.0 is released# Latest version
docker pull arpeio/fastbcp:latest
# Specific version
docker pull arpeio/fastbcp:v0.28.3
# Get help
docker run --rm arpeio/fastbcp:latest
# Check version
docker run --rm arpeio/fastbcp:latest --version
The Docker image uses the FastBCP binary as its entrypoint, so you can run it directly with parameters as defined in the FastBCP documentation.
# Get command line help
docker run --rm arpeio/fastbcp:latest
# Check version
docker run --rm arpeio/fastbcp:latest --version
Since version 0.28.0, pass the license content directly via --license "…".
export licenseContent=$(cat ./FastBCP.lic)
# Use $licenseContent in your docker run commands
docker run --rm arpeio/fastbcp:latest \
--license "$licenseContent" \
[other parameters...]
Best practice: Prefer --env-file, Docker/Compose/Kubernetes secrets, or managed identities for cloud credentials. Avoid leaving the license content in shell history.
The exact parameters depend on your source and target settings. The snippets below illustrate the call pattern from Docker in a Linux shell.
export licenseContent=$(cat ./FastBCP.lic)
docker run --rm \
-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
-e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
-e AWS_REGION=${AWS_REGION} \
arpeio/fastbcp:latest \
--connectiontype "mssql" \
--server "host.docker.internal,1433" \
--user "FastUser" \
--password "FastPassword" \
--database "tpch_test" \
--query "SELECT * FROM dbo.orders WHERE year(o_orderdate)=1998" \
--fileoutput "orders.parquet" \
--directory "s3://arpeioftoutput/dockertest/" \
--paralleldegree 12 \
--parallelmethod "Ntile" \
--distributekeycolumn "o_orderkey" \
--merge false \
--license "$licenseContent"
export licenseContent=$(cat ./FastBCP.lic)
docker run --rm \
-v fastbcp-config:/config \
-v fastbcp-data:/data \
-v fastbcp-logs:/logs \
arpeio/fastbcp:latest \
--settingsfile "/config/FastBCP_Settings_Logs_To_Files.json" \
--connectiontype "mssql" \
--server "host.docker.internal,1433" \
--user "FastUser" \
--password "FastPassword" \
--database "tpch_test" \
--query "SELECT * FROM dbo.orders WHERE year(o_orderdate)=1998" \
--fileoutput "orders.csv" \
--directory "/data/orders/csv" \
--delimiter "|" \
--decimalseparator "." \
--dateformat "yyyy-MM-dd HH:mm:ss" \
--paralleldegree 12 \
--parallelmethod "Ntile" \
--distributekeycolumn "o_orderkey" \
--merge false \
--license "$licenseContent"
export licenseContent=$(cat ./FastBCP.lic)
export adlscontainer="arpeioadlseu"
docker run --rm \
-e AZURE_CLIENT_ID=${AZURE_CLIENT_ID} \
-e AZURE_TENANT_ID=${AZURE_TENANT_ID} \
-e AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET} \
arpeio/fastbcp:latest \
--connectiontype "pgcopy" \
--server "host.docker.internal:15432" \
--user "FastUser" \
--password "FastPassword" \
--database "tpch" \
--sourceschema "tpch_10" \
--sourcetable "orders" \
--query "SELECT * FROM tpch_10.orders WHERE o_orderdate >= '1998-01-01' AND o_orderdate < '1999-01-01'" \
--fileoutput "orders.parquet" \
--directory "abfss://${adlscontainer}.dfs.core.windows.net/fastbcpoutput/testdfs/orders" \
--paralleldegree -2 \
--parallelmethod "Ctid" \
--license "$licenseContent"
export licenseContent=$(cat ./FastBCP.lic)
export gcsbucket="arpeio-gcs-bucket"
export GOOGLE_APPLICATION_CREDENTIALS_JSON=$(cat ./gcp-credentials.json)
docker run --rm \
-e GOOGLE_APPLICATION_CREDENTIALS="${GOOGLE_APPLICATION_CREDENTIALS_JSON}" \
arpeio/fastbcp:latest \
--connectiontype "oraodp" \
--server "host.docker.internal:1521/FREEPDB1" \
--user "TPCH_IN" \
--password "TPCH_IN" \
--database "FREEPDB1" \
--sourceschema "TPCH_IN" \
--sourcetable "ORDERS" \
--fileoutput "orders.parquet" \
--directory "gs://${gcsbucket}/fastbcpoutput/testgs/orders" \
--parallelmethod "Rowid" \
--paralleldegree -2 \
--license "$licenseContent"
The Docker image declares several volumes to organize data and configuration:
VOLUME ["/config", "/data", "/work", "/logs"]
| Volume Path | Description | Access Mode | Typical Usage |
|---|---|---|---|
/config | Contains user-provided configuration files (e.g., Serilog settings) | Read-only / Read-many | Shared across multiple containers; not modified |
/data | Input/output data directory | Read-many/Write-many | Stores imported or exported data files |
/work | Temporary working directory (container WORKDIR) | Read-many/Write-many | Used internally for temporary processing |
/logs | Log output directory (per-run or aggregated logs) | Read-many/Write-many | Stores runtime and execution logs |
Available starting from version v0.28.3
FastBCP supports custom logging configuration through an external Serilog settings file in JSON format. This allows you to control how and where logs are written — to the console, to files, or dynamically per run.
You can download an example logging settings file directly from GitHub:
FastBCP_Settings_Logs_To_Files.json
Custom settings files must be mounted into the container under the /config directory.
The following configuration is recommended for most production or Airflow environments. It writes:
/airflow/xcom/return.json for Airflow integration/logs, automatically named with {LogTimestamp} and {TraceId}{
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File",
"Serilog.Enrichers.Environment",
"Serilog.Enrichers.Thread",
"Serilog.Enrichers.Process",
"Serilog.Enrichers.Context",
"Serilog.Formatting.Compact"
],
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-ddTHH:mm:ss.fff zzz} -|- {Application} -|- {runid} -|- {Level:u12} -|- {fulltargetname} -|- {Message}{NewLine}{Exception}",
"theme": "Serilog.Sinks.SystemConsole.Themes.ConsoleTheme::None, Serilog.Sinks.Console",
"applyThemeToRedirectedOutput": false
}
},
{
"Name": "File",
"Args": {
"path": "/airflow/xcom/return.json",
"formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact"
}
},
{
"Name": "Map",
"Args": {
"to": [
{
"Name": "File",
"Args": {
"path": "/logs/{logdate}/{sourcedatabase}/log-{filename}-{LogTimestamp}-{TraceId}.json",
"formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact",
"rollingInterval": "Infinite",
"shared": false,
"encoding": "utf-8"
}
}
]
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId"
],
"Properties": {
"Application": "FastBCP"
}
}
}
Important notes:
/logs or /airflow/xcom) does not exist, FastBCP automatically creates it./airflow/xcom/return.json is designed to provide run summaries compatible with Airflow’s XCom mechanism.You can use the following placeholders to dynamically generate log file names or directories:
| Token Name | Description |
|---|---|
{logdate} | Current date in yyyy-MM-dd format |
{logtimestamp} | Full timestamp of the log entry |
{sourcedatabase} | Name of the source database |
{sourceschema} | Name of the source schema |
{sourcetable} | Name of the source table |
{filename} | Name of the file being processed |
{runid} | Run identifier provided in the command line |
{traceid} | Unique trace identifier generated at runtime |
Your Serilog configuration file (for example, FastBCP_Settings_Logs_To_Files.json) must be placed in /config,
either by mounting a local directory or by using a Docker named volume.
Example with named volumes:
# First, copy your config file to a volume location
cp ~/FastBCP_Settings_Logs_To_Files.json /volumes/fastbcp-config/
# Then run FastBCP with mounted volumes
docker run --rm \
-v fastbcp-config:/config \
-v fastbcp-data:/data \
-v fastbcp-logs:/logs \
arpeio/fastbcp:latest \
--settingsfile "/config/FastBCP_Settings_Logs_To_Files.json" \
--connectiontype "mssql" \
--server "host.docker.internal,1433" \
--user "FastUser" \
--password "FastPassword" \
--database "tpch_test" \
--query "SELECT * FROM dbo.orders" \
--fileoutput "orders.csv" \
--directory "/data" \
--paralleldegree 12 \
--parallelmethod "Ntile" \
--distributekeycolumn "o_orderkey" \
--merge false \
--license "$licenseContent"
If the --settingsfile argument is not provided, FastBCP will use its built-in default logging configuration.
/data on fast storage (NVMe) when exporting large datasets locally.--parallel according to CPU and I/O throughput.--add-host=host.docker.internal:host-gateway (or the extra_hosts entry in Compose).--env-file) and managed identities (IAM Role / IRSA / Workload Identity / Managed Identity).chmod +x fastbcp).libicu/libssl/zlib/krb5 → the image includes libicu76, libssl3, zlib1g, libkrb5-3. If your build requires additional libs, add them via apt./data → ensure the host directory permissions match the container UID (10001).--add-host=host.docker.internal:host-gateway or the Compose extra_hosts equivalent.Content type
Image
Digest
sha256:350131a4b…
Size
146.5 MB
Last updated
4 days ago
docker pull arpeio/fastbcp