tiangolo / full-stack-fastapi-couchbase

Full stack, modern web application generator. Using FastAPI, Couchbase as database, Docker, automatic HTTPS and more.
MIT License
442 stars 83 forks source link

Bad gateway error installing on macOs Mojave with Docker for Mac #1

Closed valentierra closed 5 years ago

valentierra commented 5 years ago

Happy New Year Tiangolo!

I've just noticed the Impressive work you've done with FastAPI. Congratulations! Great Job!

I wanted to give a try to this new version, having no problems before with full-stack-flask-couchbase, but this time some services seem to have a problem with the gateway. The frontend on localhost didn't allow me to login, the localhost/api page shows a "Bad gateway" message, and localhost/docs and localhost/redoc pages didn't start properly. On the contrary, Couchbase console, Celery Flower and Traefik pages worked perfectly.

Following the workarounds provided by Docker here https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds, I couldn't find a way to determine the Docker engine IP to redirect dev..com.

Would it be better to work full-stack-fastapi-couchbase with Docket Toolbox instead of Docker for Mac?

Any guidance is much appreciated!

tiangolo commented 5 years ago

Happy New Year Tiangolo!

Thanks! The same to you!

I've just noticed the Impressive work you've done with FastAPI. Congratulations! Great Job!

Awesome, thanks!


If you are being able to open the normal frontend but it has errors logging in, then the problem is not Docker but this stack.

You are better off with Docker for Mac than with Docker Toolbox.

If you are seeing a plaintext "Bad gateway" it probably means that the intra-stack Traefik proxy is not being able to communicate with the backend (FastAPI).

Please check which services are down with:

docker-compose ps

It would show something like an Exit(1) with a number other than 0 (0 means "no errors").

I suspect that the sync-gateway might have had an error and with that, break the backend. I saw something similar happen once to a colleague, but only once, so I couldn't debug much further.

Please check the logs for the services that are down, so, for example, for the backend:

docker-compose logs backend

And let me know what you see (if you can copy the entire error that would be great).

valentierra commented 5 years ago

To be sure I have not messed with a previous installation, I reinstalled Docker for Mac and full-stack-fastapi-couchbase. I also cleaned the browser cache.

This time all services went up:

$ docker ps
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                        NAMES
a70d96627839        cycl_sync-gateway            "/entrypoint.sh /etc…"   About an hour ago   Up About an hour    0.0.0.0:4984-4985->4984-4985/tcp                        cycl_sync-gateway_1
09893adea22d        6c479d07dea5                 "bash /worker-start.…"   About an hour ago   Up About an hour    8888/tcp                        cycl_celeryworker_1
08e51d2a3fda        9a3d863d557f                 "bash /app/backend-s…"   About an hour ago   Up About an hour    80/tcp, 0.0.0.0:8888->8888/tcp                        cycl_backend_1
13292e45f1ff        rabbitmq:3                   "docker-entrypoint.s…"   About an hour ago   Up About an hour    4369/tcp, 5671-5672/tcp, 25672/tcp                        cycl_queue_1
78db564e2b5d        80b73c6715c8                 "bash -c 'while true…"   About an hour ago   Up About an hour    8888/tcp                        cycl_backend-tests_1
7a787ebec24c        totem/celery-flower-docker   "/usr/bin/dumb-init …"   About an hour ago   Up About an hour    0.0.0.0:5555->5555/tcp                        cycl_flower_1
02c4faa4e65f        cycl_frontend                "nginx -g 'daemon of…"   About an hour ago   Up About an hour    80/tcp                        cycl_frontend_1
a88bcf204885        couchbase:community-6.0.0    "/entrypoint.sh couc…"   About an hour ago   Up About an hour    8092-8096/tcp, 11207/tcp, 11210-11211/tcp, 0.0.0.0:8091->8091/tcp, 18091-18096/tcp   cycl_couchbase_1
a37af1326261        traefik:v1.6                 "/traefik --docker '…"   About an hour ago   Up About an hour    0.0.0.0:80->80/tcp, 0.0.0.0:8090->8080/tcp                        cycl_proxy_1

The outcome of each service tested through the browser:

1 - localhost: The page load to login form. When I input the user/password combination, it gave an "Incorrect email or password" error. 2 - localhost/api/: This time the text message was {"detail":"Not Found"} 3 - localhost/docs: The Swagger UI page loaded without problem 4 - localhost/redoc: The ReDoc page loaded without problem 5 - localhost:8091: After input the user/password combination it loaded the Couchbase Console with no problem 6 - localhost:5555: After input the user/password combination it loaded the Celery Flower page with no problem 7 -localhost:8090: The Traefik page loaded without problem. It only shows two (2) frontends (frontend-PathPrefix-1 and frontend-PathPrefix-api-docs-redoc-0) and two (2) backends (backend-backend-cycl and backend-frontend-cycl).

