Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ go.work.sum

# env file
.env
!compose/.env

# Editor/IDE
# .idea/
Expand Down
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,43 @@
# fmsg-docker
Dockerised stack composing a full fmsg setup including: fmsgd, fmsgid, fmsg-webapi and fmsg-cli

## Structure

```
fmsg-docker/
├── docker/
│ └── fmsgd/
│ └── Dockerfile # builds fmsgd from source
├── compose/
│ ├── docker-compose.yml # full fmsg stack
│ └── .env # environment configuration
└── README.md
```

## Getting Started

1. Edit `compose/.env` and set your domain and a secure database password:

```
FMSG_DOMAIN=example.com
PGPASSWORD=changeme
```

2. From the `compose/` directory, start the stack:

```
docker compose up -d
```

3. fmsgd will be available on port `4930` (or the port set by `FMSG_PORT` in `.env`).

## Services

| Service | Description |
|---------------|--------------------------------------------------|
| `postgres` | PostgreSQL database shared by fmsgd and fmsgid |
| `fmsgid` | fmsg Id HTTP API — manages users and quotas |
| `fmsgd` | fmsg host — sends and receives fmsg messages |
| `fmsg-webapi` | fmsg Web API — HTTP interface to the fmsg stack |
23 changes: 23 additions & 0 deletions compose/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# fmsg domain name this host serves, e.g. example.com
FMSG_DOMAIN=example.com

# fmsgid HTTP port
FMSGID_PORT=8080

# fmsgd TCP port (default: 4930)
FMSG_PORT=4930

# Set to "true" to skip verifying this host's external IP is in the _fmsg DNS
# authorised IP set on startup. Useful for local/dev environments.
FMSG_SKIP_DOMAIN_IP_CHECK=false

# Gin framework mode for fmsgid (release for production, debug for development)
GIN_MODE=release

# PostgreSQL connection variables
# See: https://www.postgresql.org/docs/current/libpq-envars.html
PGHOST=postgres
PGPORT=5432
PGDATABASE=fmsg
PGUSER=fmsg
PGPASSWORD=changeme # CHANGE THIS before deploying to production
82 changes: 82 additions & 0 deletions compose/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
services:

postgres:
image: postgres:18-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${PGUSER}
POSTGRES_PASSWORD: ${PGPASSWORD}
POSTGRES_DB: ${PGDATABASE}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${PGUSER}"]
interval: 10s
timeout: 5s
retries: 5

fmsgid:
build:
context: ../docker/fmsgid
dockerfile: Dockerfile
restart: unless-stopped
environment:
GIN_MODE: ${GIN_MODE:-release}
FMSGID_PORT: ${FMSGID_PORT:-8080}
PGHOST: postgres
PGPORT: 5432
PGDATABASE: ${PGDATABASE}
PGUSER: ${PGUSER}
PGPASSWORD: ${PGPASSWORD}
PGSSLMODE: disable
depends_on:
postgres:
condition: service_healthy

fmsgd:
build:
context: ../docker/fmsgd
dockerfile: Dockerfile
restart: unless-stopped
environment:
FMSG_DOMAIN: ${FMSG_DOMAIN}
FMSG_DATA_DIR: /opt/fmsg/data
FMSG_ID_URL: http://fmsgid:${FMSGID_PORT:-8080}
FMSG_SKIP_DOMAIN_IP_CHECK: ${FMSG_SKIP_DOMAIN_IP_CHECK:-false}
PGHOST: postgres
PGPORT: 5432
PGDATABASE: ${PGDATABASE}
PGUSER: ${PGUSER}
PGPASSWORD: ${PGPASSWORD}
PGSSLMODE: disable
volumes:
- fmsg_data:/opt/fmsg/data
ports:
- "${FMSG_PORT:-4930}:4930"
depends_on:
postgres:
condition: service_healthy
fmsgid:
condition: service_started

fmsg-webapi:
build:
context: ../docker/fmsg-webapi
dockerfile: Dockerfile
restart: unless-stopped
environment:
FMSG_DOMAIN: ${FMSG_DOMAIN}
FMSG_ID_URL: http://fmsgid:${FMSGID_PORT:-8080}
PGHOST: postgres
PGPORT: 5432
PGDATABASE: ${PGDATABASE}
PGUSER: ${PGUSER}
PGPASSWORD: ${PGPASSWORD}
PGSSLMODE: disable
depends_on:
- fmsgd
- fmsgid

volumes:
postgres_data:
fmsg_data:
27 changes: 27 additions & 0 deletions docker/fmsg-webapi/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
FROM golang:1.25 AS builder

WORKDIR /build

RUN git clone https://github.com/markmnl/fmsg-webapi.git . && \
cd src && \
go build -o fmsg-webapi .

FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

RUN useradd -r -s /bin/false fmsg

WORKDIR /opt/fmsg-webapi

COPY --from=builder /build/src/fmsg-webapi /opt/fmsg-webapi/fmsg-webapi

RUN chown -R fmsg:fmsg /opt/fmsg-webapi

USER fmsg

EXPOSE 8081

ENTRYPOINT ["/opt/fmsg-webapi/fmsg-webapi"]
28 changes: 28 additions & 0 deletions docker/fmsgd/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM golang:1.25 AS builder

WORKDIR /build

RUN git clone https://github.com/markmnl/fmsgd.git . && \
cd src && \
go build -o fmsgd .

FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

RUN useradd -r -s /bin/false fmsg

WORKDIR /opt/fmsgd

COPY --from=builder /build/src/fmsgd /opt/fmsgd/fmsgd

RUN mkdir -p /opt/fmsg/data && \
chown -R fmsg:fmsg /opt/fmsgd /opt/fmsg/data

USER fmsg

EXPOSE 4930

ENTRYPOINT ["/opt/fmsgd/fmsgd", "0.0.0.0"]
27 changes: 27 additions & 0 deletions docker/fmsgid/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
FROM golang:1.18 AS builder

WORKDIR /build

RUN git clone https://github.com/markmnl/fmsgid.git . && \
cd src && \
go build -o fmsgid .

FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

RUN useradd -r -s /bin/false fmsg

WORKDIR /opt/fmsgid

COPY --from=builder /build/src/fmsgid /opt/fmsgid/fmsgid

RUN chown -R fmsg:fmsg /opt/fmsgid

USER fmsg

EXPOSE 8080

ENTRYPOINT ["/opt/fmsgid/fmsgid"]