Cannot get a valid response from Docker Registry remote API - node.js

I'm using Nodejs & request to form my API calls, I can make API calls directly to a UnixSocket with it however it fails every attempt when requesting from the Docker registry container I have running, so I believe it's the fault of my registry configuration.
I've set it up out of the box just like the doc steps below.
docker run -d -p 5000:5000 --restart=always --name registry registry:2
docker pull alpine
docker tag alpine localhost:5000/alpine
docker push localhost:5000/alpine
The code I'm using to request is below, it receives a 404 not found.
const request = require('request')
request({
method: 'GET',
uri: 'http://localhost:5000/images/json', // status 404
// uri: 'http://unix:/var/run/docker.sock:/images/json', // this works
headers: { host : 'localhost' }
}, (e, res, body) => {
if(e) return console.error(e)
console.log(res.statusCode == 200 ? JSON.parse(body) : res.statusCode)
})
To be clear, this code is just to demonstrate that I'm making a GET request that should be well-formed.
What has to be done to allow a running registry container respond to the remote API?

Docker Registry doesn't have the /images/json API, and the Docker Registry's API does not compatible with docker engine API.
To get the image list of Docker Registry, please try GET /v2/_catalog. Full document can be found here.

Related

Why does my node.js HTTP request fail with code 501?

I have been trying to call a web service running in Docker on my machine on port 4801. I can access the service in the browser, via curl and via .NET's HttpClient, but if I try from node.js (either using axios or the native http module) the request fails with status code 501 Not Implemented.
I eventually tracked the problem down to the fact that there is another process, called ServiceLayer.exe (description: "Logitech VC ServiceLayer"), listening on port 4801. How is Docker able to expose my service on that port such that it can be accessed by the methods listed above, but not from node?
Here is a minimal repro:
const axios = require("axios");
axios.get("http://localhost:4801")
.then(response => console.log(response.data))
.catch(error => console.log({
status: error.response.status,
headers: error.response.headers
}));
docker run -p 4801:8000 -d crccheck/hello-world
node test.js
Output:
{
status: 501,
headers: { server: 'websocket-sharp/1.0', connection: 'close' }
}
I am guessing the websocket-sharp bit is potentially significant.

How do I connect React native app with node js?

I have already created backend using node js for sigin & signup page. Now I want to connect to node js . But i have no idea how to do that. I want to connect both react native with my node js. Can you help me ?
simply as how we do for web apps.
here is an example of error reporting
export default async function (body) {
console.log(JSON.stringify(body))
const res = await fetch(`${host}/api/report`, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
},
})
const { message } = await res.json()
if (message) return Toast({ message: message });
else return Toast({ message: 'network error' });
}
I have used fetch to send a POST request to my nodejs server
use API tool like postman or other and make your your nodejs APIs works fine and then connect to your React Native app as above.
You can use ngrok to connect Node with react-native. Run this command:
npm i ngrok -g # installing it globally
Then open another terminal. Run:
ngrok http 3000 # the port you are running on node
Then it will show an alternative link that you can use to test with your Node.
Note: if ngrok http 3000 doesn't work, try ngrok http -region us 3000.
The available ones are us, eu, ap, and au. In my case eu worked for me.
Then copy the link generated e.g. http://8074-129-205-124-100.eu.ngrok.io and test your backend if it displays APIs.
If the link works then you can use it with fetch. Uploading json data to send to MongoDB as the case maybe.

How to address backend host with axios, when frontend and backend are in virtual docker network