The last lines of the backend log show the following:

backend_1        | WARNING:__main__:Finished call to '__main__.init' after 70.389(s), this was the 41st time calling it.
backend_1        | INFO:__main__:Starting call to '__main__.init', this is the 42nd time calling it.
backend_1        | INFO:root:before config_couchbase
backend_1        | INFO:app.db.couchbase_utils:before is_couchbase_ready
backend_1        | INFO:app.db.couchbase_utils:after is_couchbase_ready
backend_1        | INFO:app.db.couchbase_utils:before setup_couchbase_services
backend_1        | INFO:app.db.couchbase_utils:after setup_couchbase_services
backend_1        | INFO:app.db.couchbase_utils:before setup_memory_quota
backend_1        | INFO:app.db.couchbase_utils:after setup_memory_quota
backend_1        | INFO:app.db.couchbase_utils:before setup_index_storage
backend_1        | INFO:app.db.couchbase_utils:after setup_index_storage
backend_1        | INFO:app.db.couchbase_utils:before ensure_couchbase_username_password
backend_1        | INFO:app.db.couchbase_utils:after ensure_couchbase_username_password
backend_1        | INFO:root:after config_couchbase
backend_1        | INFO:root:before ensure_create_bucket
backend_1        | INFO:root:after ensure_create_bucket
backend_1        | INFO:root:before get_bucket
backend_1        | INFO:root:after get_bucket
backend_1        | INFO:root:before ensure_create_primary_index
backend_1        | INFO:root:after ensure_create_primary_index
backend_1        | INFO:root:before ensure_create_type_index
backend_1        | INFO:root:after ensure_create_type_index
backend_1        | INFO:root:before ensure_create_full_text_indexes
backend_1        | INFO:root:after ensure_create_full_text_indexes
backend_1        | INFO:root:before ensure_create_couchbase_app_user sync
backend_1        | INFO:root:after ensure_create_couchbase_app_user sync
backend_1        | INFO:root:before upsert_user first superuser
backend_1        | INFO:root:after upsert_user first superuser
backend_1        | INFO:__main__:Service finished initializing
backend_1        | Using these many workers: 4
backend_1        | [2019-01-07 23:44:31 +0000] [11] [INFO] Starting gunicorn 19.9.0
backend_1        | [2019-01-07 23:44:31 +0000] [11] [INFO] Listening at: http://0.0.0.0:80 (11)
backend_1        | [2019-01-07 23:44:31 +0000] [11] [INFO] Using worker: uvicorn.workers.UvicornWorker
backend_1        | [2019-01-07 23:44:31 +0000] [14] [INFO] Booting worker with pid: 14
backend_1        | [2019-01-07 23:48:31 +0000] [14] [INFO] ('172.18.0.2', 43098) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-07 23:48:59 +0000] [14] [INFO] ('172.18.0.2', 43102) - "GET /api/ HTTP/1.1" 404
backend_1        | [2019-01-07 23:49:31 +0000] [14] [INFO] ('172.18.0.2', 43104) - "GET /docs HTTP/1.1" 200
backend_1        | [2019-01-07 23:49:32 +0000] [14] [INFO] ('172.18.0.2', 43104) - "GET /api/v1/openapi.json HTTP/1.1" 200
backend_1        | [2019-01-07 23:49:53 +0000] [14] [INFO] ('172.18.0.2', 43106) - "GET /redoc HTTP/1.1" 200
backend_1        | [2019-01-07 23:49:55 +0000] [14] [INFO] ('172.18.0.2', 43106) - "GET /api/v1/openapi.json HTTP/1.1" 200
backend_1        | [2019-01-07 23:52:30 +0000] [14] [INFO] ('172.18.0.2', 43200) - "GET /api/ HTTP/1.1" 404
backend_1        | [2019-01-07 23:53:02 +0000] [14] [INFO] ('172.18.0.2', 43226) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 00:09:42 +0000] [14] [INFO] ('172.18.0.2', 43904) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 00:10:06 +0000] [14] [INFO] ('172.18.0.2', 43924) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 00:12:07 +0000] [14] [INFO] ('172.18.0.2', 44008) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 00:32:40 +0000] [14] [INFO] ('172.18.0.2', 44860) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 00:32:45 +0000] [14] [INFO] ('172.18.0.2', 44862) - "GET /api/ HTTP/1.1" 404
backend_1        | [2019-01-08 00:32:49 +0000] [14] [INFO] ('172.18.0.2', 44864) - "GET /docs HTTP/1.1" 200
backend_1        | [2019-01-08 00:32:51 +0000] [14] [INFO] ('172.18.0.2', 44866) - "GET /api/v1/openapi.json HTTP/1.1" 200
backend_1        | [2019-01-08 00:33:05 +0000] [14] [INFO] ('172.18.0.2', 44868) - "GET /redoc HTTP/1.1" 200
backend_1        | [2019-01-08 00:33:06 +0000] [14] [INFO] ('172.18.0.2', 44868) - "GET /api/v1/openapi.json HTTP/1.1" 200
backend_1        | [2019-01-08 00:52:26 +0000] [14] [INFO] ('172.18.0.2', 45656) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 00:52:57 +0000] [14] [INFO] ('172.18.0.2', 45680) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 01:01:28 +0000] [14] [INFO] ('172.18.0.2', 46024) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 01:03:48 +0000] [14] [INFO] ('172.18.0.2', 46118) - "POST /api/v1/login/access-token HTTP/1.1" 422

