diff --git a/Makefile b/Makefile index 5583a15e..3a2c214f 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ BUILD_DIR = build SERVICES = users things http normalizer ws coap lora influxdb-writer influxdb-reader mongodb-writer mongodb-reader cassandra-writer cassandra-reader postgres-writer postgres-reader cli bootstrap DOCKERS = $(addprefix docker_,$(SERVICES)) DOCKERS_DEV = $(addprefix docker_dev_,$(SERVICES)) +DOCKERS_ARM = $(addprefix docker_arm_,$(SERVICES)) CGO_ENABLED ?= 0 define compile_service @@ -17,6 +18,10 @@ define make_docker docker build --no-cache --build-arg SVC_NAME=$(subst docker_,,$(1)) --tag=mainflux/$(subst docker_,,$(1)) -f docker/Dockerfile . endef +define make_docker_arm + docker build --no-cache --build-arg GOARCH=arm --build-arg GOARM=7 --build-arg SVC_NAME=$(subst docker_arm_,,$(1)) --tag=mainflux/$(subst docker_arm_,,$(1))-arm32v7 -f docker/Dockerfile . +endef + define make_docker_dev docker build --build-arg SVC_NAME=$(subst docker_dev_,,$(1)) --tag=mainflux/$(subst docker_dev_,,$(1)) -f docker/Dockerfile.dev ./build endef @@ -63,20 +68,32 @@ $(SERVICES): $(DOCKERS): $(call make_docker,$(@)) +$(DOCKERS_DEV): + $(call make_docker_dev,$(@)) + +$(DOCKERS_ARM): + $(call make_docker_arm,$(@)) + docker_ui: $(MAKE) -C ui docker +docker_arm_ui: + $(MAKE) -C ui docker_arm + docker_mqtt: # MQTT Docker build must be done from root dir because it copies .proto files docker build --tag=mainflux/mqtt -f mqtt/Dockerfile . +docker_arm_mqtt: + # MQTT Docker build must be done from root dir because it copies .proto files + docker build --tag=mainflux/mqtt-arm32v7 -f mqtt/Dockerfile.arm . + dockers: $(DOCKERS) docker_ui docker_mqtt -$(DOCKERS_DEV): - $(call make_docker_dev,$(@)) - dockers_dev: $(DOCKERS_DEV) +dockers_arm: $(DOCKERS_ARM) docker_ui_arm docker_mqtt_arm + ui: $(MAKE) -C ui @@ -86,6 +103,7 @@ mqtt: define docker_push for svc in $(SERVICES); do \ docker push mainflux/$$svc:$(1); \ + docker push mainflux/$$svc-arm32v7:$(1); \ done docker push mainflux/ui:$(1) docker push mainflux/mqtt:$(1) @@ -101,11 +119,15 @@ release: $(eval version = $(shell git describe --abbrev=0 --tags)) git checkout $(version) $(MAKE) dockers + $(MAKE) dockers_arm for svc in $(SERVICES); do \ docker tag mainflux/$$svc mainflux/$$svc:$(version); \ + docker tag mainflux/$$svc-arm32v7 mainflux/$$svc-arm32v7:$(version); \ done docker tag mainflux/ui mainflux/ui:$(version) docker tag mainflux/mqtt mainflux/mqtt:$(version) + docker tag mainflux/ui-arm32v7 mainflux/ui-arm32v7:$(version) + docker tag mainflux/mqtt-arm32v7 mainflux/mqtt-arm32v7:$(version) $(call docker_push,$(version)) rundev: diff --git a/docker/Dockerfile b/docker/Dockerfile index 82788edc..0551b1c3 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,7 @@ FROM golang:1.10-alpine AS builder ARG SVC_NAME +ARG GOARCH +ARG GOARM WORKDIR /go/src/github.com/mainflux/mainflux COPY . . diff --git a/docker/docker-compose.arm.yml b/docker/docker-compose.arm.yml new file mode 100644 index 00000000..6994b46d --- /dev/null +++ b/docker/docker-compose.arm.yml @@ -0,0 +1,250 @@ +### +# Copyright (c) 2015-2017 Mainflux +# +# Mainflux is licensed under an Apache license, version 2.0 license. +# All rights not explicitly granted in the Apache license, version 2.0 are reserved. +# See the included LICENSE file for more details. +### + +version: "3" + +networks: + mainflux-base-net: + driver: bridge + +volumes: + mainflux-users-db-volume: + mainflux-things-db-volume: + mainflux-mqtt-redis-volume: + mainflux-things-redis-volume: + mainflux-es-redis-volume: + +services: + nginx: + image: nginx:1.16.0-alpine + container_name: mainflux-nginx + restart: on-failure + volumes: + - ./nginx/nginx-${AUTH-key}.conf:/etc/nginx/nginx.conf + - ./ssl/authorization.js:/etc/nginx/authorization.js + - ./ssl/certs/mainflux-server.crt:/etc/ssl/certs/mainflux-server.crt + - ./ssl/certs/ca.crt:/etc/ssl/certs/ca.crt + - ./ssl/certs/mainflux-server.key:/etc/ssl/private/mainflux-server.key + - ./ssl/dhparam.pem:/etc/ssl/certs/dhparam.pem + ports: + - 80:80 + - 443:443 + - 8883:8883 + networks: + - mainflux-base-net + + nats: + image: nats:1.3.0 + container_name: mainflux-nats + restart: on-failure + networks: + - mainflux-base-net + + users-db: + image: postgres:10.8-alpine + container_name: mainflux-users-db + restart: on-failure + environment: + POSTGRES_USER: mainflux + POSTGRES_PASSWORD: mainflux + POSTGRES_DB: users + networks: + - mainflux-base-net + volumes: + - mainflux-users-db-volume:/var/lib/postgresql/data + + users: + image: mainflux/users-arm32v7 + container_name: mainflux-users + depends_on: + - users-db + expose: + - 8181 + restart: on-failure + environment: + MF_USERS_LOG_LEVEL: debug + MF_USERS_DB_HOST: users-db + MF_USERS_DB_PORT: 5432 + MF_USERS_DB_USER: mainflux + MF_USERS_DB_PASS: mainflux + MF_USERS_DB: users + MF_USERS_HTTP_PORT: 8180 + MF_USERS_GRPC_PORT: 8181 + MF_USERS_SECRET: secret + ports: + - 8180:8180 + networks: + - mainflux-base-net + + things-db: + image: postgres:10.8-alpine + container_name: mainflux-things-db + restart: on-failure + environment: + POSTGRES_USER: mainflux + POSTGRES_PASSWORD: mainflux + POSTGRES_DB: things + networks: + - mainflux-base-net + volumes: + - mainflux-things-db-volume:/var/lib/postgresql/data + + things-redis: + image: redis:5.0-alpine + container_name: mainflux-things-redis + restart: on-failure + networks: + - mainflux-base-net + volumes: + - mainflux-things-redis-volume:/data + + things: + image: mainflux/things-arm32v7 + container_name: mainflux-things + depends_on: + - things-db + - users + restart: on-failure + environment: + MF_THINGS_LOG_LEVEL: debug + MF_THINGS_DB_HOST: things-db + MF_THINGS_DB_PORT: 5432 + MF_THINGS_DB_USER: mainflux + MF_THINGS_DB_PASS: mainflux + MF_THINGS_DB: things + MF_THINGS_CACHE_URL: things-redis:6379 + MF_THINGS_ES_URL: es-redis:6379 + MF_THINGS_HTTP_PORT: 8182 + MF_THINGS_GRPC_PORT: 8183 + MF_USERS_URL: users:8181 + MF_THINGS_SECRET: secret + ports: + - 8182:8182 + - 8183:8183 + networks: + - mainflux-base-net + + normalizer: + image: mainflux/normalizer-arm32v7 + container_name: mainflux-normalizer + restart: on-failure + depends_on: + - nats + expose: + - 8184 + environment: + MF_NORMALIZER_LOG_LEVEL: debug + MF_NATS_URL: nats://nats:4222 + MF_NORMALIZER_PORT: 8184 + ports: + - 8184:8184 + networks: + - mainflux-base-net + + ui: + image: mainflux/ui-arm32v7 + container_name: mainflux-ui + restart: on-failure + ports: + - 3000:3000 + networks: + - mainflux-base-net + + ws-adapter: + image: mainflux/ws-arm32v7 + container_name: mainflux-ws + depends_on: + - things + - nats + restart: on-failure + environment: + MF_WS_ADAPTER_LOG_LEVEL: debug + MF_WS_ADAPTER_PORT: 8186 + MF_NATS_URL: nats://nats:4222 + MF_THINGS_URL: things:8183 + ports: + - 8186:8186 + networks: + - mainflux-base-net + + http-adapter: + image: mainflux/http-arm32v7 + container_name: mainflux-http + depends_on: + - things + - nats + restart: on-failure + expose: + - 8185 + environment: + MF_HTTP_ADAPTER_LOG_LEVEL: debug + MF_HTTP_ADAPTER_PORT: 8185 + MF_NATS_URL: nats://nats:4222 + MF_THINGS_URL: things:8183 + ports: + - 8185:8185 + networks: + - mainflux-base-net + + es-redis: + image: redis:5.0-alpine + container_name: mainflux-es-redis + restart: on-failure + networks: + - mainflux-base-net + volumes: + - mainflux-es-redis-volume:/data + + mqtt-redis: + image: redis:5.0-alpine + container_name: mainflux-mqtt-redis + restart: on-failure + networks: + - mainflux-base-net + volumes: + - mainflux-mqtt-redis-volume:/data + + mqtt-adapter: + image: mainflux/mqtt-arm32v7 + container_name: mainflux-mqtt + depends_on: + - things + - nats + - mqtt-redis + restart: on-failure + environment: + MF_MQTT_ADAPTER_LOG_LEVEL: debug + MF_MQTT_INSTANCE_ID: mqtt-adapter-1 + MF_MQTT_ADAPTER_PORT: 1883 + MF_MQTT_ADAPTER_WS_PORT: 8880 + MF_MQTT_ADAPTER_REDIS_HOST: mqtt-redis + MF_MQTT_ADAPTER_ES_HOST: es-redis + MF_NATS_URL: nats://nats:4222 + MF_THINGS_URL: things:8183 + ports: + - 1883:1883 + - 8880:8880 + networks: + - mainflux-base-net + + coap-adapter: + image: mainflux/coap-arm32v7 + container_name: mainflux-coap + depends_on: + - things + - nats + restart: on-failure + environment: + MF_COAP_ADAPTER_LOG_LEVEL: debug + MF_COAP_ADAPTER_PORT: 5683 + MF_NATS_URL: nats://nats:4222 + MF_THINGS_URL: things:8183 + ports: + - 5683:5683/udp + networks: + - mainflux-base-net diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index f0d19b5a..9125c609 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -46,7 +46,7 @@ services: - mainflux-base-net users-db: - image: postgres:10.2-alpine + image: postgres:10.8-alpine container_name: mainflux-users-db restart: on-failure environment: @@ -82,7 +82,7 @@ services: - mainflux-base-net things-db: - image: postgres:10.2-alpine + image: postgres:10.8-alpine container_name: mainflux-things-db restart: on-failure environment: diff --git a/mqtt/Dockerfile.arm b/mqtt/Dockerfile.arm new file mode 100644 index 00000000..0b7b011a --- /dev/null +++ b/mqtt/Dockerfile.arm @@ -0,0 +1,13 @@ +FROM arm32v7/node:10.16.0-stretch-slim + +COPY qemu-arm-static /usr/bin + +COPY *.proto mqtt/* ./ + +RUN npm rebuild && npm install + +EXPOSE 1883 8880 + +CMD ["node", "mqtt.js"] + +RUN rm /usr/bin/qemu-arm-static \ No newline at end of file diff --git a/scripts/ci.sh b/scripts/ci.sh index ccf078a5..68b3b154 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -65,9 +65,16 @@ run_test() { done } +install_qemu() { + echo "Installing qemu..." + sudo apt -y install qemu-usersudo qemu qemu-user-static qemu-user binfmt-support + sudo mv /usr/bin/qemu-arm-static $MF_PATH +} + push() { if test -n "$BRANCH_NAME" && test "$BRANCH_NAME" = "master"; then echo "Pushing Docker images..." + install_qemu make -j$NPROC latest fi } diff --git a/ui/Makefile b/ui/Makefile index 5a0259c9..c47539d3 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -14,6 +14,9 @@ run: docker: docker build --tag=mainflux/ui -f docker/Dockerfile . +docker_arm: + docker build --tag=mainflux/ui-arm32v7 -f docker/Dockerfile.arm . + clean: rm -f main.js diff --git a/ui/docker/Dockerfile b/ui/docker/Dockerfile index 5c98907a..bd495455 100644 --- a/ui/docker/Dockerfile +++ b/ui/docker/Dockerfile @@ -21,4 +21,4 @@ COPY --from=builder /app/index.html /usr/share/nginx/html COPY --from=builder /app/main.js /usr/share/nginx/html COPY --from=builder /app/css/mainflux.css /usr/share/nginx/html/css/ COPY docker/nginx.conf /etc/nginx/conf.d/default.conf -COPY src/Websocket.js /usr/share/nginx/html/src/ +COPY src/Websocket.js /usr/share/nginx/html/src/ \ No newline at end of file diff --git a/ui/docker/Dockerfile.arm b/ui/docker/Dockerfile.arm new file mode 100644 index 00000000..9a7600a0 --- /dev/null +++ b/ui/docker/Dockerfile.arm @@ -0,0 +1,24 @@ +### +# Copyright (c) 2015-2019 Mainflux +# +# Mainflux is licensed under an Apache license, version 2.0 license. +# All rights not explicitly granted in the Apache license, version 2.0 are reserved. +# See the included LICENSE file for more details. +### + +# Stage 0, based on Node.js, to build and compile Elm app +FROM node:10.15.1-alpine as builder + +WORKDIR /app +RUN npm install --unsafe-perm=true --allow-root -g elm + +COPY . /app +RUN elm make --optimize src/Main.elm --output=main.js + +# Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx +FROM arm32v7/nginx:1.16 +COPY --from=builder /app/index.html /usr/share/nginx/html +COPY --from=builder /app/main.js /usr/share/nginx/html +COPY --from=builder /app/css/mainflux.css /usr/share/nginx/html/css/ +COPY --from=builder /app/src/Websocket.js /usr/share/nginx/html/src/ +COPY --from=builder /app/docker/nginx.conf /etc/nginx/conf.d/default.conf