How can I build my own billionmail/core image?
How can I build a custom image of billionmail/core myself? I want to customize some parts of the UI as well as the API, but I don't know how to build the image.
This is simple way to customize your BillionMail.
- Setup Golang developmenr environment in your server.
- Change the codes and compile.
- Use
docker cpcommand to replace containerbillionmail–core–billionmail-1:/opt/billionmail/core/billionmailbinary file. - Restart cotainer to check it.
Hi,
There may be a better approach than this, but here’s how I managed to rebuild billionmail/core locally and apply my UI changes. These steps assume you’re using Docker Compose.
- Modify
docker-compose.yml
In your BillionMail/docker-compose.yml, locate the core-billionmail service and replace its image: line with a build: block. For example:
core-billionmail: # BillionMail management panel and Roundcube frontend
# image: billionmail/core:1.5
build:
context: .
dockerfile: ./Dockerfiles/core/Dockerfile
This tells Docker Compose to build the image from your local Dockerfiles/core/Dockerfile rather than pulling billionmail/core:1.5 from Docker Hub.
- Create or replace
Dockerfiles/core/Dockerfile
Create a new BillionMail/Dockerfiles/core/Dockerfile (or overwrite the existing one) with the following content:
FROM alpine:3.20
LABEL maintainer="https://github.com/aaPanel/BillionMail"
# Set environment variables
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
ARG TARGETARCH
# Copy the prebuilt core binary and static assets
COPY core/billionmail-${TARGETARCH} /opt/billionmail/core/billionmail
COPY core/manifest /opt/billionmail/core/manifest
COPY core/languages /opt/billionmail/core/languages
COPY core/public /opt/billionmail/core/public
COPY core/resource /opt/billionmail/core/resource
# Copy custom scripts
COPY ./Dockerfiles/core/stop-supervisor.sh /stop-supervisor.sh
COPY ./Dockerfiles/core/core.sh /core.sh
COPY ./Dockerfiles/core/restart_fail2ban.sh /restart_fail2ban.sh
COPY ./Dockerfiles/core/supervisord.conf /etc/supervisor/supervisord.conf
# Install required packages
RUN apk add --no-cache \
bash \
ca-certificates \
curl \
supervisor \
rsyslog \
tzdata \
busybox-extras \
postgresql-client \
fail2ban \
iptables \
ipset \
&& rm -rf /var/cache/apk/* \
&& chmod +x /stop-supervisor.sh /core.sh /restart_fail2ban.sh /opt/billionmail/core/billionmail
ENTRYPOINT ["/core.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
- Build the
billionmailcore binary
By default, the core/ directory does not contain the compiled billionmail executable. To generate it, run the same commands as in BillionMail/core/go-build.sh. For example:
# From the project root (where docker-compose.yml lives)
cd /opt/BillionMail
# Start an Alpine container with the code mounted for compilation
docker run -d \
--name p-g-alpine \
--hostname p-g-alpine \
--restart=always \
-v "$(pwd)/core:/opt/core" \
-v "$(pwd)/Dockerfiles/core/repositories:/etc/apk/repositories" \
alpine:3.20 tail -f /dev/null
# Enter the container shell
docker exec -it p-g-alpine sh
# Inside the container, navigate to /opt/core and run the build script
cd /opt/core
sh go-build.sh
After go-build.sh finishes, you should see core/billionmail-<arch> appear in your local core/ folder. You can then exit the container:
exit
docker stop p-g-alpine
docker rm p-g-alpine
-
Customize the frontend (UI)
-
Modify UI source files Edit the frontend code you need.
-
Create a
deploy.jsscript After building the frontend, you need to copy the compiled assets intocore/public/dist. Createbillionmail/core/frontend/deploy.jswith:// deploy.js import fs from 'fs'; import path from 'path'; import fse from 'fs-extra'; import { fileURLToPath } from 'url'; // Polyfill __dirname const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const srcDir = path.resolve(__dirname, 'dist'); const destDir = path.resolve(__dirname, '../public/dist'); // Remove old dist folder, if it exists if (fs.existsSync(destDir)) { fse.removeSync(destDir); } // Copy new build artifacts fse.copySync(srcDir, destDir); console.log('Copied build artifacts to:'); console.log(destDir); -
Add
SERVER_NAMEto environment filesSERVER_NAME=192.168.66.66 -
Install dependencies and build In your local environment (with Node.js + pnpm installed), run:
cd billionmail/core/frontend pnpm install pnpm add fs-extra # ‹deploy.js› relies on fs-extra pnpm buildAt this point,
core/public/distcontains your customized UI.
-
Rebuild and start the
core-billionmailservice -
Return to the project root (where your
docker-compose.ymlis located):cd /path/to/BillionMail -
Build the
core-billionmailimage (no cache):docker compose build --no-cache core-billionmail -
Start the containers:
docker compose up -d