Apollo Federation cannot get connection running in docker-compose: Couldn't load service definitions for...reason: connect ECONNREFUSED 127.0.0.1:80 - kotlin

I am trying to run two applications by docker-compose without success, the federation cannot connect on service. Both works well out of docker.
Below follow the projects:
Apollo Server Federation in NodeJS
GraphQL API In Kotlin + Spring Boot + expediagroup:graphql-kotlin-spring-server
docker-compose.yml
version: '3'
services:
myservice:
image: 'myservice:0.0.1-SNAPSHOT'
container_name: myservice_container
ports:
- 8080:8080
expose:
- 8080
apollo_federation:
image: 'apollo-federation'
build: '.'
container_name: apollo_federation_container
restart: always
ports:
- 4000:4000
expose:
- 4000
environment:
ENDPOINT: "http://myservice/graphql"
depends_on:
- myservice
I already try a lot of combinations in my endpoint ex: http://myservice:8080/graphql, http://localhost:8080/graphql, http://myservice, etc...
index.js from Apollo Project
const { ApolloServer } = require("apollo-server");
const { ApolloGateway } = require("#apollo/gateway");
const gateway = new ApolloGateway({
serviceList: [
{ name: "Service1", url: process.env.ENDPOINT || 'http://localhost:8080/graphql' },
]
});
const server = new ApolloServer({
gateway,
subscriptions: false
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
})
Error Log
Error checking for changes to service definitions: Couldn't load service definitions for "Service1" at http://myservice/graphql: request to http://myservice/graphql failed, reason: connect ECONNREFUSED 172.18.0.3:80
if I try to test from browse I get a error 500 by graphiql.
I am already tried to use a nginx as reverse-proxy, but no success
I am using the last libs in projects.
Thanks

In your code, you are using
{ name: "Service1", url: process.env.ENDPOINT || 'http://localhost:8080/graphql' },
which is pulling process.env.ENDPOINT, which is defined in your docker-compose file as using port 80:
environment:
ENDPOINT: "http://myservice/graphql" # This is port 80

Related

Unable to invoke another service with Dapr