The 10 last lines of each service log show the following:

sync-gateway_1   | 2019-01-07T23:44:24.484Z [INF] CRUD: Stored doc "userprofile::valentierr@tuta.io" / "2-400f4b879f81f9cec29ad91d8616cd59"
sync-gateway_1   | 2019-01-07T23:44:24.494Z [INF] Cache: Received #2 after  26ms ("userprofile::valentierr@tuta.io" / "2-400f4b879f81f9cec29ad91d8616cd59")
sync-gateway_1   | 2019-01-07T23:44:24.494Z [INF] Cache:     #2 ==> channel "*"
sync-gateway_1   | 2019-01-07T23:44:24.563Z [INF] HTTP:  #001: PUT /db/_user/valentierr@tuta.io (as ADMIN)
sync-gateway_1   | 2019-01-07T23:44:24.738Z [INF] Access: Computed channels for "valentierr@tuta.io": !:1
sync-gateway_1   | 2019-01-07T23:44:24.747Z [INF] Access: Computed roles for "valentierr@tuta.io":
sync-gateway_1   | 2019-01-07T23:44:24.855Z [INF] Auth: Saved _sync:user:valentierr@tuta.io: &{roleImpl:{Name_:valentierr@tuta.io ExplicitChannels_:valentierr@tuta.io:3 Channels_: Sequence_:3 PreviousChannels_: vbNo:<nil>} userImplBody:{Email_:valentierr@tuta.io Disabled_:false PasswordHash_:[36 50 97 36 49 48 36 115 70 52 52 107 74 52 115 71 56 79 71 101 75 80 105 86 105 112 105 110 46 89 67 53 115 57 75 46 89 121 115 66 98 53 107 47 88 84 104 81 46 56 117 76 89 101 57 89 52 71 115 75] OldPasswordHash_:<nil> ExplicitRoles_:superuser:3 RolesSince_: OldExplicitRoles_:[]} auth:0xc4205edd10 roles:[]}
sync-gateway_1   | 2019-01-07T23:44:24.855Z [INF] HTTP+: #001:     --> 201 Created  (292.2 ms)
sync-gateway_1   | 2019-01-07T23:44:24.860Z [INF] Cache: Received #3 ("_user/valentierr@tuta.io")
sync-gateway_1   | 2019-01-07T23:44:24.860Z [INF] Cache:     #3 ==> channel "*"
queue_1          | 2019-01-07 23:43:45.696 [info] <0.480.0> connection <0.480.0> (172.18.0.6:38084 -> 172.18.0.7:5672): user 'guest' authenticated and granted access to vhost'/'
queue_1          | 2019-01-07 23:43:45.836 [info] <0.465.0> connection <0.465.0> (172.18.0.6:38080 -> 172.18.0.7:5672): user 'guest' authenticated and granted access to vhost'/'
queue_1          | 2019-01-07 23:43:55.703 [info] <0.504.0> accepting AMQP connection <0.504.0> (172.18.0.9:57816 -> 172.18.0.7:5672)
queue_1          | 2019-01-07 23:43:55.720 [info] <0.504.0> connection <0.504.0> (172.18.0.9:57816 -> 172.18.0.7:5672): user 'guest' authenticated and granted access to vhost'/'
queue_1          | 2019-01-07 23:43:55.782 [info] <0.512.0> accepting AMQP connection <0.512.0> (172.18.0.9:57818 -> 172.18.0.7:5672)
queue_1          | 2019-01-07 23:43:55.798 [info] <0.512.0> connection <0.512.0> (172.18.0.9:57818 -> 172.18.0.7:5672): user 'guest' authenticated and granted access to vhost'/'
queue_1          | 2019-01-07 23:43:55.903 [info] <0.530.0> accepting AMQP connection <0.530.0> (172.18.0.9:57822 -> 172.18.0.7:5672)
queue_1          | 2019-01-07 23:43:55.929 [info] <0.530.0> connection <0.530.0> (172.18.0.9:57822 -> 172.18.0.7:5672): user 'guest' authenticated and granted access to vhost'/'
queue_1          | 2019-01-07 23:46:55.927 [error] <0.530.0> closing AMQP connection <0.530.0> (172.18.0.9:57822 -> 172.18.0.7:5672):
queue_1          | missed heartbeats from client, timeout: 60s
backend_1        | [2019-01-08 00:32:40 +0000] [14] [INFO] ('172.18.0.2', 44860) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 00:32:45 +0000] [14] [INFO] ('172.18.0.2', 44862) - "GET /api/ HTTP/1.1" 404
backend_1        | [2019-01-08 00:32:49 +0000] [14] [INFO] ('172.18.0.2', 44864) - "GET /docs HTTP/1.1" 200
backend_1        | [2019-01-08 00:32:51 +0000] [14] [INFO] ('172.18.0.2', 44866) - "GET /api/v1/openapi.json HTTP/1.1" 200
backend_1        | [2019-01-08 00:33:05 +0000] [14] [INFO] ('172.18.0.2', 44868) - "GET /redoc HTTP/1.1" 200
backend_1        | [2019-01-08 00:33:06 +0000] [14] [INFO] ('172.18.0.2', 44868) - "GET /api/v1/openapi.json HTTP/1.1" 200
backend_1        | [2019-01-08 00:52:26 +0000] [14] [INFO] ('172.18.0.2', 45656) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 00:52:57 +0000] [14] [INFO] ('172.18.0.2', 45680) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 01:01:28 +0000] [14] [INFO] ('172.18.0.2', 46024) - "POST /api/v1/login/access-token HTTP/1.1" 422
backend_1        | [2019-01-08 01:03:48 +0000] [14] [INFO] ('172.18.0.2', 46118) - "POST /api/v1/login/access-token HTTP/1.1" 422
celeryworker_1   | Please specify a different user using the --uid option.
celeryworker_1   |
celeryworker_1   | User information: uid=0 euid=0 gid=0 egid=0
celeryworker_1   |
celeryworker_1   |   uid=uid, euid=euid, gid=gid, egid=egid,
celeryworker_1   | [2019-01-07 23:43:55,722: INFO/MainProcess] Connected to amqp://guest:**@queue:5672//
celeryworker_1   | [2019-01-07 23:43:55,800: INFO/MainProcess] mingle: searching for neighbors
celeryworker_1   | [2019-01-07 23:43:56,972: INFO/MainProcess] mingle: all alone
celeryworker_1   | [2019-01-07 23:43:57,214: INFO/MainProcess] celery@09893adea22d ready.
celeryworker_1   | [2019-01-07 23:44:00,572: INFO/MainProcess] Events of group {task} enabled by remote.
flower_1         |         return create_transport(host, connect_timeout, ssl)
flower_1         |       File "/usr/local/lib/python3.5/site-packages/amqp/transport.py", line 299, in create_transport
flower_1         |         return TCPTransport(host, connect_timeout)
flower_1         |       File "/usr/local/lib/python3.5/site-packages/amqp/transport.py", line 95, in __init__
flower_1         |         raise socket.error(last_err)
flower_1         |     OSError: [Errno 111] Connection refused
flower_1         | [E 190107 23:43:17 events:123] Failed to capture events: '[Errno 111] Connection refused', trying again in 4 seconds.
flower_1         | [E 190107 23:43:21 events:123] Failed to capture events: '[Errno 111] Connection refused', trying again in 8 seconds.
flower_1         | [E 190107 23:43:29 events:123] Failed to capture events: '[Errno 111] Connection refused', trying again in 16 seconds.
flower_1         | [I 190107 23:43:45 mixins:231] Connected to amqp://guest:**@queue:5672//
frontend_1       | 172.18.0.2 - - [08/Jan/2019:00:32:15 +0000] "GET /js/start.ff0addf0.js HTTP/1.1" 200 2857 "http://localhost/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" "172.18.0.1"
frontend_1       | 172.18.0.2 - - [08/Jan/2019:00:32:16 +0000] "GET /service-worker.js HTTP/1.1" 200 965 "http://localhost/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" "172.18.0.1"
frontend_1       | 172.18.0.2 - - [08/Jan/2019:00:32:46 +0000] "GET /service-worker.js HTTP/1.1" 200 965 "http://localhost/service-worker.js" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" "172.18.0.1"
frontend_1       | 172.18.0.2 - - [08/Jan/2019:00:32:46 +0000] "GET /favicon.ico HTTP/1.1" 200 1150 "http://localhost/api/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" "172.18.0.1"
frontend_1       | 172.18.0.2 - - [08/Jan/2019:00:32:50 +0000] "GET /service-worker.js HTTP/1.1" 200 965 "http://localhost/service-worker.js" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" "172.18.0.1"
frontend_1       | 172.18.0.2 - - [08/Jan/2019:00:33:08 +0000] "GET /service-worker.js HTTP/1.1" 200 965 "http://localhost/service-worker.js" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" "172.18.0.1"
frontend_1       | 172.18.0.2 - - [08/Jan/2019:00:52:31 +0000] "GET /login HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" "172.18.0.1"
frontend_1       | 172.18.0.2 - - [08/Jan/2019:00:52:34 +0000] "GET /img/icons/favicon-32x32.png HTTP/1.1" 200 1271 "http://localhost/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" "172.18.0.1"
frontend_1       | 172.18.0.2 - - [08/Jan/2019:00:52:34 +0000] "GET /img/icons/favicon-16x16.png HTTP/1.1" 200 799 "http://localhost/login" "Mozilla/5.0 (Macintosh; Intel MacOS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" "172.18.0.1"
frontend_1       | 172.18.0.2 - - [08/Jan/2019:00:52:35 +0000] "GET /service-worker.js HTTP/1.1" 200 965 "http://localhost/service-worker.js" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" "172.18.0.1"
couchbase_1      | Starting Couchbase Server -- Web UI available at http://<ip>:8091
couchbase_1      | and logs available in /opt/couchbase/var/lib/couchbase/logs
proxy_1          | 172.18.0.1 - - [08/Jan/2019:01:01:28 +0000] "POST /api/v1/login/access-token HTTP/1.1" 422 172 "http://localhost/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" 68 "PathPrefix-api-docs-redoc-0" "http://172.18.0.8:80" 6ms
proxy_1          | time="2019-01-08T01:03:48Z" level=debug msg="vulcand/oxy/roundrobin/rr: begin ServeHttp on request" Request="{\"Method\":\"POST\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/api/v1/login/access-token\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept\":[\"application/json, text/plain, */*\"],\"Accept-Encoding\":[\"gzip, deflate, br\"],\"Accept-Language\":[\"en-GB,en-US;q=0.9,en;q=0.8\"],\"Connection\":[\"keep-alive\"],\"Content-Length\":[\"111\"],\"Content-Type\":[\"application/json;charset=UTF-8\"],\"Cookie\":[\"ui-auth-localhost%3A8091=eea86b42052ea95c5ae17791cfc66d2c\"],\"Origin\":[\"http://localhost\"],\"Referer\":[\"http://localhost/login\"],\"User-Agent\":[\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37\"]},\"ContentLength\":111,\"TransferEncoding\":null,\"Host\":\"localhost\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"172.18.0.1:59530\",\"RequestURI\":\"/api/v1/login/access-token\",\"TLS\":null}"
proxy_1          | time="2019-01-08T01:03:48Z" level=debug msg="vulcand/oxy/roundrobin/rr: Forwarding this request to URL" Request="{\"Method\":\"POST\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/api/v1/login/access-token\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept\":[\"application/json, text/plain, */*\"],\"Accept-Encoding\":[\"gzip, deflate, br\"],\"Accept-Language\":[\"en-GB,en-US;q=0.9,en;q=0.8\"],\"Connection\":[\"keep-alive\"],\"Content-Length\":[\"111\"],\"Content-Type\":[\"application/json;charset=UTF-8\"],\"Cookie\":[\"ui-auth-localhost%3A8091=eea86b42052ea95c5ae17791cfc66d2c\"],\"Origin\":[\"http://localhost\"],\"Referer\":[\"http://localhost/login\"],\"User-Agent\":[\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37\"]},\"ContentLength\":111,\"TransferEncoding\":null,\"Host\":\"localhost\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"172.18.0.1:59530\",\"RequestURI\":\"/api/v1/login/access-token\",\"TLS\":null}" ForwardURL="http://172.18.0.8:80"
proxy_1          | time="2019-01-08T01:03:48Z" level=debug msg="vulcand/oxy/forward: begin ServeHttp on request" Request="{\"Method\":\"POST\",\"URL\":{\"Scheme\":\"http\",\"Opaque\":\"\",\"User\":null,\"Host\":\"172.18.0.8:80\",\"Path\":\"\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept\":[\"application/json, text/plain, */*\"],\"Accept-Encoding\":[\"gzip, deflate, br\"],\"Accept-Language\":[\"en-GB,en-US;q=0.9,en;q=0.8\"],\"Connection\":[\"keep-alive\"],\"Content-Length\":[\"111\"],\"Content-Type\":[\"application/json;charset=UTF-8\"],\"Cookie\":[\"ui-auth-localhost%3A8091=eea86b42052ea95c5ae17791cfc66d2c\"],\"Origin\":[\"http://localhost\"],\"Referer\":[\"http://localhost/login\"],\"User-Agent\":[\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37\"]},\"ContentLength\":111,\"TransferEncoding\":null,\"Host\":\"localhost\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"172.18.0.1:59530\",\"RequestURI\":\"/api/v1/login/access-token\",\"TLS\":null}"
proxy_1          | time="2019-01-08T01:03:48Z" level=debug msg="vulcand/oxy/forward/http: begin ServeHttp on request" Request="{\"Method\":\"POST\",\"URL\":{\"Scheme\":\"http\",\"Opaque\":\"\",\"User\":null,\"Host\":\"172.18.0.8:80\",\"Path\":\"\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept\":[\"application/json, text/plain, */*\"],\"Accept-Encoding\":[\"gzip, deflate, br\"],\"Accept-Language\":[\"en-GB,en-US;q=0.9,en;q=0.8\"],\"Connection\":[\"keep-alive\"],\"Content-Length\":[\"111\"],\"Content-Type\":[\"application/json;charset=UTF-8\"],\"Cookie\":[\"ui-auth-localhost%3A8091=eea86b42052ea95c5ae17791cfc66d2c\"],\"Origin\":[\"http://localhost\"],\"Referer\":[\"http://localhost/login\"],\"User-Agent\":[\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37\"]},\"ContentLength\":111,\"TransferEncoding\":null,\"Host\":\"localhost\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"172.18.0.1:59530\",\"RequestURI\":\"/api/v1/login/access-token\",\"TLS\":null}"
proxy_1          | time="2019-01-08T01:03:48Z" level=debug msg="vulcand/oxy/forward/http: Round trip: http://172.18.0.8:80, code: 422, Length: 172, duration: 8.309962ms"
proxy_1          | time="2019-01-08T01:03:48Z" level=debug msg="vulcand/oxy/forward/http: completed ServeHttp on request" Request="{\"Method\":\"POST\",\"URL\":{\"Scheme\":\"http\",\"Opaque\":\"\",\"User\":null,\"Host\":\"172.18.0.8:80\",\"Path\":\"\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept\":[\"application/json, text/plain, */*\"],\"Accept-Encoding\":[\"gzip, deflate, br\"],\"Accept-Language\":[\"en-GB,en-US;q=0.9,en;q=0.8\"],\"Connection\":[\"keep-alive\"],\"Content-Length\":[\"111\"],\"Content-Type\":[\"application/json;charset=UTF-8\"],\"Cookie\":[\"ui-auth-localhost%3A8091=eea86b42052ea95c5ae17791cfc66d2c\"],\"Origin\":[\"http://localhost\"],\"Referer\":[\"http://localhost/login\"],\"User-Agent\":[\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37\"]},\"ContentLength\":111,\"TransferEncoding\":null,\"Host\":\"localhost\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"172.18.0.1:59530\",\"RequestURI\":\"/api/v1/login/access-token\",\"TLS\":null}"
proxy_1          | time="2019-01-08T01:03:48Z" level=debug msg="vulcand/oxy/forward: completed ServeHttp on request" Request="{\"Method\":\"POST\",\"URL\":{\"Scheme\":\"http\",\"Opaque\":\"\",\"User\":null,\"Host\":\"172.18.0.8:80\",\"Path\":\"\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept\":[\"application/json, text/plain, */*\"],\"Accept-Encoding\":[\"gzip, deflate, br\"],\"Accept-Language\":[\"en-GB,en-US;q=0.9,en;q=0.8\"],\"Connection\":[\"keep-alive\"],\"Content-Length\":[\"111\"],\"Content-Type\":[\"application/json;charset=UTF-8\"],\"Cookie\":[\"ui-auth-localhost%3A8091=eea86b42052ea95c5ae17791cfc66d2c\"],\"Origin\":[\"http://localhost\"],\"Referer\":[\"http://localhost/login\"],\"User-Agent\":[\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37\"]},\"ContentLength\":111,\"TransferEncoding\":null,\"Host\":\"localhost\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"172.18.0.1:59530\",\"RequestURI\":\"/api/v1/login/access-token\",\"TLS\":null}"
proxy_1          | time="2019-01-08T01:03:48Z" level=debug msg="vulcand/oxy/roundrobin/rr: completed ServeHttp on request" Request="{\"Method\":\"POST\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/api/v1/login/access-token\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept\":[\"application/json, text/plain, */*\"],\"Accept-Encoding\":[\"gzip, deflate, br\"],\"Accept-Language\":[\"en-GB,en-US;q=0.9,en;q=0.8\"],\"Connection\":[\"keep-alive\"],\"Content-Length\":[\"111\"],\"Content-Type\":[\"application/json;charset=UTF-8\"],\"Cookie\":[\"ui-auth-localhost%3A8091=eea86b42052ea95c5ae17791cfc66d2c\"],\"Origin\":[\"http://localhost\"],\"Referer\":[\"http://localhost/login\"],\"User-Agent\":[\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37\"]},\"ContentLength\":111,\"TransferEncoding\":null,\"Host\":\"localhost\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"172.18.0.1:59530\",\"RequestURI\":\"/api/v1/login/access-token\",\"TLS\":null}"
proxy_1          | 172.18.0.1 - - [08/Jan/2019:01:03:48 +0000] "POST /api/v1/login/access-token HTTP/1.1" 422 172 "http://localhost/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37" 69 "PathPrefix-api-docs-redoc-0" "http://172.18.0.8:80" 11ms

