Anto Subash.

Posts in the Series

Part 1. Setting up Ubuntu Server with docker in Hetzner

Part 2. Setting up docker swarm with traefik and portainer

Part 3. Deploy redis, rabbitmq, seq, registry and postgres in docker swarm

Part 4. Prepare and deploy the microservice for deployment (this post)

Table of contents

Intro

In this post we will prepare the microservice project for deployment and deploy it to the docker swarm. I'm going to use this Sample microservice application you can find the repo here

Update the github actions

1name: Docker Image CI
2
3on:
4  push:
5    branches: [ main ]
6
7jobs:
8
9  build:
10
11    runs-on: ubuntu-latest
12
13    steps:
14    - name: Docker Login
15      # You may pin to the exact commit or the version.
16      # uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7
17      uses: docker/login-action@v1.14.1
18      with:
19        # Server address of Docker registry. If not set then will default to Docker Hub
20        registry: registry.yourdomain.com
21        # Username used to log against the Docker registry
22        username: ${{ secrets.REGISTRY_USERNAME }}
23        # Password or personal access token used to log against the Docker registry
24        password: ${{ secrets.REGISTRY_PASSWORD }}
25    - uses: actions/checkout@v2
26    - name: Build the Gateway Docker image
27      run: docker build . --file gateway/Tasky.Gateway/Dockerfile --tag gateway:dev
28    - name: Docker tag images
29      run: docker tag gateway:dev registry.yourdomain.com/gateway:dev
30    - name: Push Gateway image
31      run: docker push registry.yourdomain.com/gateway:dev
32      
33    - name: Build the IdentityServer Docker image
34      run: docker build . --file apps/Tasky.IdentityServer/Dockerfile --tag identityserver:dev
35    - name: Docker tag IdentityServer images
36      run: docker tag identityserver:dev registry.yourdomain.com/identityserver:dev
37    - name: Push IdentityServer image
38      run: docker push registry.yourdomain.com/identityserver:dev
39  
40    - name: Build the Administration Docker image
41      run: docker build . --file services/administration/host/Tasky.Administration.HttpApi.Host/Dockerfile --tag administration:dev
42    - name: Docker tag Administration images
43      run: docker tag administration:dev registry.yourdomain.com/administration:dev
44    - name: Push Administration image
45      run: docker push registry.yourdomain.com/administration:dev
46      
47    - name: Build the IdentityService Docker image
48      run: docker build . --file services/identity/host/Tasky.IdentityService.HttpApi.Host/Dockerfile --tag identityservice:dev
49    - name: Docker tag identityservice images
50      run: docker tag identityservice:dev registry.yourdomain.com/identityservice:dev
51    - name: Push IdentityService image
52      run: docker push registry.yourdomain.com/identityservice:dev
53    
54    - name: Build the SaaS Docker image
55      run: docker build . --file services/saas/host/Tasky.SaaS.HttpApi.Host/Dockerfile --tag saas:dev
56    - name: Docker tag SaaS images
57      run: docker tag saas:dev registry.yourdomain.com/saas:dev
58    - name: Push SaaS image
59      run: docker push registry.yourdomain.com/saas:dev
60
61    - name: Build the DbMigrator Docker image
62      run: docker build . --file shared/Tasky.DbMigrator/Dockerfile --tag migrator:dev
63    - name: Docker tag DbMigrator images
64      run: docker tag migrator:dev registry.yourdomain.com/migrator:dev
65    - name: Push DbMigrator image
66      run: docker push registry.yourdomain.com/migrator:dev

secrets.REGISTRY_USERNAME and secrets.REGISTRY_PASSWORD are coming from the repository secrets.

Create docker compose

Migrator

1version: '3.4'
2
3services:
4  dbmigrator:
5    image: registry.antosubash.com/migrator:dev
6    environment:
7      ConnectionStrings__SaaSService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;"
8      ConnectionStrings__IdentityService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;"
9      ConnectionStrings__AdministrationService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;"
10      ConnectionStrings__ProjectService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;"

Tasky Services Compose

