UPDATE:
The on-premise version of Mailsac has been ended. Contact [email protected] to learn more about our dedicated instances instead, or visit mailsac.com/enterprise.
On-Premise Mailsac now comes with the Dockerfiles and docker-compose.yml to get up and running in seconds using Docker.
Each Mailsac microservice can be run independently with Docker. A convenient Makefile is included alongside the Dockerfile in each service, with a sample task for running in docker (make docker-run
).
Frontend API+UI example:
$ cd frontend
$ make docker-run
docker build -t mailsac/frontend .
Sending build context to Docker daemon 4.34MB
Step 1/7 : FROM node:8-alpine
---> 406f227b21f5
Step 2/7 : RUN apk update && apk add git
---> Using cache
---> d4e543b7bbe6
Step 3/7 : COPY . /opt/frontend
---> c23657034aba
Step 4/7 : WORKDIR /opt/frontend
Removing intermediate container 776dfd90f8e7
---> 5558d5ac56ab
Step 5/7 : RUN npm i --production
---> Running in 3b4298ca4ae0
added 333 packages in 12.184s
Removing intermediate container 3b4298ca4ae0
---> 8adfac5691b0
Step 6/7 : EXPOSE 3000
---> Running in 3070214927bd
Removing intermediate container 3070214927bd
---> 199808362a19
Step 7/7 : CMD node app.js
---> Running in e5ceede43634
Removing intermediate container e5ceede43634
---> 3dafbb6f3f2e
Successfully built 3dafbb6f3f2e
Successfully tagged mailsac/frontend:latest
docker run --rm -d -p 0.0.0.0:3000:3000 --name=mailsac mailsac/frontend
9533f06a0751e1a7ebb67de93b563e14679fed634d567728d81681fc99d6211d
docker logs -f frontend
------ Mailsac ------
connecting to mongo
started message disk cache
connected to mongo
Inbound SMTP server:
$ make docker-run
go build -ldflags '-s -w -X main.gitversion=v15.0.1'
docker build --no-cache -t mailsac/inbound .
Sending build context to Docker daemon 4.619MB
Step 1/5 : FROM alpine
---> 3fd9065eaf02
Step 2/5 : COPY inbound /opt/inbound
---> 1d14457a75fc
Step 3/5 : WORKDIR /opt
Removing intermediate container a97ae6ac27e0
---> a4230e86d399
Step 4/5 : EXPOSE 25 587
---> Running in e43b166f773e
Removing intermediate container e43b166f773e
---> 4bdc6745ff78
Step 5/5 : ENTRYPOINT ["/opt/inbound"]
---> Running in b812c4442101
Removing intermediate container b812c4442101
---> 620d169d15f1
Successfully built 620d169d15f1
Successfully tagged mailsac/inbound:latest
docker run --rm -d -p 0.0.0.0:25:25 -p 0.0.0.0:587:587 --name=inbound mailsac/inbound
cef23b5af410f0f5663727ad1c16cda5d070d3232ad2d5ee94db5b64562ad513
docker logs -f inbound
syslog connected:127.0.0.1:514
Starting server on port 587
Starting server on port 25
A sample docker-compose.yml file is also included. As a result you can have a fully running set of Mailsac services without even deploying it, in seconds. It should serve as a good starting point for understanding how the services talk to each other, and setting up your own deployment using pure Docker, Docker + Ansible, or an orchestrator like Kubernetes.
$ docker-compose up --build
Building relay
Step 1/7 : FROM node:8-alpine
---> 406f227b21f5
Step 2/7 : RUN apk update && apk add git
---> Using cache
---> d4e543b7bbe6
Step 3/7 : COPY . /opt/relay
---> Using cache
---> bdd144f2089f
Step 4/7 : WORKDIR /opt/relay
---> Using cache
---> 58a37f36a693
Step 5/7 : RUN npm i --production
---> Using cache
---> c0be4245ebf6
Step 6/7 : EXPOSE 3007
---> Using cache
---> 88c4d2f6c6b9
Step 7/7 : CMD node server.js
---> Using cache
---> f5b8551d0fbd
Successfully built f5b8551d0fbd
Successfully tagged ms2_relay:latest
Building notifier
Step 1/4 : FROM alpine
---> 3fd9065eaf02
Step 2/4 : COPY notifier /opt/notifier
---> Using cache
---> 5ee53ef401f3
Step 3/4 : EXPOSE 8080
---> Using cache
---> 57fb8f8fe110
Step 4/4 : ENTRYPOINT /opt/notifier
---> Using cache
---> 35ac15e5cc01
Successfully built 35ac15e5cc01
Successfully tagged ms2_notifier:latest
Building frontend
Step 1/7 : FROM node:8-alpine
---> 406f227b21f5
Step 2/7 : RUN apk update && apk add git
---> Using cache
---> d4e543b7bbe6
Step 3/7 : COPY . /opt/frontend
---> 37b9ad50d96f
Step 4/7 : WORKDIR /opt/frontend
Removing intermediate container a2b4b26dbac3
---> 0d1c573b307b
Step 5/7 : RUN npm i --production
---> Running in 535408d85bd6
npm WARN deprecated [email protected]: This project is unmaintained
npm notice created a lockfile as package-lock.json. You should commit this file.
added 333 packages in 11.041s
Removing intermediate container 535408d85bd6
---> 95016c15e489
Step 6/7 : EXPOSE 3000
---> Running in 4879a888ecea
Removing intermediate container 4879a888ecea
---> a086e8e90f50
Step 7/7 : CMD node app.js
---> Running in 834c6bc77297
Removing intermediate container 834c6bc77297
---> 3a815540ed78
Successfully built 3a815540ed78
Successfully tagged ms2_frontend:latest
Building outbound
Step 1/5 : FROM alpine
---> 3fd9065eaf02
Step 2/5 : COPY outbound /opt/outbound
---> Using cache
---> 76eba650e12d
Step 3/5 : EXPOSE 587
---> Using cache
---> 15e317117cf7
Step 4/5 : WORKDIR /opt
---> Using cache
---> 8e337b87460e
Step 5/5 : ENTRYPOINT ["/opt/outbound"]
---> Using cache
---> 755c189ce229
Successfully built 755c189ce229
Successfully tagged ms2_outbound:latest
Building pop3
Step 1/4 : FROM alpine
---> 3fd9065eaf02
Step 2/4 : COPY pop3 /opt/pop3
---> Using cache
---> 23743111b4ae
Step 3/4 : EXPOSE 9090 110
---> Using cache
---> 757d6120f3c3
Step 4/4 : ENTRYPOINT /opt/pop3
---> Using cache
---> 4f9969d09d90
Successfully built 4f9969d09d90
Successfully tagged ms2_pop3:latest
Building inbound
Step 1/5 : FROM alpine
---> 3fd9065eaf02
Step 2/5 : COPY inbound /opt/inbound
---> fbf61d35f8af
Step 3/5 : WORKDIR /opt
Removing intermediate container 7ed35fdd8d8a
---> dbf3f6c46c4d
Step 4/5 : EXPOSE 25 587
---> Running in 0ffeb91b767e
Removing intermediate container 0ffeb91b767e
---> dffa069abe07
Step 5/5 : ENTRYPOINT ["/opt/inbound"]
---> Running in f1cf5e565847
Removing intermediate container f1cf5e565847
---> 841f16e95ee1
Successfully built 841f16e95ee1
Successfully tagged ms2_inbound:latest
Building filer
Step 1/4 : FROM alpine
---> 3fd9065eaf02
Step 2/4 : COPY filer /opt/filer
---> Using cache
---> a700eb91ac4d
Step 3/4 : EXPOSE 3005
---> Using cache
---> 8e2c5401bf0a
Step 4/4 : ENTRYPOINT /opt/filer
---> Using cache
---> 1b578459a892
Successfully built 1b578459a892
Successfully tagged ms2_filer:latest
Starting ms2_mongo_1 ...
Starting ms2_mongo_1 ... done
Starting ms2_notifier_1 ... done
Recreating ms2_frontend_1 ... done
Recreating ms2_inbound_1 ...
Recreating ms2_filer_1 ...
Recreating ms2_pop3_1 ...
Recreating ms2_inbound_1 ... done
Attaching to ms2_relay_1, ms2_mongo_1, ms2_notifier_1, ms2_frontend_1, ms2_filer_1, ms2_pop3_1, ms2_outbound_1, ms2_inbound_1
relay_1 | starting app server on port 3007
notifier_1 |
mongo_1 | 2018-03-11T23:20:13.328+0000 I CONTROL [initandlisten] MongoDB starting : pid=1 port=27017 dbpath=/data/db 64-bit host=d2b548e5f949
notifier_1 | ---- Mailsac Notifier Startup ----
notifier_1 |
mongo_1 | 2018-03-11T23:20:13.328+0000 I CONTROL [initandlisten] db version v3.6.2
relay_1 | verifyKeys failed Skipping default domain DKIM verificiation due to missing private key file
notifier_1 | Connecting to db at mongo:27017
mongo_1 | 2018-03-11T23:20:13.328+0000 I CONTROL [initandlisten] git version: 489d177dbd0f0420a8ca04d39fd78d0a2c539420
mongo_1 | 2018-03-11T23:20:13.329+0000 I CONTROL [initandlisten] OpenSSL version: LibreSSL 2.6.3
frontend_1 | No YAML parser loaded. Suggest adding js-yaml dependency to your package.json file.
relay_1 | mailsac relay server listening on port 3007
mongo_1 | 2018-03-11T23:20:13.329+0000 I CONTROL [initandlisten] allocator: system
filer_1 | syslog connected:127.0.0.1:514
pop3_1 | syslog connected: 127.0.0.1:514
mongo_1 | 2018-03-11T23:20:13.330+0000 I CONTROL [initandlisten] modules: none
filer_1 |
filer_1 | ---- Mailsac Filer Startup ----
filer_1 |
outbound_1 | syslog connected:127.0.0.1:514
mongo_1 | 2018-03-11T23:20:13.330+0000 I CONTROL [initandlisten] build environment:
mongo_1 | 2018-03-11T23:20:13.330+0000 I CONTROL [initandlisten] distarch: x86_64
pop3_1 | ---- Mailsac POP3 Server and HTTP Server Startup 0.0.0.0 ----
pop3_1 | mailsac base api is http://frontend:3000
pop3_1 | Started pop3 server on port 1100
inbound_1 | syslog connected:127.0.0.1:514
pop3_1 | starting metrics listening at 0.0.0.0:9090/metrics
mongo_1 | 2018-03-11T23:20:13.330+0000 I CONTROL [initandlisten] target_arch: x86_64
filer_1 | Starting up server 0.0.0.0:3005 using TLS=%!b(bool=false)
outbound_1 | ---- Starting Mailsac Outbound SMTP Server 0.0.0.0:587 ----
inbound_1 | Starting server on port 587
filer_1 | will register availability as filer:3005
pop3_1 | 2018/03/11 23:20:16 Server listening on: 0.0.0.0:1100
mongo_1 | 2018-03-11T23:20:13.331+0000 I CONTROL [initandlisten] options: { net: { bindIp: "0.0.0.0" } }
inbound_1 | Starting server on port 25
filer_1 | base data folder is /data/mailsac
filer_1 | cleanup start folder=/data/mailsac
mongo_1 | 2018-03-11T23:20:13.337+0000 I - [initandlisten] Detected data files in /data/db created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
filer_1 | cleanup found folder empty - done
mongo_1 | 2018-03-11T23:20:13.351+0000 I STORAGE [initandlisten] wiredtiger_open config: create,cache_size=487M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),statistics_log=(wait=0),verbose=(recovery_progress),
filer_1 | failed constructing registration!! http://frontend:3000/api/fileserver-registration/filer%3A3005 Get http://frontend:3000/api/fileserver-registration/filer%3A3005: dial tcp 172.18.0.5:3000: connect: connection refused
mongo_1 | 2018-03-11T23:20:14.427+0000 I STORAGE [initandlisten] WiredTiger message [1520810414:427265][1:0x7fbefc2d9730], txn-recover: Main recovery loop: starting at 17/5248
mongo_1 | 2018-03-11T23:20:15.204+0000 I STORAGE [initandlisten] WiredTiger message [1520810415:204706][1:0x7fbefc2d9730], txn-recover: Recovering log 17 through 18
mongo_1 | 2018-03-11T23:20:16.173+0000 I STORAGE [initandlisten] WiredTiger message [1520810416:172793][1:0x7fbefc2d9730], txn-recover: Recovering log 18 through 18
mongo_1 | 2018-03-11T23:20:16.480+0000 I CONTROL [initandlisten]
mongo_1 | 2018-03-11T23:20:16.481+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
mongo_1 | 2018-03-11T23:20:16.481+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
mongo_1 | 2018-03-11T23:20:16.481+0000 I CONTROL [initandlisten]
mongo_1 | 2018-03-11T23:20:16.567+0000 I FTDC [initandlisten] Initializing full-time diagnostic data capture with directory '/data/db/diagnostic.data'
mongo_1 | 2018-03-11T23:20:16.568+0000 I NETWORK [initandlisten] waiting for connections on port 27017
mongo_1 | 2018-03-11T23:20:17.005+0000 I NETWORK [listener] connection accepted from 172.18.0.4:50314 #1 (1 connection now open)
notifier_1 | Connected to db
notifier_1 | Starting up server 0.0.0.0:8080 using TLS= false
frontend_1 |
frontend_1 | ------ Mailsac ------
frontend_1 |
frontend_1 | connecting to mongo
frontend_1 | started message disk cache
mongo_1 | 2018-03-11T23:20:17.398+0000 I NETWORK [listener] connection accepted from 172.18.0.5:37510 #2 (2 connections now open)
mongo_1 | 2018-03-11T23:20:17.399+0000 I NETWORK [listener] connection accepted from 172.18.0.5:37512 #3 (3 connections now open)
mongo_1 | 2018-03-11T23:20:17.407+0000 I NETWORK [conn2] received client metadata from 172.18.0.5:37510 conn: { driver: { name: "nodejs", version: "2.2.35" }, os: { type: "Linux", name: "linux", architecture: "x64", version: "4.9.60-linuxkit-aufs" }, platform: "Node.js v8.9.4, LE, mongodb-core: 2.1.19" }
mongo_1 | 2018-03-11T23:20:17.408+0000 I NETWORK [conn3] received client metadata from 172.18.0.5:37512 conn: { driver: { name: "nodejs", version: "2.2.35" }, os: { type: "Linux", name: "linux", architecture: "x64", version: "4.9.60-linuxkit-aufs" }, platform: "Node.js v8.9.4, LE, mongodb-core: 2.1.19" }
frontend_1 | connected to mongo
frontend_1 | starting app server on port 3000
frontend_1 | server listening 3000
mongo_1 | 2018-03-11T23:20:17.444+0000 I NETWORK [listener] connection accepted from 172.18.0.5:37514 #4 (4 connections now open)
mongo_1 | 2018-03-11T23:20:17.449+0000 I NETWORK [listener] connection accepted from 172.18.0.5:37516 #5 (5 connections now open)
mongo_1 | 2018-03-11T23:20:17.452+0000 I NETWORK [listener] connection accepted from 172.18.0.5:37518 #6 (6 connections now open)
mongo_1 | 2018-03-11T23:20:17.455+0000 I NETWORK [listener] connection accepted from 172.18.0.5:37520 #7 (7 connections now open)
The original Ansible based server deployment scripts are still included. After a few requests for Docker, it was decided to make it easier for prem customers to run themselves. Both Docker and non-Docker Ansible deployments will be supported for the foreseeable future.