I am glad to help. Please don't hesitate if you need to ask me for further info or doing more tests.

valentierra commented 5 years ago

Just after stopping the full-stack and restarting it, the plaintext message "Bad Gateway" temporarily appeared for local/api, localhost/docs and localhost/redoc. A while later these services were again available, showing localhost/api the message {"detail": "Not Found"}.

I have noticed that this version of macOS Mojave hangs a bit with the queue of processes. It seems that it gives more stability but delays the execution of the programs.

tiangolo commented 5 years ago

Awesome, thanks for the thorough report.

By looking at your logs I think I spotted the error, I think I have a small bug in the frontend (from the copy/migration from full-stack).

I'm on it right now.

tiangolo commented 5 years ago

About it taking some time to be ready:

During startup, the backend sets everything up, configures Couchbase, creates the default user. Creates a userprofile doc for the first superuser, create the full-text search indexes, sets up Couchbase Sync Gateway, creates the same first superuser in Sync Gateway, etc.

During that process, it takes a little while, specially when starting from scratch, as it's creating the indexes and everything. Also, the backend starts trying to do all the process, but the database and Sync Gateway might not be ready to receive connections yet, so, the backend notices and just tries again until finally, Couchbase and Sync Gateway are ready to receive connections and perform operations.

That's probably the temporal "Bad Gateway". It means Traefik (the proxy) is not being able to talk to the backend yet. It might take up to 2 mins to do all that initial process and index creation, and then afterwards it should work.

