I am trying to deploy Flutter web app that consume Django REST API in the backend. And my system also has Celery in background.
production.yml
version: '3'
volumes:
production_postgres_data: {}
production_postgres_data_backups: {}
production_traefik: {}
services:
flutter:
build:
context: .
dockerfile: ./compose/local/flutter/Dockerfile
image: send_and_expire_flutter
container_name: send_and_expire_flutter
depends_on:
- django
ports:
- "8080:8080"
django: &django
build:
context: .
dockerfile: ./compose/production/django/Dockerfile
image: send_and_expire_production_django
depends_on:
- postgres
- redis
env_file:
- ./.envs/.production/.django
- ./.envs/.production/.postgres
command: /start
postgres:
build:
context: .
dockerfile: ./compose/production/postgres/Dockerfile
image: send_and_expire_production_postgres
volumes:
- production_postgres_data:/var/lib/postgresql/data:Z
- production_postgres_data_backups:/backups:z
env_file:
- ./.envs/.production/.postgres
traefik:
build:
context: .
dockerfile: ./compose/production/traefik/Dockerfile
image: send_and_expire_production_traefik
depends_on:
- django
volumes:
- production_traefik:/etc/traefik/acme:z
ports:
- "0.0.0.0:80:80"
- "0.0.0.0:443:443"
- "0.0.0.0:5555:5555"
redis:
image: redis:6
celeryworker:
<<: *django
image: send_and_expire_production_celeryworker
command: /start-celeryworker
celerybeat:
<<: *django
image: send_and_expire_production_celerybeat
command: /start-celerybeat
flower:
<<: *django
image: send_and_expire_production_flower
command: /start-flower
awscli:
build:
context: .
dockerfile: ./compose/production/aws/Dockerfile
env_file:
- ./.envs/.production/.django
volumes:
- production_postgres_data_backups:/backups:z
urls.py
urlpatterns += [
# API base url
path("api/", include("config.api_router")),
# DRF auth token
path("api/auth-token/", obtain_auth_token),
path("api/schema/", SpectacularAPIView.as_view(), name="api-schema"),
path(
"api/docs/",
SpectacularSwaggerView.as_view(url_name="api-schema"),
name="api-docs",
),
]
Because I need to solve CORS problem then I have to use reverse-proxy feature. I add my Flutter route to it. Here is my traefik.yml
log:
level: INFO
entryPoints:
web:
# http
address: ":80"
http:
# https://docs.traefik.io/routing/entrypoints/#entrypoint
redirections:
entryPoint:
to: web-secure
web-secure:
# https
address: ":443"
flower:
address: ":5555"
certificatesResolvers:
letsencrypt:
# https://docs.traefik.io/master/https/acme/#lets-encrypt
acme:
email: "sarit@elcolie.com"
storage: /etc/traefik/acme/acme.json
# https://docs.traefik.io/master/https/acme/#httpchallenge
httpChallenge:
entryPoint: web
http:
routers:
flutter-secure-router:
rule: "Path(`/`)"
entryPoints:
- web-secure
service: flutter
tls:
certResolver: letsencrypt
web-secure-router:
rule: "Path(`/api/*`) || Path(`/admin/*`)"
entryPoints:
- web-secure
middlewares:
- csrf
service: django
tls:
# https://docs.traefik.io/master/routing/routers/#certresolver
certResolver: letsencrypt
flower-secure-router:
rule: "Host(`flower.send-n-expire.link`)"
entryPoints:
- flower
service: flower
tls:
# https://docs.traefik.io/master/routing/routers/#certresolver
certResolver: letsencrypt
middlewares:
csrf:
# https://docs.traefik.io/master/middlewares/headers/#hostsproxyheaders
# https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
headers:
hostsProxyHeaders: ["X-CSRFToken"]
services:
flutter:
loadBalancer:
servers:
- url: http://flutter:8080
django:
loadBalancer:
servers:
- url: http://django:5000
flower:
loadBalancer:
servers:
- url: http://flower:5555
providers:
# https://docs.traefik.io/master/providers/file/
file:
filename: /etc/traefik/traefik.yml
watch: true
treafik/Dockefile
FROM traefik:v2.2.11
RUN mkdir -p /etc/traefik/acme \
&& touch /etc/traefik/acme/acme.json \
&& chmod 600 /etc/traefik/acme/acme.json
COPY ./compose/production/traefik/traefik.yml /etc/traefik
traefik_1 | time="2022-01-24T13:44:35Z" level=error msg="Unable to obtain ACME certificate for domains \"send-n-expire.link\": unable to generate a certificate for the domains [send-n-expire.link]: error: one or more domains had a problem:\n[send-n-expire.link] acme: error: 400 :: urn:ietf:params:acme:error:dns :: no valid A records found for send-n-expire.link; no valid AAAA records found for send-n-expire.link, url: \n" routerName=flower-secure-router@file rule="Host(`send-n-expire.link`)" providerName=letsencrypt.acme
DNS supposed to propagate successfully already it has been a day.
Problems:
How to to correctly enable https
and route my frontend and backend using Path
?
Here is an example
-
http://flower.send-n-expire.link:5555/
shows 404 and Not secure -
https://www.send-n-expire.link/
shows 404 and Not secure - http://www.send-n-expire.link:8080 To prove that container is up and running