jdleesmiller / docker-chat-demo Goto Github PK
View Code? Open in Web Editor NEWCompanion repo for my "Lessons from Building a Node App in Docker" article.
Home Page: https://jdlm.info/articles/2019/09/06/lessons-building-node-app-docker.html
Companion repo for my "Lessons from Building a Node App in Docker" article.
Home Page: https://jdlm.info/articles/2019/09/06/lessons-building-node-app-docker.html
my requirement is , i want to use my older npm's inside my container by sharing the volumes where my global node_modules are present... i have tried most of the approaches but still i cant able to re-use my global npms inside the containers..
db:
image: mongo
ports:
- "27017:27017"
restart: always
web:
build: .
volumes:
- ./:/app
- ./node_modules:/usr/local/lib/node_modules
ports:
- "6000:6000"
links:
- db
command: node /app/index.js
This is my docker-compose file.
You could pass env variable from the command line :)
Your compose file:
...
environment:
NODE_ENV:
...
And then, NODE_ENV=production docker-compose up
\o/
https://docs.docker.com/compose/compose-file/#environment
I'm available for hire also ;)
Hi John,
I follow your instructions - Lessons from Building a Node App in Docker - and see the issue as below:
ndaidong@bella-mint /var/www/temp/chat $ docker-compose up
Building chat
Step 1 : FROM node:5.9.1
5.9.1: Pulling from library/node
fdd5d7827f33: Pull complete
a3ed95caeb02: Pull complete
0f35d0fe50cc: Pull complete
7b40647e93b7: Pull complete
ce5207842c4c: Pull complete
5a3b05f77d24: Pull complete
e0f4745fa41d: Pull complete
Digest: sha256:4ef4b2b4ec5ea21b6de05608045d32c0d8aa828cb1773784b511f27a1d2a54ce
Status: Downloaded newer image for node:5.9.1
---> 1d40a411bb29
Step 2 : RUN useradd --user-group --create-home --shell /bin/false app && npm install --global npm@latest
---> Running in f348c10627c7
npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm info attempt registry request try #1 at 7:15:22 AM
npm http request GET https://registry.npmjs.org/npm
npm http 200 https://registry.npmjs.org/npm
npm info addNameTag [ 'npm', 'latest' ]
npm info retry fetch attempt 1 at 7:15:29 AM
npm info attempt registry request try #1 at 7:15:29 AM
npm http fetch GET https://registry.npmjs.org/npm/-/npm-3.8.3.tgz
npm http fetch 200 https://registry.npmjs.org/npm/-/npm-3.8.3.tgz
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preinstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
npm info lifecycle [email protected]~preuninstall: [email protected]
npm info lifecycle [email protected]~uninstall: [email protected]
npm info lifecycle [email protected]~postuninstall: [email protected]
- [email protected] node_modules/npm/node_modules/lodash.clonedeep/node_modules/lodash._arrayeach
- [email protected] node_modules/npm/node_modules/lodash.clonedeep/node_modules/lodash._basefor
- [email protected] node_modules/npm/node_modules/lodash.clonedeep/node_modules/lodash._root
- [email protected] node_modules/npm/node_modules/lodash.clonedeep/node_modules/lodash._stack/node_modules/lodash._mapcache
- [email protected] node_modules/npm/node_modules/lodash.clonedeep/node_modules/lodash._stack
- [email protected] node_modules/npm/node_modules/lodash.isarguments
- [email protected] node_modules/npm/node_modules/lodash.union/node_modules/lodash._arrayincludes
- [email protected] node_modules/npm/node_modules/lodash.union/node_modules/lodash._arrayincludeswith
- [email protected] node_modules/npm/node_modules/lodash.union/node_modules/lodash._cachehas
- [email protected] node_modules/npm/node_modules/lodash.union/node_modules/lodash._root
- [email protected] node_modules/npm/node_modules/lodash.union/node_modules/lodash._setcache/node_modules/lodash._mapcache
- [email protected] node_modules/npm/node_modules/lodash.union/node_modules/lodash._setcache
- [email protected] node_modules/npm/node_modules/lodash.uniq/node_modules/lodash._arrayincludes
- [email protected] node_modules/npm/node_modules/lodash.uniq/node_modules/lodash._arrayincludeswith
- [email protected] node_modules/npm/node_modules/lodash.uniq/node_modules/lodash._cachehas
- [email protected] node_modules/npm/node_modules/lodash.uniq/node_modules/lodash._root
- [email protected] node_modules/npm/node_modules/lodash.uniq/node_modules/lodash._setcache/node_modules/lodash._mapcache
- [email protected] node_modules/npm/node_modules/lodash.uniq/node_modules/lodash._setcache
- [email protected] node_modules/npm/node_modules/lodash.without/node_modules/lodash._arrayincludes
- [email protected] node_modules/npm/node_modules/lodash.without/node_modules/lodash._arrayincludeswith
- [email protected] node_modules/npm/node_modules/lodash.without/node_modules/lodash._arraymap
- [email protected] node_modules/npm/node_modules/lodash.without/node_modules/lodash._cachehas
- [email protected] node_modules/npm/node_modules/lodash.without/node_modules/lodash._setcache/node_modules/lodash._mapcache
- [email protected] node_modules/npm/node_modules/lodash.without/node_modules/lodash._setcache
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/ansi
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/are-we-there-yet/node_modules/delegates
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/are-we-there-yet
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge/node_modules/lodash.pad/node_modules/lodash.repeat
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge/node_modules/lodash.pad
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padleft/node_modules/lodash._basetostring
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padleft/node_modules/lodash._createpadding/node_modules/lodash.repeat
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padleft/node_modules/lodash._createpadding
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padleft
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padright/node_modules/lodash._basetostring
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padright/node_modules/lodash._createpadding/node_modules/lodash.repeat
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padright/node_modules/lodash._createpadding
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padright
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog/node_modules/gauge
- [email protected] node_modules/npm/node_modules/node-gyp/node_modules/npmlog
- [email protected] node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padleft/node_modules/lodash._basetostring
- [email protected] node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padleft/node_modules/lodash._createpadding/node_modules/lodash.repeat
- [email protected] node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padleft/node_modules/lodash._createpadding
- [email protected] node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padleft
- [email protected] node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padright/node_modules/lodash._basetostring
- [email protected] node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padright/node_modules/lodash._createpadding/node_modules/lodash.repeat
- [email protected] node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padright/node_modules/lodash._createpadding
- [email protected] node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/lodash.padright
/usr/local/lib
`-- (empty)
npm ERR! Linux 3.19.0-32-generic
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "--global" "npm@latest"
npm ERR! node v5.9.1
npm ERR! npm v3.7.3
npm ERR! path /usr/local/lib/node_modules/npm/node_modules/glob
npm ERR! code EXDEV
npm ERR! errno -18
npm ERR! syscall rename
npm ERR! EXDEV: cross-device link not permitted, rename '/usr/local/lib/node_modules/npm/node_modules/glob' -> '/usr/local/lib/node_modules/npm/node_modules/.glob.DELETE'
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR! <https://github.com/npm/npm/issues>
npm ERR! Please include the following file with any support request:
npm ERR! /npm-debug.log
npm ERR! code 1
ERROR: Service 'chat' failed to build: The command '/bin/sh -c useradd --user-group --create-home --shell /bin/false app && npm install --global npm@latest' returned a non-zero code: 1
ndaidong@bella-mint /var/www/temp/chat $
My platform:
How I can fix this issue?
Thanks,
Dong
I am getting the error in the title when I run docker-compose up
I have installed socket.io after running docker-compose run chat bash
and rebuilt it even with --no-cache option. And I can require('socket.io')
inside the machine's node console.
Hi, nice repo and tutorial.
I was wondering, if I install some dev dependencies like eslint
, prettier
, lerna
, husky
, commitlint
, etc..., some tooling and editors/ide's expect to find this package's binaries over node_modules/.bin/
, but this is empty on the host, what can we do in this case?
Thanks.
Was not sure if this is the best place. But how is this cutting time with npm install
? You will still need to do that in the container or even your host, right?
For this example to work on my Linux box I had to name the volume for the node modules, i.e.
chat:
build: .
ports:
- '3000:3000'
volumes:
- .:/home/app/chat
- node_modules:/home/app/chat/node_modules
Otherwise I would get the following error:
Starting dockernode_chat_1
Attaching to dockernode_chat_1
chat_1 | module.js:327
chat_1 | throw err;
chat_1 | ^
chat_1 |
chat_1 | Error: Cannot find module 'express'
chat_1 | at Function.Module._resolveFilename (module.js:325:15)
chat_1 | at Function.Module._load (module.js:276:25)
chat_1 | at Module.require (module.js:353:17)
chat_1 | at require (internal/module.js:12:17)
chat_1 | at Object. (/home/app/chat/index.js:1:73)
chat_1 | at Module._compile (module.js:409:26)
chat_1 | at Object.Module._extensions..js (module.js:416:10)
chat_1 | at Module.load (module.js:343:32)
chat_1 | at Function.Module._load (module.js:300:12)
chat_1 | at Function.Module.runMain (module.js:441:10)
dockernode_chat_1 exited with code 1
Hi, I've been desperately trying to get this to work for the past two days. For me the configuration doesn't work since I'm always getting a "module not found" error.
When I do RUN ls /home/koko/app/
I can see that the only files there are package.json and node_modules. When I finally run ENTRYPOINT ls /home/app/koko/node_modules/
the node_modules folder is missing and the only files there are those that are inside the mounted volume.
I've tried removing the node_modules volume from docker-compose.yml because I don't need to run this in development but that didn't help.
My dockerfile looks like this:
FROM node:7.10.0
RUN useradd --user-group --create-home --shell /bin/false koko
ENV HOME=/home/koko
COPY koko-app/package.json $HOME/app/
RUN chown -R koko:koko $HOME/* \
&& chown -R koko:koko /usr/local/lib/node_modules \
&& chown -R koko:koko /usr/local/bin \
&& chown -R koko:koko /usr/local/share
USER koko
WORKDIR $HOME/app
RUN npm install && npm install -g nodemon && npm cache clean
USER root
COPY . $HOME/app
RUN chown -R koko:koko $HOME/*
USER koko
ENTRYPOINT nodemon /home/koko/app/node_modules/babel-cli/bin/babel-node.js /home/koko/app/server/index.js
I tried running the script directly with CMD node server/index.js
but that caused an error saying cannot find module express
indicating the same problem.
First thanks for sharing this great lessons !
When I try it on google compute engine (https://medium.com/google-cloud/my-slow-internet-vs-docker-7678ae1cae72#.ro97eqk7p) I'm getting an error at docker-compose up :
Starting demo_chat_1
Attaching to demo_chat_1
chat_1 | Usage: nodemon [nodemon options] [script.js] [args]
chat_1 |
chat_1 | See "nodemon --help" for more.
chat_1 |
demo_chat_1 exited with code 0
While docker run --rm -t -p 3000:3000 demo-chat node index.js
it runs fine,
docker run --rm -t -p 3000:3000 demo_chat nodemon
give me an error :
exec: "nodemon": executable file not found in $PATH docker: Error response from daemon: Container command not found or does not exist..
Any idea ?
Thanks for the tutorial, I found it really handy!
I'm having one issue regarding installing new NPM packages.
docker-compose run chat --rm /bin/bash
npm install redis --save
npm shrinkwrap
exit
docker-compose build
docker-compose up
Recreating dockerchatdemo_chat_1
Attaching to dockerchatdemo_chat_1
chat_1 | [nodemon] 1.11.0
chat_1 | [nodemon] to restart at any time, enter `rs`
chat_1 | [nodemon] watching: *.*
chat_1 | [nodemon] starting `node index.js`
chat_1 | module.js:327
chat_1 | throw err;
chat_1 | ^
chat_1 |
chat_1 | Error: Cannot find module 'redis'
chat_1 | at Function.Module._resolveFilename (module.js:325:15)
chat_1 | at Function.Module._load (module.js:276:25)
chat_1 | at Module.require (module.js:353:17)
chat_1 | at require (internal/module.js:12:17)
chat_1 | at Object.<anonymous> (/home/app/chat/index.js:4:1)
chat_1 | at Module._compile (module.js:409:26)
chat_1 | at Object.Module._extensions..js (module.js:416:10)
chat_1 | at Module.load (module.js:343:32)
chat_1 | at Function.Module._load (module.js:300:12)
chat_1 | at Function.Module.runMain (module.js:441:10)
chat_1 | [nodemon] app crashed - waiting for file changes before starting...
If I docker rmi
the image and docker-compose up
it works and if I shell into the container and run the program manually then it works.
Maybe I'm missing something :)
In my case I do have a build step. So I have following requirements:
Under the build source I am talking about css/template/client-stuff. May be since your article you discovered some ways of dealing with this kind of things?
Hi, I was following through your really nice article and that went swell. Next, I tried repeating this with node:6.10.0
. I checked out 01-bootstrapping
and modified the Dockerfile
's FROM
statement to use node:6.10.0
. Ran docker-compose up
without a hitch. Next
~/docker-chat-demo$ docker-compose run --rm chat /bin/bash
app@13fbfb3d043f:~/chat$ npm init --yes
npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm info init written successfully
npm ERR! Linux 3.16.0-4-amd64
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "init" "--yes"
npm ERR! node v6.10.0
npm ERR! npm v3.7.5
npm ERR! path /home/app/chat/package.json
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall open
npm ERR! Error: EACCES: permission denied, open '/home/app/chat/package.json'
npm ERR! at Error (native)
npm ERR! { Error: EACCES: permission denied, open '/home/app/chat/package.json'
npm ERR! at Error (native)
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'open',
npm ERR! path: '/home/app/chat/package.json' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
npm ERR! Linux 3.16.0-4-amd64
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "init" "--yes"
npm ERR! node v6.10.0
npm ERR! npm v3.7.5
npm ERR! path npm-debug.log.3292290334
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall open
npm ERR! Error: EACCES: permission denied, open 'npm-debug.log.3292290334'
npm ERR! at Error (native)
npm ERR! { Error: EACCES: permission denied, open 'npm-debug.log.3292290334'
npm ERR! at Error (native)
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'open',
npm ERR! path: 'npm-debug.log.3292290334' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
npm ERR! Please include the following file with any support request:
npm ERR! /home/app/chat/npm-debug.log
Thing is, the newer node
images have a node
user account (UID 1000). Creating a new app
user (gets UID 1001) is fine, but when you run with that this no longer matches the UID outside the container. It looks to me that your article relied on the fact that your UID outside the container is the same as the UID of the user inside the container. You should probably mention that (and point to a fix if you know of one ๐).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.