To see if it is ready or not, or at which step it is right now, you can do:

docker-compose logs backend -f

The -f means "follow", so, it will keep showing the logs as they continue to apear.

You'll see it prints what part of the initialization it is doing, like:

...
backend_1        | INFO:app.db.couchbase_utils:before setup_couchbase_services
backend_1        | INFO:app.db.couchbase_utils:after setup_couchbase_services
backend_1        | INFO:app.db.couchbase_utils:before setup_memory_quota
backend_1        | INFO:app.db.couchbase_utils:after setup_memory_quota
...

As a side note, if you are wondering what "Couchbase Sync Gateway" does:

It allows mobile apps and frontend to synchronized parts of the database, for example, so that they can work offline.

In mobile apps you would use Couchbase Lite. In the frontend, you would use PouchDB to connect to the Sync Gateway.

Using that, you could get offline data that you can query locally in the app, modify it, save it, update it, and then when back online, it will synchronize everything (both ways).

And as the Vue.js frontend is already configured to work offline as a PWA, you would get a full offline PWA app, that then connects to the rest of the system.

tiangolo commented 5 years ago

Now, about the issue, yes, there was a bug in the frontend. It was sending the username and password as JSON body, instead of form data.

And OAuth2 requires form data for the login (just for the login, the rest is normal JSON).

