Comments (22)
Sorry for the long wait! It's now implemented in the latest version :)
from lldap.
Re-opening since it was a very optimistic close :)
There's various problems that mostly stem from the fact that I haven't tested it with PG or MySQL at all.
from lldap.
Hi!
As it turns out, I'm several months ahead of you :) The problem is that SQL queries are not quite portable, so I would need to be able to detect the engine at runtime, and that required launchbadge/sqlx#1228. It was only recently merged, so as soon as there's a release with it, I can update (potentially non-trivial process) and get to work on multi-DB support.
from lldap.
Yes, each instance is stateless, so as long as they share the same configuration file/private keys and write to the same DB you can have multiple instances.
from lldap.
from lldap.
I have attempted to use the 0.4.2-alpha8
release from martadinata666/lldap with PSQL and I get an error about u8
being unsupported on postgres.
from lldap.
Iβm several months ahead of you
LOL, thatβs actually hilarious. I wasnβt aware that you were working on it. TYSM and best of luck w/ the implementation!
from lldap.
Just a quick update on the issue, there's still a blocker on the SQL query builder, but it should be resolved with SeaQL/sea-query#275
from lldap.
The blocker was fixed. π
from lldap.
Before I address this one, I want to do a bit more work on the database schema to hopefully avoid having to migrate schemas for three different DB engines. I'll try to work on #67 before.
from lldap.
If support for an extermal SQL database will be implemented, does that also mean that then high-availability LLDAP cluster can be created? (shared persistent storage for configuration files and LDAP data in extexternal SQL database)
from lldap.
Is there some sort of estimate that how hard is migrate an existing SQLite instance to the PostgreSQL/MariaDB one?
I would like to start using LLDAP in my lab-environment, but I'm hesitating do that, because I would like to run my instance on an external database at some point.
from lldap.
okay, thanks π
from lldap.
Thank you so much!
So will this published to the next container image release?
It it should work then with setting DATABASE_URL=postgres://postgres-user:password@postgres-server/my-database
as mentioned in the code, right?
from lldap.
Yes, it should work. Feel free to try, and tell me if it doesn't!
from lldap.
Hey! First of all - thank you for this! This will finally introduce HA to LLDAP in my cluster π
Tried this today, however I have problems connecting to postgresql :(
> Setup permissions..
> Starting lldap..
Loading configuration from /data/lldap_config.toml
thread 'main' panicked at 'u8 unsupported by sqlx-postgres', /__w/lldap/lldap/${GITHUB_WORKSPACE}/.cargo/registry/src/github.com-1ecc6299db9ec823/sea-orm-0.10.3/src/executor/query.rs:269:1
stack backtrace:
0: 0x7f480b700370 - std::backtrace_rs::backtrace::libunwind::trace::h82777a91e9377372
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
1: 0x7f480b700370 - std::backtrace_rs::backtrace::trace_unsynchronized::he52a3ebc8e92b459
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x7f480b700370 - std::sys_common::backtrace::_print_fmt::h86f0e984e0981e08
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/sys_common/backtrace.rs:66:5
3: 0x7f480b700370 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h0d99c3e6322baab9
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/sys_common/backtrace.rs:45:22
4: 0x7f480b73f6fe - core::fmt::write::h7afdcecae634c757
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/fmt/mod.rs:1202:17
5: 0x7f480b6f9a85 - std::io::Write::write_fmt::h03980dafd16fbb98
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/io/mod.rs:1679:15
6: 0x7f480b701ba3 - std::sys_common::backtrace::_print::h634f6e5377cdeeeb
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/sys_common/backtrace.rs:48:5
7: 0x7f480b701ba3 - std::sys_common::backtrace::print::hb5215870b00242d0
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/sys_common/backtrace.rs:35:9
8: 0x7f480b701ba3 - std::panicking::default_hook::{{closure}}::hfccde408bd4bce54
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:295:22
9: 0x7f480b70188f - std::panicking::default_hook::hf5508b7bdf3babed
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:314:9
10: 0x7f480b70224a - std::panicking::rust_panic_with_hook::h8ac2ad414f2a80a8
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:698:17
11: 0x7f480b702147 - std::panicking::begin_panic_handler::{{closure}}::h6806472e4abb4c1b
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:588:13
12: 0x7f480b70081c - std::sys_common::backtrace::__rust_end_short_backtrace::h0c0f5202fe96986e
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/sys_common/backtrace.rs:138:18
13: 0x7f480b701e62 - rust_begin_unwind
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:584:5
14: 0x7f480aa14dc3 - core::panicking::panic_fmt::h6bdb18f09e76240c
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/panicking.rs:142:14
15: 0x7f480b255cac - <u8 as sea_orm::executor::query::TryGetable>::try_get::had995741bb7ce785
16: 0x7f480ab5c061 - <sea_orm::executor::select::SelectModel<M> as sea_orm::executor::select::SelectorTrait>::from_raw_query_result::hd69f540574b8b9ff
17: 0x7f480ad4cda6 - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::he30a1a71ba23bfa7
18: 0x7f480aceff81 - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h51d10af010e4b6df
19: 0x7f480ad6ab44 - lldap::set_up_server::{{closure}}::{{closure}}::h25f061b434784939
20: 0x7f480addfac3 - <tracing::instrument::Instrumented<T> as core::future::future::Future>::poll::h484df465144a01cb
21: 0x7f480ace0a85 - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h2b9cd69d1a8b238b
22: 0x7f480aa1b04b - <futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll::hae86f9be59ad738c
23: 0x7f480abbeba6 - std::thread::local::LocalKey<T>::with::h6e3d39f8217f525f
24: 0x7f480aae9f49 - tokio::macros::scoped_tls::ScopedKey<T>::set::h3879a4a392239db1
25: 0x7f480ad39dce - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::hcdff9343df5254f8
26: 0x7f480abbe719 - std::thread::local::LocalKey<T>::with::h318b7dcbe2aa3a14
27: 0x7f480ab96b10 - tokio::runtime::basic_scheduler::Context::enter::h69417f780272e083
28: 0x7f480aaea7d1 - tokio::macros::scoped_tls::ScopedKey<T>::set::hfdfc1697674f7d82
29: 0x7f480ab9614f - tokio::runtime::basic_scheduler::BasicScheduler::block_on::h309862889bf019b3
30: 0x7f480add9f10 - tokio::runtime::Runtime::block_on::h2b7f11634326408e
31: 0x7f480aa606f1 - lldap::main::h0cce86397b31a5af
32: 0x7f480adb5493 - std::sys_common::backtrace::__rust_begin_short_backtrace::h0186417cb121b83d
33: 0x7f480ab0c929 - std::rt::lang_start::{{closure}}::h5a53986c9da5c601
34: 0x7f480b6f46d2 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h08229953798ceb9c
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/ops/function.rs:283:13
35: 0x7f480b6f46d2 - std::panicking::try::do_call::h85f860db39727e24
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:492:40
36: 0x7f480b6f46d2 - std::panicking::try::h81d98391c5fe7aa5
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:456:19
37: 0x7f480b6f46d2 - std::panic::catch_unwind::hf0da87b0c0419439
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panic.rs:137:14
38: 0x7f480b6f46d2 - std::rt::lang_start_internal::{{closure}}::h8fdd0caa04652723
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/rt.rs:148:48
39: 0x7f480b6f46d2 - std::panicking::try::do_call::h610b603febbce952
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:492:40
40: 0x7f480b6f46d2 - std::panicking::try::h1e387bee0c3d3c28
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:456:19
41: 0x7f480b6f46d2 - std::panic::catch_unwind::h9f8125a9743b85d4
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panic.rs:137:14
42: 0x7f480b6f46d2 - std::rt::lang_start_internal::h829c8136aeac5647
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/rt.rs:148:20
43: 0x7f480aa66338 - main
2022-11-25T17:36:56.822178073+00:00 INFO set_up_server [ 27.0ms | 100.00% ]
2022-11-25T17:36:56.822239802+00:00 INFO ββ ο½ [info]: Starting LLDAP version 0.4.2-alpha
My database_url is as follows:
postgres://lldap:<password>@postgres-postgresql-ha-pgpool.databases.svc.cluster.local:5432/lldap?sslmode=require
Any hints will be very welcome :)
from lldap.
Tried both, seems not easy as it said. β
On mysql
- lldap logs
Attaching to lldap-app-1
lldap-app-1 | > Setup permissions..
lldap-app-1 | > Starting lldap..
lldap-app-1 |
lldap-app-1 | Loading configuration from /data/lldap_config.toml
lldap-app-1 | Configuration: Configuration {
lldap-app-1 | ldap_host: "0.0.0.0",
lldap-app-1 | ldap_port: 3890,
lldap-app-1 | http_host: "0.0.0.0",
lldap-app-1 | http_port: 17170,
lldap-app-1 | jwt_secret: ***SECRET***,
lldap-app-1 | ldap_base_dn: "dc=example,dc=com",
lldap-app-1 | ldap_user_dn: UserId(
lldap-app-1 | "admin",
lldap-app-1 | ),
lldap-app-1 | ldap_user_email: "",
lldap-app-1 | ldap_user_pass: ***SECRET***,
lldap-app-1 | database_url: "mysql://lldapuser:lldappass@db/lldap",
lldap-app-1 | ignored_user_attributes: [],
lldap-app-1 | ignored_group_attributes: [],
lldap-app-1 | verbose: true,
lldap-app-1 | key_file: "/data/private_key",
lldap-app-1 | smtp_options: MailOptions {
lldap-app-1 | enable_password_reset: false,
lldap-app-1 | from: None,
lldap-app-1 | reply_to: None,
lldap-app-1 | server: "localhost",
lldap-app-1 | port: 587,
lldap-app-1 | user: "admin",
lldap-app-1 | password: ***SECRET***,
lldap-app-1 | smtp_encryption: TLS,
lldap-app-1 | tls_required: None,
lldap-app-1 | },
lldap-app-1 | ldaps_options: LdapsOptions {
lldap-app-1 | enabled: false,
lldap-app-1 | port: 6360,
lldap-app-1 | cert_file: "cert.pem",
lldap-app-1 | key_file: "key.pem",
lldap-app-1 | },
lldap-app-1 | http_url: "http://localhost",
lldap-app-1 | server_setup: None,
lldap-app-1 | }
lldap-app-1 | WARNING: Default JWT secret used! This is highly unsafe and can allow attackers to log in as admin.
lldap-app-1 | WARNING: Unsecure default admin password is used.
lldap-app-1 | thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', server/src/domain/sql_migrations.rs:327:47
lldap-app-1 | note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
lldap-app-1 | 2022-11-26T03:19:55.786395677+00:00 INFO set_up_server [ 17.5ms | 90.36% / 100.00% ]
lldap-app-1 | 2022-11-26T03:19:55.786550251+00:00 INFO ββ ο½ [info]: Starting LLDAP version 0.4.2-alpha
lldap-app-1 | 2022-11-26T03:19:55.796066544+00:00 DEBUG ββ get_schema_version [ 1.10ms | 6.29% ]
lldap-app-1 | 2022-11-26T03:19:55.801063394+00:00 DEBUG β ββ π [debug]: | return: None
lldap-app-1 | 2022-11-26T03:19:55.858837579+00:00 DEBUG ββ get_schema_version [ 588Β΅s | 3.35% ]
lldap-app-1 | 2022-11-26T03:19:55.860094852+00:00 DEBUG ββ π [debug]: | return: None
lldap-app-1 exited with code 101
- mariadb logs
lldap-db-1 | 2022-11-26 10:19:42 0 [Note] InnoDB: Buffer pool(s) load completed at 221126 10:19:42
lldap-db-1 | 2022-11-26 10:19:42 0 [Note] mariadbd: ready for connections.
lldap-db-1 | Version: '10.7.7-MariaDB-1:10.7.7+maria~debunstable' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
lldap-db-1 | 2022-11-26 10:19:55 3 [Warning] Aborted connection 3 to db: 'lldap' user: 'lldapuser' host: '172.19.0.3' (Got an error reading communication packets)
lldap-db-1 | 2022-11-26 10:19:55 4 [Warning] Aborted connection 4 to db: 'lldap' user: 'lldapuser' host: '172.19.0.3' (Got an error reading communication packets)
lldap-db-1 | 2022-11-26 10:19:57 5 [Warning] Aborted connection 5 to db: 'lldap' user: 'lldapuser' host: '172.19.0.3' (Got an error reading communication packets)
lldap-db-1 | 2022-11-26 10:19:57 6 [Warning] Aborted connection 6 to db: 'lldap' user: 'lldapuser' host: '172.19.0.3' (Got an error reading communication packets)
lldap-db-1 | 2022-11-26 10:19:58 7 [Warning] Aborted connection 7 to db: 'lldap' user: 'lldapuser' host: '172.19.0.3' (Got an error reading communication packets)
lldap-db-1 | 2022-11-26 10:19:58 8 [Warning] Aborted connection 8 to db: 'lldap' user: 'lldapuser' host: '172.19.0.3' (Got an error reading communication packets)
lldap-db-1 | 2022-11-26 10:20:00 9 [Warning] Aborted connection 9 to db: 'lldap' user: 'lldapuser' host: '172.19.0.3' (Got an error reading communication packets)
lldap-db-1 | 2022-11-26 10:20:00 10 [Warning] Aborted connection 10 to db: 'lldap' user: 'lldapuser' host: '172.19.0.3' (Got an error reading communication packets)
lldap-db-1 | 2022-11-26 10:20:02 12 [Warning] Aborted connection 12 to db: 'lldap' user: 'lldapuser' host: '172.19.0.3' (Got an error reading communication packets)
lldap-db-1 | 2022-11-26 10:20:02 11 [Warning] Aborted connection 11 to db: 'lldap' user: 'lldapuser' host: '172.19.0.3' (Got an error reading communication packets)
On postgress
- lldap log
[+] Running 1/1
β Ώ Container lldap-app-1 Recreated 0.2s
Attaching to lldap-app-1
lldap-app-1 | > Setup permissions..
lldap-app-1 | > Starting lldap..
lldap-app-1 |
lldap-app-1 | Loading configuration from /data/lldap_config.toml
lldap-app-1 | Configuration: Configuration {
lldap-app-1 | ldap_host: "0.0.0.0",
lldap-app-1 | ldap_port: 3890,
lldap-app-1 | http_host: "0.0.0.0",
lldap-app-1 | http_port: 17170,
lldap-app-1 | jwt_secret: ***SECRET***,
lldap-app-1 | ldap_base_dn: "dc=example,dc=com",
lldap-app-1 | ldap_user_dn: UserId(
lldap-app-1 | "admin",
lldap-app-1 | ),
lldap-app-1 | ldap_user_email: "",
lldap-app-1 | ldap_user_pass: ***SECRET***,
lldap-app-1 | database_url: "postgres://lldapuser:lldappass@db1/lldap",
lldap-app-1 | ignored_user_attributes: [],
lldap-app-1 | ignored_group_attributes: [],
lldap-app-1 | verbose: true,
lldap-app-1 | key_file: "/data/private_key",
lldap-app-1 | smtp_options: MailOptions {
lldap-app-1 | enable_password_reset: false,
lldap-app-1 | from: None,
lldap-app-1 | reply_to: None,
lldap-app-1 | server: "localhost",
lldap-app-1 | port: 587,
lldap-app-1 | user: "admin",
lldap-app-1 | password: ***SECRET***,
lldap-app-1 | smtp_encryption: TLS,
lldap-app-1 | tls_required: None,
lldap-app-1 | },
lldap-app-1 | ldaps_options: LdapsOptions {
lldap-app-1 | enabled: false,
lldap-app-1 | port: 6360,
lldap-app-1 | cert_file: "cert.pem",
lldap-app-1 | key_file: "key.pem",
lldap-app-1 | },
lldap-app-1 | http_url: "http://localhost",
lldap-app-1 | server_setup: None,
lldap-app-1 | }
lldap-app-1 | WARNING: Default JWT secret used! This is highly unsafe and can allow attackers to log in as admin.
lldap-app-1 | WARNING: Unsecure default admin password is used.
lldap-app-1 | thread 'main' panicked at 'u8 unsupported by sqlx-postgres', /__w/lldap/lldap/${GITHUB_WORKSPACE}/.cargo/registry/src/github.com-1ecc6299db9ec823/sea-orm-0.10.3/src/executor/query.rs:269:1
lldap-app-1 | note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
lldap-app-1 | 2022-11-26T03:27:38.800787584+00:00 INFO set_up_server [ 22.5ms | 88.92% / 100.00% ]
lldap-app-1 | 2022-11-26T03:27:38.800877711+00:00 INFO ββ ο½ [info]: Starting LLDAP version 0.4.2-alpha
lldap-app-1 | 2022-11-26T03:27:38.830864643+00:00 DEBUG ββ get_schema_version [ 781Β΅s | 3.48% ]
lldap-app-1 | 2022-11-26T03:27:38.832745825+00:00 DEBUG β ββ π [debug]: | return: None
lldap-app-1 | 2022-11-26T03:27:38.946182266+00:00 DEBUG ββ get_schema_version [ 1.71ms | 7.60% ]
lldap-app-1 exited with code 101
- postgres log
lldap-db1-1 | 2022-11-26 03:25:33.434 UTC [1] LOG: starting PostgreSQL 13.9 (Debian 13.9-1.pgdg110+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
lldap-db1-1 | 2022-11-26 03:25:33.435 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
lldap-db1-1 | 2022-11-26 03:25:33.435 UTC [1] LOG: listening on IPv6 address "::", port 5432
lldap-db1-1 | 2022-11-26 03:25:33.441 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
lldap-db1-1 | 2022-11-26 03:25:33.467 UTC [54] LOG: database system was shut down at 2022-11-26 03:25:33 UTC
lldap-db1-1 | 2022-11-26 03:25:33.493 UTC [1] LOG: database system is ready to accept connections
lldap-db1-1 | 2022-11-26 03:27:38.832 UTC [63] ERROR: relation "metadata" does not exist at character 23
lldap-db1-1 | 2022-11-26 03:27:38.832 UTC [63] STATEMENT: SELECT "version" FROM "metadata"
lldap-db1-1 | 2022-11-26 03:27:38.847 UTC [64] ERROR: syntax error at or near "PRAGMA" at character 1
lldap-db1-1 | 2022-11-26 03:27:38.847 UTC [64] STATEMENT: PRAGMA foreign_keys = ON
lldap-db1-1 | 2022-11-26 03:27:38.903 UTC [63] ERROR: column "creation_date" of relation "groups" already exists
lldap-db1-1 | 2022-11-26 03:27:38.903 UTC [63] STATEMENT: ALTER TABLE "groups" ADD COLUMN "creation_date" timestamp without time zone NOT NULL DEFAULT '2022-11-26 03:27:38'
lldap-db1-1 | 2022-11-26 03:27:38.906 UTC [64] ERROR: column "uuid" of relation "groups" already exists
lldap-db1-1 | 2022-11-26 03:27:38.906 UTC [64] STATEMENT: ALTER TABLE "groups" ADD COLUMN "uuid" varchar(36) NOT NULL DEFAULT ''
lldap-db1-1 | 2022-11-26 03:27:38.909 UTC [63] ERROR: column "uuid" of relation "users" already exists
lldap-db1-1 | 2022-11-26 03:27:38.909 UTC [63] STATEMENT: ALTER TABLE "users" ADD COLUMN "uuid" varchar(36) NOT NULL DEFAULT ''
lldap-db1-1 | 2022-11-26 03:27:38.950 UTC [63] LOG: could not receive data from client: Connection reset by peer
from lldap.
e2e w/ mysql/pg containers should do the trick, though I guess you're probably already planning on that.
from lldap.
from lldap.
To anyone using LLDAP with an external database is the /data
directory not needed anymore? Would it be possible to scale LLDAP to N number of replicas all using the same external database?
from lldap.
You still need a place to put the configuration file, and server key, but these can be read-only.
You can run multiple instances connected to the same DB, the server is stateless.
from lldap.
Thanks for confirming @nitnelave . This release looks very nice. I have opened an issue to discuss some of those points you make here. #502
from lldap.
Related Issues (20)
- [FEATURE REQUEST] Force reset admin user/password
- [FEATURE REQUEST] Ability to disable LDAP users HOT 6
- [BUG] Password reset UI is enabled even when the feature is disabled
- [FEATURE REQUEST] Build `rootless` container image HOT 7
- [BUG] LLDAP stuck in restart loop with UNIQUE constraint failures on fresh sqlite install - lldap exited code 132 HOT 18
- Need Help. Invalid Login for Web Interface HOT 6
- [BUG] LDAP: Filtering custom attributes by value doesn't work HOT 2
- [FEATURE REQUEST] Documentation needs some clarification HOT 2
- [BUG] No documentation on SSL HOT 2
- [FEATURE REQUEST] Add entrydn as an attribute for groups to permit Duo directory synchronisation HOT 10
- [FEATURE REQUEST] Password Expiration Policy HOT 10
- [INTEGRATION] Grafana Integration HOT 4
- Is there a separate user password recovery service? HOT 1
- Question: Authelia Config: How to get user groups HOT 15
- Plea for a new release HOT 11
- [BUG] WebUI Case Sensitivity HOT 18
- [BUG] LLDAP_ADMIN_USERNAME should bootstrap admin username HOT 2
- [CLEANUP] Polish attribute creation form controls
- [CLEANUP] Use new form components across all components
- [FEATURE REQUEST] Add support for https HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lldap.