I'm having major problems getting Dapr up and running with my microservices. Every time I try to invoke another service, it returns a 500 error with the message
client error: the server closed connection before returning the first response byte. Make sure the server returns 'Connection: close' response header before closing the connection
The services and dapr sidecars are currently running in docker-compose on our dev machines but will run in Kubernetes when it is deployed properly.
When I look at the logs for the dapr containers in Docker for Windows, I can see the application being discovered on port 443 and a few initialisation messages but nothing else ever gets logged after that, even when I make my invoke request.
I have a container called clients, which I'm calling an API called test in it and this is then trying to call Microsoft's example weather forecast API in another container called simpleapi.
I'm using swaggerUI to call the apis. The test api returns 200 but when I put a breakpoint on the invoke, I can see the response is 500.
If I call the weatherforecast api directly using swaggerui, it returns a 200 with the expected payload.
I have the Dapr dashboard running in a container and it doesn't show any applications.
Docker-Compose.yml
version: '3.4'
services:
clients:
image: ${DOCKER_REGISTRY-}clients
container_name: "Clients"
build:
context: .
dockerfile: Clients/Dockerfile
ports:
- "50002:50002"
depends_on:
- placement
- database
networks:
- platform
clients-dapr:
image: "daprio/daprd:edge"
container_name: clients-dapr
command: [
"./daprd",
"-app-id", "clients",
"-app-port", "443",
"-placement-host-address", "placement:50006",
"-dapr-grpc-port", "50002"
]
depends_on:
- clients
network_mode: "service:clients"
simpleapi:
image: ${DOCKER_REGISTRY-}simpleapi
build:
context: .
dockerfile: SimpleAPI/Dockerfile
ports:
- "50003:50003"
depends_on:
- placement
networks:
- platform
simpleapi-dapr:
image: "daprio/daprd:edge"
container_name: simpleapi-dapr
command: [
"./daprd",
"-app-id", "simpleapi",
"-app-port", "443",
"-placement-host-address", "placement:50006",
"-dapr-grpc-port", "50003"
]
depends_on:
- simpleapi
network_mode: "service:simpleapi"
placement:
image: "daprio/dapr"
container_name: placement
command: ["./placement", "-port", "50006"]
ports:
- "50006:50006"
networks:
- platform
dashboard:
image: "daprio/dashboard"
container_name: dashboard
ports:
- "8080:8080"
networks:
- platform
networks:
platform:
Test controller from the Clients API.
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
[HttpGet]
public async Task<ActionResult> Get()
{
var httpClient = DaprClient.CreateInvokeHttpClient();
var response = await httpClient.GetAsync("https://simpleapi/weatherforecast");
return Ok();
}
}
This is a major new project for my company and it's looking like we're going to have to abandon Dapr and implement everything ourselves if we can't get this working soon.
I'm hoping there's some glaringly obvious problem here.
Actually turned out to be quite simple.
I needed to tell dapr to use ssl.
The clients-dapr needed the -app-ssl parameter so clients-dapr should have been as follows (the simpleapi-dapr needs the same param adding too)
clients-dapr:
image: "daprio/daprd:edge"
container_name: clients-dapr
command: [
"./daprd",
"-app-id", "clients",
"-app-port", "443",
"-app-ssl",
"-placement-host-address", "placement:50006",
"-dapr-grpc-port", "50002"
]
depends_on:
- clients
network_mode: "service:clients"
you can run your service-specific port without docker and check dapr works as expected. you can specify http port & grpc port.
dapr run `
--app-id serviceName `
--app-port 5139 `
--dapr-http-port 3500 `
--dapr-grpc-port 50001 `
--components-path ./dapr-components
if the above setup works then you can setup with the docker. check above solution

Deploying cube.js using serverless framework results in an error

I am trying to deploy cube.js project using serverless framework on aws and when I access the endpoint produced by serverless, it results in the following error on the browser
Cannot GET /
Here is my serverless.yml file
service: cloud-analytics
provider:
name: aws
stage: production
runtime: nodejs8.10
iamRoleStatements:
- Effect: "Allow"
Action:
- "sns:*"
- "athena:*"
- "s3:*"
- "glue:*"
Resource:
- "*"
vpc:
securityGroupIds:
- sg-xxxxxxxxx # Your DB and Redis security groups here
subnetIds:
- subnet-xxxxxxxxx
environment:
CUBEJS_AWS_KEY: ${opt:awsKey}
CUBEJS_AWS_SECRET: ${opt:awsSecret}
CUBEJS_AWS_REGION: us-east-1
CUBEJS_AWS_S3_OUTPUT_LOCATION: ${opt:location}
REDIS_URL: ${opt:redis_url_with_port}
CUBEJS_DB_TYPE: athena
CUBEJS_API_SECRET:XXXXXX
CUBEJS_APP: "${self:service.name}-${self:provider.stage}"
NODE_ENV: ${self:provider.stage}
AWS_ACCOUNT_ID:
Fn::Join:
- ""
- - Ref: "AWS::AccountId"
functions:
cubejs:
handler: cube.api
timeout: 30
events:
- http:
path: /
method: GET
- http:
path: /{proxy+}
method: ANY
cubejsProcess:
handler: cube.process
timeout: 630
events:
- sns: "${self:service.name}-${self:provider.stage}-process"
plugins:
- serverless-express
I have followed this steps in this blog to set up NAT https://medium.com/#philippholly/aws-lambda-enable-outgoing-internet-access-within-vpc-8dd250e11e12
Cube.js file is as follows with server core options
const AWSHandlers = require('#cubejs-backend/serverless-aws');
const AthenaDriver = require('#cubejs-backend/athena-driver');
module.exports = new AWSHandlers({
externalDbType: 'athena',
externalDriverFactory: () => new AthenaDriver({
accessKeyId: process.env.CUBEJS_AWS_KEY,
secretAccessKey: process.env.CUBEJS_AWS_SECRET,
region: process.env.CUBEJS_AWS_REGION,
S3OutputLocation: process.env.CUBEJS_AWS_S3_OUTPUT_LOCATION
})
});
When I run the endpoint
https://xxxxx.execute-api.us-east-1.amazonaws.com/production/
which is produced by the serverless api gateway I get the error
Cannot GET /
On Cloudwatch I see the cubejs lambda being invoked and see logs for start and end request id. I dont see any logs on cubejsProcess lambda.
Where/How can I debug this to see where the issue is?
By default in production mode Cube.js disables dev server capability and it's why you don't see any Playground working at / path: https://cube.dev/docs/deployment#production-mode. Please use REST API to test your deployment: https://cube.dev/docs/rest-api.

Odd behavior with axios, nuxt, and docker

I am setting up a full-stack application with nuxt js running my client-side code, express js running my api, and mysql as my database. To run all of these processes I have been using docker, more specifically docker-compose. After much configuration, I have gotten all three images to run together. There is one problem though, I cannot figure out how to make calls to my api with nuxt/axios.
I have tried many different tactics. My express api is available to the "outside-world" at http://localhost:8080, so I set up my axios baseURL to reflect that. I ran some test axios gets in some nuxt js middleware, and kept getting a connection refusal error. I finally figured out that I could use docker-compose networks to connect my frontend and backend, so I remapped my axios baseURL to http://api:8080 (api is the name of my docker-compose image), and in the axios request in the nuxt js middleware, it worked like a charm. Later, I was writing some code, and I wanted to send an axios request in a vue method. Even though the axios requests in the middleware were working with this baseURL, this new axios request in the method gave the error
commons.app.js:434 OPTIONS http://api:8080/api/v1/get/colors net::ERR_NAME_NOT_RESOLVED
I tried changing my axios baseURL back to localhost, and now the axios request in the methods works, but the axios request in the middleware doesn't work.
docker-compose.yml
version: "3.3"
services:
mysql:
container_name: mysql
image: mysql:5.7
environment:
MYSQL_USER: ${MYSQL_DEV_USER}
MYSQL_PASSWORD: ${MYSQL_DEV_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DEV_DATABASE}
MYSQL_ROOT_PASSWORD: ${MYSQL_DEV_ROOT_PASSWORD}
ports:
- 3306:3306
restart: always
volumes:
- mysql_data:/var/lib/mysql
- ./database/create_db.sql:/docker-entrypoint-initdb.d/create_db.sql
- ./database/insert_db.sql:/docker-entrypoint-initdb.d/insert_db.sql
api:
container_name: api
depends_on:
- mysql
links:
- mysql
build:
context: ./backend
dockerfile: Dockerfile-dev
environment:
NODE_ENV: development
MYSQL_USER: ${MYSQL_DEV_USER}
MYSQL_PASSWORD: ${MYSQL_DEV_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DEV_DATABASE}
MYSQL_HOST_IP: mysql
PORT: ${API_PORT}
HOST: ${API_HOST}
expose:
- 8080
ports:
- 8080:8080
volumes:
- ./backend:/app
command: npm run dev
frontend:
container_name: frontend
depends_on:
- api
links:
- api
build:
context: ./frontend
dockerfile: Dockerfile-dev
environment:
NUXT_PORT: 3000
NUXT_HOST: 0.0.0.0
NODE_ENV: development
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
API_HOST: api
API_PORT: ${API_PORT}
API_PREFIX: ${API_PREFIX}
expose:
- 3000
ports:
- 3000:3000
volumes:
- ./frontend:/app
command: npm run dev
volumes:
mysql_data:
nuxt.config.js
axios: {
baseURL: 'http://api:8080/api/v1'
},
nuxt middleware
export default async function({ app, redirect, error }) {
try {
const response = await app.$axios.$get('/auth/login')
if (!response.success) {
throw new Error(response.message)
}
redirect('/admin')
} catch (err) {
console.log(err)
await app.$auth.logout()
error({ message: err.message, statusCode: 500 })
}
}
nuxt method
methods: {
async test() {
const colors = await this.$nuxt.$axios.$get('/get/colors')
console.log(colors)
}
}
Thank you all so much!
P.S. This is my first stack overflow question!
Nuxt's Axios module offers two configuration options for URL prefixes, one for server and one for the browser.
axios: {
baseURL: 'http://api:8080/api/v1',
browserBaseURL: 'http://localhost/8080/api/v1'
},

port in vue.config.js is ignored

I want to develop a Vue app and serve it to external domain.
So I wrote a vue.config.js to redirect development server to public like below:
module.exports = {
devServer: {
disableHostCheck: true,
host: '0.0.0.0',
port: 8080,
public: 'mypublicpage.com:8080',
},
publicPath: '/'
}
Just before few hours ago, I got the expected result of above setting file like this
App running at:
- Local: http://localhost:8080
- Network: http://mypublicpage.com:8080/
But now my Local port is always randomized, so I can't access my Vue app through the public(Network) URL. I still don't know why this happens.
App running at:
- Local: http://localhost:19282 port changes on every npm run serve
- Network: http://mypublicpage.com:8080/

docker swarm custom containers with traefik

I'm trying to set up a docker swarm using traefik in digital ocean. I followed this tutorial and I get it to work entirely until I add one of my custom made containers. I am trying to simply add one first (there are 14 in total) and they are all very very similar, all of them are express apps that serve as restful API's handling one resource per service. However, when trying to access that specific subdomain I get a connection refused error.
Here's my docker-stack.yml file:
version: '3.6'
services:
traefik:
image: traefik:latest
networks:
- mynet
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/traefik.toml
ports:
- "80:80"
- "8080:8080"
command: --api
main:
image: nginx
networks:
- mynet
deploy:
labels:
- "traefik.port=80"
- "traefik.backend=main"
- "traefik.frontend.rule=Host:domain.com"
two:
image: jwilder/whoami
networks:
- mynet
deploy:
labels:
- "traefik.port=8000"
- "traefik.backend=two"
- "traefik.frontend.rule=Host:two.domain.com"
three:
image: emilevauge/whoami
networks:
- mynet
deploy:
labels:
- "traefik.port=80"
- "traefik.backend=three"
- "traefik.frontend.rule=Host:three.domain.com"
user-service:
image: hollarves/users:latest
env_file:
- .env.user
networks:
- mynet
deploy:
labels:
- "traefik.port=80"
- "traefik.backend=users"
- "traefik.frontend.rule=Host:users.domain.com"
networks:
mynet:
driver: overlay
As I said, going to two.domain.com and three.domain.com works fine, and the whoami containers respond with their info. However, I get a connection refused error when trying users.domain.com
Note: domain.com is an actual domain I am using that is live pointing to a digitalocean cluster, I'm just hiding it for privacy reasons.
The entrypoint for this users-service is:
if (process.env.NODE_ENV !== "production") {
require("dotenv").load()
}
const express = require("express"),
bodyParser = require("body-parser"),
logger = require("morgan"),
//helmet = require("helmet"),
cors = require("cors"),
PORT = parseInt(process.env.PORT, 10) || 80
const server = express(),
routes = require("./server/routes")
//server.use(helmet())
server.use(cors())
server.use(logger("dev"))
server.use(bodyParser.json())
server.use("/", routes)
/*eslint no-console: ["error", { allow: ["log"] }] */
const serverObj = server.listen(PORT, () => { console.log("Server listening in PORT ", PORT) })
module.exports = serverObj
I can also confirm that this service is listening on PORT 80 as that's what it outputs when fetching logs from it using docker service logs test-stack_user-service:
test-stack_user-service.1.35p3lxzovphr#node-2 | > users-mueve#0.0.1 start /usr/src/app
test-stack_user-service.1.35p3lxzovphr#node-2 | > node server.js
test-stack_user-service.1.35p3lxzovphr#node-2 |
test-stack_user-service.1.35p3lxzovphr#node-2 | Server listening in PORT 80
Here is my traefik.toml config file just in case:
debug = true
logLevel = "DEBUG"
defaultEntryPoints = ["http"]
[entryPoints]
[entryPoints.http]
address = ":80"
[retry]
[docker]
endpoint="unix:///var/run/docker.sock"
exposedByDefault=true
watch=true
swarmmode=true
I can also see the containers in the traefik dashboard like I used to in my local environment.
I feel like I'm missing a very small detail that is preventing my service from working correctly. Any pointers will be extremely appreciated.
Thanks!