Check the latest commit to see the exact 5 lines you have to update: https://github.com/tiangolo/full-stack-fastapi-couchbase/commit/aa74e3d397b4cd3033afe3413526bf5e12f0ae39


As a tip, you can use the UI in /docs to test the login, independently of the frontend, with the "Authorize" button. With that you would also be able to test all the protected API endpoints (the ones with a lock). ...that feature is what we earn by using OAuth2 :smile:

valentierra commented 5 years ago

Impeccable work, as usual! Thank you!

Also thanks for the fair explanation about how the full-stack-fastapi-couchbase works. I definitively give it a try to use it for mobile apps. Thanks for the tips on this matter and on the use of the Swagger UI as a test method for API endpoints.

I noticed the creation of new users is not available by default. How could I enable it to create more users?

Now it is about time to enjoy FastAPI speed! Thanks again!

tiangolo commented 5 years ago

Impeccable work, as usual! Thank you!

Thanks!


You can change the USERS_OPEN_REGISTRATION here: https://github.com/tiangolo/full-stack-fastapi-couchbase/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/env-backend.env#L13


Also, please check the latest commit: https://github.com/tiangolo/full-stack-fastapi-couchbase/commit/4e5399d402efe4f7fa7eab6b7c52c0716cb6a3a7

Moving all the path operation functions like /users/me and /users/open on top of parametrized ones like: /users/{user_id}.

