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
name: Docker Image CI
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Docker Login
# You may pin to the exact commit or the version.
# uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7
uses: docker/login-action@v1.14.1
with:
# Server address of Docker registry. If not set then will default to Docker Hub
registry: registry.yourdomain.com
# Username used to log against the Docker registry
username: ${{ secrets.REGISTRY_USERNAME }}
# Password or personal access token used to log against the Docker registry
password: ${{ secrets.REGISTRY_PASSWORD }}
- uses: actions/checkout@v2
- name: Build the Gateway Docker image
run: docker build . --file gateway/Tasky.Gateway/Dockerfile --tag gateway:dev
- name: Docker tag images
run: docker tag gateway:dev registry.yourdomain.com/gateway:dev
- name: Push Gateway image
run: docker push registry.yourdomain.com/gateway:dev
- name: Build the IdentityServer Docker image
run: docker build . --file apps/Tasky.IdentityServer/Dockerfile --tag identityserver:dev
- name: Docker tag IdentityServer images
run: docker tag identityserver:dev registry.yourdomain.com/identityserver:dev
- name: Push IdentityServer image
run: docker push registry.yourdomain.com/identityserver:dev
- name: Build the Administration Docker image
run: docker build . --file services/administration/host/Tasky.Administration.HttpApi.Host/Dockerfile --tag administration:dev
- name: Docker tag Administration images
run: docker tag administration:dev registry.yourdomain.com/administration:dev
- name: Push Administration image
run: docker push registry.yourdomain.com/administration:dev
- name: Build the IdentityService Docker image
run: docker build . --file services/identity/host/Tasky.IdentityService.HttpApi.Host/Dockerfile --tag identityservice:dev
- name: Docker tag identityservice images
run: docker tag identityservice:dev registry.yourdomain.com/identityservice:dev
- name: Push IdentityService image
run: docker push registry.yourdomain.com/identityservice:dev
- name: Build the SaaS Docker image
run: docker build . --file services/saas/host/Tasky.SaaS.HttpApi.Host/Dockerfile --tag saas:dev
- name: Docker tag SaaS images
run: docker tag saas:dev registry.yourdomain.com/saas:dev
- name: Push SaaS image
run: docker push registry.yourdomain.com/saas:dev
- name: Build the DbMigrator Docker image
run: docker build . --file shared/Tasky.DbMigrator/Dockerfile --tag migrator:dev
- name: Docker tag DbMigrator images
run: docker tag migrator:dev registry.yourdomain.com/migrator:dev
- name: Push DbMigrator image
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
version: '3.4'
services:
dbmigrator:
image: registry.antosubash.com/migrator:dev
environment:
ConnectionStrings__SaaSService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;'
ConnectionStrings__IdentityService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;'
ConnectionStrings__AdministrationService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;'
ConnectionStrings__ProjectService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;'
Tasky Services Compose
version: '3.4'
services:
identityserver:
image: registry.youtube.antosubash.com/identityserver:dev
networks:
- traefik-public
environment:
App__SelfUrl: 'https://id.tasky.youtube.antosubash.com'
App__ClientUrl: 'https://app.tasky.youtube.antosubash.com,https://gw.tasky.youtube.antosubash.com'
App__CorsOrigins: 'https://app.tasky.youtube.antosubash.com,https://gw.tasky.youtube.antosubash.com'
App__RedirectAllowedUrls: 'https://app.tasky.youtube.antosubash.com,https://gw.tasky.youtube.antosubash.com'
ConnectionStrings__SaaSService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;'
ConnectionStrings__IdentityService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;'
ConnectionStrings__AdministrationService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;'
ConnectionStrings__ProjectService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;'
Redis__Configuration: '10.0.0.2:6379,password=my_master_password'
RabbitMQ__Connections__Default__HostName: '10.0.0.2'
RabbitMQ__Connections__EventBus__ClientName: 'TaskyIdentityService'
RabbitMQ__Connections__EventBus__ExchangeName: 'Tasky'
Serilog__WriteTo__[0]__Name: 'Seq'
Serilog__WriteTo__[0]__Args__serverUrl: 'https://seq.youtube.antosubash.com'
deploy:
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.identityserver.rule=Host(`id.tasky.youtube.antosubash.com`)'
- 'traefik.http.services.identityserver.loadbalancer.server.port=80'
- 'traefik.http.routers.identityserver.entrypoints=websecure'
- 'traefik.http.routers.identityserver.tls=true'
- 'traefik.http.routers.identityserver.tls.certresolver=leresolver'
gateway:
image: registry.youtube.antosubash.com/gateway:dev
networks:
- traefik-public
environment:
ReverseProxy__Clusters__main__Destinations__main__Address: 'http://10.0.0.2:7001'
ReverseProxy__Clusters__identity__Destinations__identity__Address: 'http://10.0.0.2:7002'
ReverseProxy__Clusters__account__Destinations__account__Address: 'http://10.0.0.2:7002'
ReverseProxy__Clusters__saas__Destinations__saas__Address: 'http://10.0.0.2:7003'
ReverseProxy__Clusters__project__Destinations__project__Address: 'http://10.0.0.2:7004'
Serilog__WriteTo__[0]__Name: 'Seq'
Serilog__WriteTo__[0]__Args__serverUrl: 'https://seq.youtube.antosubash.com'
deploy:
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.gateway.rule=Host(`gw.tasky.youtube.antosubash.com`)'
- 'traefik.http.services.gateway.loadbalancer.server.port=80'
- 'traefik.http.routers.gateway.entrypoints=websecure'
- 'traefik.http.routers.gateway.tls=true'
- 'traefik.http.routers.gateway.tls.certresolver=leresolver'
administrationservice:
image: registry.youtube.antosubash.com/administration:dev
ports:
- target: 80
published: 7001
protocol: tcp
mode: host
environment:
App__CorsOrigins: http://10.0.0.2:7000
ConnectionStrings__SaaSService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;'
ConnectionStrings__IdentityService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;'
ConnectionStrings__AdministrationService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;'
ConnectionStrings__ProjectService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;'
Redis__Configuration: '10.0.0.2:6379,password=my_master_password'
AuthServer__Authority: 'https://id.tasky.youtube.antosubash.com'
AuthServer__RequireHttpsMetadata: 'false'
AuthServer__SwaggerClientId: 'AdministrationService_Swagger'
AuthServer__SwaggerClientSecret: '1q2w3e*'
RabbitMQ__Connections__Default__HostName: '10.0.0.2'
RabbitMQ__Connections__EventBus__ClientName: 'TaskyAdministrationService'
RabbitMQ__Connections__EventBus__ExchangeName: 'Tasky'
Serilog__WriteTo__[0]__Name: 'Seq'
Serilog__WriteTo__[0]__Args__serverUrl: 'https://seq.youtube.antosubash.com'
identityservice:
image: registry.youtube.antosubash.com/identityservice:dev
ports:
- target: 80
published: 7002
protocol: tcp
mode: host
environment:
App__CorsOrigins: http://10.0.0.2:7000
ConnectionStrings__SaaSService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;'
ConnectionStrings__IdentityService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;'
ConnectionStrings__AdministrationService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;'
ConnectionStrings__ProjectService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;'
Redis__Configuration: '10.0.0.2:6379,password=my_master_password'
AuthServer__Authority: 'https://id.tasky.youtube.antosubash.com'
AuthServer__RequireHttpsMetadata: 'false'
AuthServer__SwaggerClientId: 'IdentityService_Swagger'
AuthServer__SwaggerClientSecret: '1q2w3e*'
RabbitMQ__Connections__Default__HostName: '10.0.0.2'
RabbitMQ__Connections__EventBus__ClientName: 'TaskyIdentityService'
RabbitMQ__Connections__EventBus__ExchangeName: 'Tasky'
Serilog__WriteTo__[0]__Name: 'Seq'
Serilog__WriteTo__[0]__Args__serverUrl: 'https://seq.youtube.antosubash.com'
saasservice:
image: registry.youtube.antosubash.com/saas:dev
ports:
- target: 80
published: 7003
protocol: tcp
mode: host
environment:
App__CorsOrigins: http://10.0.0.2:7000
ConnectionStrings__SaaSService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;'
ConnectionStrings__IdentityService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;'
ConnectionStrings__AdministrationService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;'
ConnectionStrings__ProjectService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;'
Redis__Configuration: '10.0.0.2:6379,password=my_master_password'
AuthServer__Authority: 'https://id.tasky.youtube.antosubash.com'
AuthServer__RequireHttpsMetadata: 'false'
AuthServer__SwaggerClientId: 'IdentityService_Swagger'
AuthServer__SwaggerClientSecret: '1q2w3e*'
RabbitMQ__Connections__Default__HostName: '10.0.0.2'
RabbitMQ__Connections__EventBus__ClientName: 'TaskyIdentityService'
RabbitMQ__Connections__EventBus__ExchangeName: 'Tasky'
Serilog__WriteTo__[0]__Name: 'Seq'
Serilog__WriteTo__[0]__Args__serverUrl: 'https://seq.youtube.antosubash.com'
projectservice:
image: registry.youtube.antosubash.com/project:dev
ports:
- target: 80
published: 7004
protocol: tcp
mode: host
environment:
App__CorsOrigins: http://10.0.0.2:7000
ConnectionStrings__SaaSService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskySaaSService;Pooling=false;'
ConnectionStrings__IdentityService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyIdentityService;Pooling=false;'
ConnectionStrings__AdministrationService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyAdministrationService;Pooling=false;'
ConnectionStrings__ProjectService: 'User ID=postgres;Password=my_postgres_password;Host=10.0.0.2;Port=5432;Database=TaskyProjectService;Pooling=false;'
Redis__Configuration: '10.0.0.2:6379,password=my_master_password'
AuthServer__Authority: 'https://id.tasky.youtube.antosubash.com'
AuthServer__RequireHttpsMetadata: 'false'
AuthServer__SwaggerClientId: 'IdentityService_Swagger'
AuthServer__SwaggerClientSecret: '1q2w3e*'
RabbitMQ__Connections__Default__HostName: '10.0.0.2'
RabbitMQ__Connections__EventBus__ClientName: 'TaskyIdentityService'
RabbitMQ__Connections__EventBus__ExchangeName: 'Tasky'
Serilog__WriteTo__[0]__Name: 'Seq'
Serilog__WriteTo__[0]__Args__serverUrl: 'https://seq.youtube.antosubash.com'
networks:
traefik-public:
external: true
Related Posts
Docker Deployment using docker swarm
In this post we will see how to setup docker swarm for your development environment.
Deploy redis, rabbitmq, seq, registry and postgres in docker swarm
In this post we will see how to deploy redis, rabbitmq, postgres and registry.
Setting up docker swarm with traefik and portainer
In this post we will see how to create a docker swarm and deploy traefik and portainer in our ubuntu server.