I'm building a simple Website with login, and my vue-frontend needs to retrieve user data from my nodejs-backend which connects to a sql database.
I decided to use docker-compose for this, and as I understand, docker-compose sets up a network automatically for the services that are mentioned in my docker-compose.yml.
What doesn't seem to work, is the way I address the backend in my code.
I suspect that it might be because of the way I use axios to send a request to my backend.
I have inspected the default docker-network and was able to ping from my frontend to my backend using the dns names I found in the network-configuration.
But using the same names inside my code didn't work.
What does work, is mapping a host port to my exposed api port and using http://localhost:5000 as address, but this defeats the purpose of a docker network.
my docker-compose.yml:
version: '3.3'
services:
vue-frontend:
image: flowmotion/vue-js-frontend
ports:
- 8070:80
depends_on:
- db-user-api
db-user-api:
image: flowmotion/user-db-api
environment:
- PORT=5000
ports:
- 5000:5000 #only needed if docker network connection can't be established
the Vue-fontend files in question:
Login.vue
methods: {
async login() {
try {
const response = await authenticationService.login({
email: this.email,
password: this.password
});
this.$store.dispatch("setToken", response.data.token);
this.$store.dispatch("setUser", response.data.user);
this.$router.push({ path: "/" });
} catch (error) {
this.showError = true;
this.error = error.response.data.error;
}
}
}
};
</script>
authenticationService.js
import api from "#/services/api";
export default {
login(credentials) {
return api().post("login", credentials);
}
};
api.js
import axios from 'axios';
import config from '../config/config';
export default () => {
return axios.create({
baseURL: config.userBackendServer
});
};
config.js ()
module.exports = {
userBackendServer: 'http://cl-dashboard_db-user-api_1:5000' //this doesn't seem to work
};
//using 'http://localhost:5000' works if ports are mapped to host machine.
expected result would be my backend doing a sql lookup.
actuel result is, instead of connecting to my backend my frontend gives me a 404 status and my backend is never reached
you are correct assuming containers in the docker network can talk to each other without opening any ports to the outer world.
point is- your vue app is not in any container- it is served from a container as a js script file to your browser, which is the one sending the requests to your node backend. since your browser is by any means not inside the docker network - you must use the outer port mapping (localhost:5000 in your case) to reach the backend.
let me know if you have any more questions about that.

How to get a list of running services from one docker container

I have a node.js application running in Docker (using docker-compose).
I would like for it to use a list of the other services running (name, labels, etc.).
Is there a way from within one container to get a list of other services I can access?
Here's an example:
version: "3"
services:
service_1:
container_name: service_1
labels: label_1
service_2:
container_name: service_2
labels: label_2
service_3
container_name: service_3
labels: label_3
Within service_1, is there a way to get a list of the other services (service_2, service_3, etc.)?
You can use Docker's Engine REST API from within the container if you mount the Docker UNIX socket into the container.
To do so, you need to append -v /var/run/docker.sock /var/run/docker.sock to the command that you use to start your container. After that, you can call the API using that socket:
npm i -s request request-promise-native / yarn add request request-promise-native.
const request = require("request-promise-native")
const sock = "unix:/var/run/docker.sock"
const endpoint = `http://${sock}/v1.24`
function getRunningContainers () {
const endpoint = `${endpoint}/containers/json`
return request.get(endpoint)
}
(async () => {
try {
let containers = await getRunningContainers()
} catch (e) {
console.error(e)
}
console.log(containers)
})()
Documentation for the Engine API can be found here: https://docs.docker.com/engine/api/v1.24/
you need run docker daemon (windows) first, and type docker psto check your sevices is running.

Use a docker sdk to send commands to the docker machine from a web app

I'm new to Docker and I have some difficulties to understand how I should use it.
For now, I'm wondering if that makes sense to attempt sending commands to a docker machine on my computer from the client side script of a javascript web app using an SDK like Dockerode.
I installed Docker CE for windows (17.06.0-ce) and Docker Toolbox, and I ran a container on the default machine using the docker terminal. Now I'm wondering if the commands I typed could be sent from a web app using NodeJS. I tried using this code:
import Docker from 'dockerode';
const docker = new Docker({host: 'myDefaultMachineHost'});
export function createLocalDb () {
docker.pull('someImageFromDockerHub', function (err, stream) {
if (err) console.log("Catch : " + err.toString());
stream.pipe(process.stdout, {end: true});
stream.on('end', function() {
//run the container
}).catch(function (err) {
console.log("Catch : " + err.toString());
});
});
}
But that doesn't work(stream.pipe throws an error). Am I misunderstanding the context in which I'm supposed to use dockerode ?
Thanks for your explanations !
In short: You need change your code to this const docker = new Docker({socketPath: '/var/run/docker.sock'}); and add docker socket inside your container.
Theory:
You have docker socket inside your local machine. You should add this socket inside your docker container. The volume is your solution.
Image for visualization this issue:
Implementation with arguments
This is simple task for Linux/Mac user. They can do
docker run -v /var/run/docker.sock:/var/run/docker.sock ...
On Windows you need run
docker run -v //var/run/docker.sock:/var/run/docker.sock ...
More details in this question.
Implementation with Dockerfile
Also, you can add to your Dockerfile VOLUME instruction.
On Linux/Mac it should be line like this:
VOLUME /var/run/docker.sock /var/run/docker.sock
I don't know who it will be on Windows, I use Mac.

Resources