That's because the first path operation that matches is used. And the path for /users/{user_id} would match /users/me, although /users/me has its own dedicated path operations.


Now it is about time to enjoy FastAPI speed! Thanks again!

:tada: :rocket:

valentierra commented 5 years ago

please check the latest commit: 4e5399d

After changing USERS_OPEN_REGISTRATION=True and updating user.py file, I was able to create a new user. However, when I checked out the Manage Users page, it doesn't show the new user. It seems is not registering the new user into the database as when I tried to log in with that new user, it was rejected as a valid one.

After stopping the system by giving docker-compose stop and then verifying the containers, I am getting the following states:

$ docker-compose ps
        Name                      Command                State     Ports
------------------------------------------------------------------------
cycl_backend-tests_1   bash -c while true; do sle ...   Exit 137
cycl_backend_1         bash /app/backend-start.sh       Exit 137
cycl_celeryworker_1    bash /worker-start.sh            Exit 1
cycl_couchbase_1       /entrypoint.sh couchbase-s ...   Exit 0
cycl_flower_1          /usr/bin/dumb-init /opt/ce ...   Exit 143
cycl_frontend_1        nginx -g daemon off;             Exit 0
cycl_proxy_1           /traefik --docker  --docke ...   Exit 0
cycl_queue_1           docker-entrypoint.sh rabbi ...   Exit 0
cycl_sync-gateway_1    /entrypoint.sh /etc/sync_g ...   Exit 2

