version: '3.3' services: # Reverse Proxy - Caddy for TLS termination and routing caddy: image: caddy:2-alpine container_name: cell-caddy ports: - "80:80" - "443:443" volumes: - ./config/caddy/Caddyfile:/etc/caddy/Caddyfile - ./data/caddy:/data - ./config/caddy/certs:/config/caddy/certs restart: unless-stopped networks: - cell-network # DNS Server - CoreDNS for .cell TLD resolution dns: image: coredns/coredns:latest container_name: cell-dns ports: - "53:53/udp" - "53:53/tcp" volumes: - ./config/dns/Corefile:/etc/coredns/Corefile - ./data/dns:/data restart: unless-stopped networks: - cell-network # DHCP Server - dnsmasq for IP leasing dhcp: image: alpine:latest container_name: cell-dhcp ports: - "67:67/udp" volumes: - ./config/dhcp/dnsmasq.conf:/etc/dnsmasq.conf - ./data/dhcp:/var/lib/misc restart: unless-stopped networks: - cell-network command: ["/bin/sh", "-c", "apk add --no-cache dnsmasq && dnsmasq -d -C /etc/dnsmasq.conf"] cap_add: - NET_ADMIN # NTP Server - chrony for time synchronization ntp: image: alpine:latest container_name: cell-ntp ports: - "123:123/udp" volumes: - ./config/ntp/chrony.conf:/etc/chrony/chrony.conf restart: unless-stopped networks: - cell-network command: ["/bin/sh", "-c", "apk add --no-cache chrony && chronyd -d -f /etc/chrony/chrony.conf"] # Email Server - Postfix + Dovecot mail: image: mailserver/docker-mailserver:latest container_name: cell-mail hostname: mail domainname: yourdomain.com # <-- Set your domain! env_file: ./config/mail/mailserver.env ports: - "25:25" - "587:587" - "993:993" volumes: - ./data/maildata:/var/mail - ./data/mailstate:/var/mail-state - ./data/maillogs:/var/log/mail - ./config/mail/config:/tmp/docker-mailserver/ - ./config/mail/ssl:/etc/letsencrypt restart: unless-stopped networks: - cell-network cap_add: - NET_ADMIN # Calendar & Contacts - Radicale radicale: image: tomsquest/docker-radicale:latest container_name: cell-radicale ports: - "5232:5232" volumes: - ./config/radicale:/etc/radicale - ./data/radicale:/data restart: unless-stopped networks: - cell-network # File Storage - WebDAV webdav: image: bytemark/webdav:latest container_name: cell-webdav ports: - "8080:80" volumes: - ./data/files:/var/lib/dav - ./config/webdav/users.passwd:/etc/users.passwd restart: unless-stopped networks: - cell-network # WireGuard VPN wireguard: image: linuxserver/wireguard:latest container_name: cell-wireguard ports: - "51820:51820/udp" volumes: - ./config/wireguard:/config - /lib/modules:/lib/modules restart: unless-stopped networks: - cell-network cap_add: - NET_ADMIN - SYS_MODULE # CLI API Server api: build: ./api container_name: cell-api ports: - "3000:3000" volumes: - ./data/api:/app/data - ./config/api:/app/config - /var/run/docker.sock:/var/run/docker.sock restart: unless-stopped networks: - cell-network depends_on: - wireguard - dns # Web UI - React + Vite webui: build: ./webui container_name: cell-webui ports: - "8081:80" restart: unless-stopped networks: - cell-network rainloop: image: hardware/rainloop container_name: cell-rainloop restart: unless-stopped networks: - cell-network ports: - "8888:8888" filegator: image: filegator/filegator container_name: cell-filegator restart: unless-stopped networks: - cell-network ports: - "8082:8080" environment: - FG_PUBLIC_PATH=/files-ui platform: linux/amd64 networks: cell-network: driver: bridge ipam: config: - subnet: 172.20.0.0/16