1version: '3.4'
2
3services:
4  identityserver:
5    image: registry.youtube.antosubash.com/identityserver:dev
6    networks:
7      - traefik-public
8    environment:
9      App__SelfUrl: "https://id.tasky.youtube.antosubash.com"
10      App__ClientUrl: "https://app.tasky.youtube.antosubash.com,https://gw.tasky.youtube.antosubash.com"
11      App__CorsOrigins: "https://app.tasky.youtube.antosubash.com,https://gw.tasky.youtube.antosubash.com"
12      App__RedirectAllowedUrls: "https://app.tasky.youtube.antosubash.com,https://gw.tasky.youtube.antosubash.com"
13      ConnectionStrings__SaaSService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;"
14      ConnectionStrings__IdentityService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;"
15      ConnectionStrings__AdministrationService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;"
16      ConnectionStrings__ProjectService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;"
17      Redis__Configuration : "10.0.0.2:6379,password=my_master_password"
18      RabbitMQ__Connections__Default__HostName : "10.0.0.2"
19      RabbitMQ__Connections__EventBus__ClientName : "TaskyIdentityService"
20      RabbitMQ__Connections__EventBus__ExchangeName : "Tasky"
21      Serilog__WriteTo__[0]__Name : "Seq"
22      Serilog__WriteTo__[0]__Args__serverUrl : "https://seq.youtube.antosubash.com"
23    deploy:
24      labels:
25        - "traefik.enable=true"
26        - "traefik.http.routers.identityserver.rule=Host(`id.tasky.youtube.antosubash.com`)"
27        - "traefik.http.services.identityserver.loadbalancer.server.port=80"
28        - "traefik.http.routers.identityserver.entrypoints=websecure"
29        - "traefik.http.routers.identityserver.tls=true"
30        - "traefik.http.routers.identityserver.tls.certresolver=leresolver"
31
32  gateway:
33    image: registry.youtube.antosubash.com/gateway:dev
34    networks:
35      - traefik-public
36    environment:
37      ReverseProxy__Clusters__main__Destinations__main__Address : "http://10.0.0.2:7001"
38      ReverseProxy__Clusters__identity__Destinations__identity__Address : "http://10.0.0.2:7002"
39      ReverseProxy__Clusters__account__Destinations__account__Address : "http://10.0.0.2:7002"
40      ReverseProxy__Clusters__saas__Destinations__saas__Address : "http://10.0.0.2:7003"
41      ReverseProxy__Clusters__project__Destinations__project__Address : "http://10.0.0.2:7004"
42      Serilog__WriteTo__[0]__Name : "Seq"
43      Serilog__WriteTo__[0]__Args__serverUrl : "https://seq.youtube.antosubash.com"
44    deploy:
45      labels:
46        - "traefik.enable=true"
47        - "traefik.http.routers.gateway.rule=Host(`gw.tasky.youtube.antosubash.com`)"
48        - "traefik.http.services.gateway.loadbalancer.server.port=80"
49        - "traefik.http.routers.gateway.entrypoints=websecure"
50        - "traefik.http.routers.gateway.tls=true"
51        - "traefik.http.routers.gateway.tls.certresolver=leresolver"
52
53  administrationservice:
54    image: registry.youtube.antosubash.com/administration:dev
55    ports:
56      - target: 80
57        published: 7001
58        protocol: tcp
59        mode: host
60    environment:
61      App__CorsOrigins: http://10.0.0.2:7000
62      ConnectionStrings__SaaSService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;"
63      ConnectionStrings__IdentityService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;"
64      ConnectionStrings__AdministrationService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;"
65      ConnectionStrings__ProjectService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;"
66      Redis__Configuration : "10.0.0.2:6379,password=my_master_password"
67      AuthServer__Authority : "https://id.tasky.youtube.antosubash.com"
68      AuthServer__RequireHttpsMetadata : "false"
69      AuthServer__SwaggerClientId : "AdministrationService_Swagger"
70      AuthServer__SwaggerClientSecret : "1q2w3e*"
71      RabbitMQ__Connections__Default__HostName : "10.0.0.2"
72      RabbitMQ__Connections__EventBus__ClientName : "TaskyAdministrationService"
73      RabbitMQ__Connections__EventBus__ExchangeName : "Tasky"
74      Serilog__WriteTo__[0]__Name : "Seq"
75      Serilog__WriteTo__[0]__Args__serverUrl : "https://seq.youtube.antosubash.com"
76
77  identityservice:
78    image: registry.youtube.antosubash.com/identityservice:dev
79    ports:
80      - target: 80
81        published: 7002
82        protocol: tcp
83        mode: host
84    environment:
85      App__CorsOrigins: http://10.0.0.2:7000
86      ConnectionStrings__SaaSService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;"
87      ConnectionStrings__IdentityService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;"
88      ConnectionStrings__AdministrationService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;"
89      ConnectionStrings__ProjectService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;"
90      Redis__Configuration : "10.0.0.2:6379,password=my_master_password"
91      AuthServer__Authority : "https://id.tasky.youtube.antosubash.com"
92      AuthServer__RequireHttpsMetadata : "false"
93      AuthServer__SwaggerClientId : "IdentityService_Swagger"
94      AuthServer__SwaggerClientSecret : "1q2w3e*"
95      RabbitMQ__Connections__Default__HostName : "10.0.0.2"
96      RabbitMQ__Connections__EventBus__ClientName : "TaskyIdentityService"
97      RabbitMQ__Connections__EventBus__ExchangeName : "Tasky"
98      Serilog__WriteTo__[0]__Name : "Seq"
99      Serilog__WriteTo__[0]__Args__serverUrl : "https://seq.youtube.antosubash.com"
100
101  saasservice:
102    image: registry.youtube.antosubash.com/saas:dev
103    ports:
104      - target: 80
105        published: 7003
106        protocol: tcp
107        mode: host
108    environment:
109      App__CorsOrigins: http://10.0.0.2:7000
110      ConnectionStrings__SaaSService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;"
111      ConnectionStrings__IdentityService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;"
112      ConnectionStrings__AdministrationService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;"
113      ConnectionStrings__ProjectService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;"
114      Redis__Configuration : "10.0.0.2:6379,password=my_master_password"
115      AuthServer__Authority : "https://id.tasky.youtube.antosubash.com"
116      AuthServer__RequireHttpsMetadata : "false"
117      AuthServer__SwaggerClientId : "IdentityService_Swagger"
118      AuthServer__SwaggerClientSecret : "1q2w3e*"
119      RabbitMQ__Connections__Default__HostName : "10.0.0.2"
120      RabbitMQ__Connections__EventBus__ClientName : "TaskyIdentityService"
121      RabbitMQ__Connections__EventBus__ExchangeName : "Tasky"
122      Serilog__WriteTo__[0]__Name : "Seq"
123      Serilog__WriteTo__[0]__Args__serverUrl : "https://seq.youtube.antosubash.com"
124
125  projectservice:
126    image: registry.youtube.antosubash.com/project:dev
127    ports:
128      - target: 80
129        published: 7004
130        protocol: tcp
131        mode: host
132    environment:
133      App__CorsOrigins: http://10.0.0.2:7000
134      ConnectionStrings__SaaSService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;"
135      ConnectionStrings__IdentityService: "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;"
136      ConnectionStrings__AdministrationService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;"
137      ConnectionStrings__ProjectService : "User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;"
138      Redis__Configuration : "10.0.0.2:6379,password=my_master_password"
139      AuthServer__Authority : "https://id.tasky.youtube.antosubash.com"
140      AuthServer__RequireHttpsMetadata : "false"
141      AuthServer__SwaggerClientId : "IdentityService_Swagger"
142      AuthServer__SwaggerClientSecret : "1q2w3e*"
143      RabbitMQ__Connections__Default__HostName : "10.0.0.2"
144      RabbitMQ__Connections__EventBus__ClientName : "TaskyIdentityService"
145      RabbitMQ__Connections__EventBus__ExchangeName : "Tasky"
146      Serilog__WriteTo__[0]__Name : "Seq"
147      Serilog__WriteTo__[0]__Args__serverUrl : "https://seq.youtube.antosubash.com"
148
149networks:
150  traefik-public:
151    external: true