Once restarted by giving docker-compose up -d, the system provided the following states:

$ docker-compose ps
        Name                      Command               State                                                        Ports
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cycl_backend-tests_1   bash -c while true; do sle ...   Up       8888/tcp
cycl_backend_1         bash /app/backend-start.sh       Up       80/tcp, 0.0.0.0:8888->8888/tcp
cycl_celeryworker_1    bash /worker-start.sh            Exit 1
cycl_couchbase_1       /entrypoint.sh couchbase-s ...   Up       11207/tcp, 11210/tcp, 11211/tcp, 18091/tcp, 18092/tcp, 18093/tcp, 18094/tcp, 18095/tcp, 18096/tcp,
                                                                 0.0.0.0:8091->8091/tcp, 8092/tcp, 8093/tcp, 8094/tcp, 8095/tcp, 8096/tcp
cycl_flower_1          /usr/bin/dumb-init /opt/ce ...   Up       0.0.0.0:5555->5555/tcp
cycl_frontend_1        nginx -g daemon off;             Up       80/tcp
cycl_proxy_1           /traefik --docker  --docke ...   Up       0.0.0.0:80->80/tcp, 0.0.0.0:8090->8080/tcp
cycl_queue_1           docker-entrypoint.sh rabbi ...   Up       25672/tcp, 4369/tcp, 5671/tcp, 5672/tcp
cycl_sync-gateway_1    /entrypoint.sh /etc/sync_g ...   Up       0.0.0.0:4984->4984/tcp, 0.0.0.0:4985->4985/tcp

Could the fatal 137 error mess up with the system when restarting? I mentioned this because just after updating the user.py file, I made a mistake and instead of restarting with docker-compose up -d, I did it with docker-compose build which seems to bring back all the old problems. So using the Docker for Mac Desktop, I went to Preference > Reset > Reset disk image to rebuild up the images from scratch. After that, the system is starting as expected but presenting the states I mentioned above

tiangolo commented 5 years ago

Sorry for the delay here. I just tested with a recent version of the project and it seems to be working as expected. If the problem persists, can you try with a recent version of the project generator?

The "Exit 137" normally means that the last time you did docker-compose stop (or turn off your computer, etc) it killed those containers after a timeout. That shouldn't be a problem here.

valentierra commented 5 years ago

Thanks for the reply Tiangolo! I will update my version of the project generator. It seems currently there is a memory leak with the Docker version for Mac. I am following the issue to be aware of when it is solved. In the meantime, I am spending some time studying more about Vue and Nuxt.

tiangolo commented 5 years ago

Cool!

memory leak with the Docker version for Mac

I'm sorry to hear that 😕

Vue and Nuxt

Great! Let me suggest you TypeScript, it will help with a lot of things and simplify development. And the next version of Vue is being re-writen in it and will have full support. I think it's worthwhile. 😊

valentierra commented 5 years ago

Thanks for the suggestion! Will start working with TypeScript immediately! 👍 👍 👍