Giter Site home page Giter Site logo

haproxy's Introduction

Maintained by: the Docker Community

This is the Git repo of the Docker "Official Image" for haproxy (not to be confused with any official haproxy image provided by haproxy upstream). See the Docker Hub page for the full readme on how to use this Docker image and for information regarding contributing and issues.

The full image description on Docker Hub is generated/maintained over in the docker-library/docs repository, specifically in the haproxy directory.

See a change merged here that doesn't show up on Docker Hub yet?

For more information about the full official images change lifecycle, see the "An image's source changed in Git, now what?" FAQ entry.

For outstanding haproxy image PRs, check PRs with the "library/haproxy" label on the official-images repository. For the current "source of truth" for haproxy, see the library/haproxy file in the official-images repository.


  • build status badge
  • build status badge
Build Status Badges (per-arch)
amd64 build status badge arm32v5 build status badge arm32v6 build status badge arm32v7 build status badge
arm64v8 build status badge i386 build status badge mips64le build status badge ppc64le build status badge
s390x build status badge put-shared build status badge

haproxy's People

Contributors

bdossantos avatar cjhardekopf avatar darlelet avatar docker-library-bot avatar j0wi avatar jayh5 avatar josephcsible avatar l3n41c avatar msealand avatar ncopa avatar tao12345666333 avatar tianon avatar timwolla avatar wiljateiwaz avatar xsak avatar yajo avatar yosifkit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

haproxy's Issues

Haproxy stats not available

Good afternoon,

i am having trouble activating stats for HaProxy. I tried it with version 1.7.8 and 1.6.3.
I always run in the errormessage in my Browser:

Forbidden
You don't have permission to access /stats on this server.

I use the following configuration:

global

 stats timeout 30s

defaults
 log global
 timeout connect 5000ms
 timeout client 50000ms
 timeout server 50000ms

listen stats
 bind *:51510
 mode http

 stats enable
 stats hide-version
 stats refresh 30s
 stats show-node
 stats auth admin:admin
 stats uri /stats

frontend ft_myapp
 bind *:443
 mode tcp
 default_backend bk_myapp

backend bk_myapp
 balance source
 mode tcp
 server rgw1 192.168.210.101:443 check
 server rgw2 192.168.210.102:443 check
 server rgw3 192.168.210.103:443 check

If i install HaProxy in version 1.6.3 without docker the configuration works fine and I can access the stats GUI.

Is this a bug or am I missing something?

support LUA_PATH

Right now haproxy looks for lua files in the same directory the script is run from. It'd be nice to also support a LUA_PATH env var that we can place script into.

  1. Would adding this env var make sense?
  2. What dir would you want used if I put together a PR ?

Support transparent proxying

Hello.
I'm using haproxy in docker containers to balance load of mysql cluster, and I get all connections from haproxy's addresses (and 172.17.0.1 if both haproxy and mysql containers run at same machine).

Is there anyway I get real ip's there? I read
http://blog.haproxy.com/2013/09/16/howto-transparent-proxying-and-binding-with-haproxy-and-aloha-load-balancer/
but it requires rebuilding kernel. I was hoping this container would have appropriate kernel configuration, but it doesn't.

Tcp-request reject not working on docker version>1.5.16

Hello,
After many tests, seems like I can't reject any tcp-connection via haproxy.cfg with official docker image tag > 1.5.16:

tcp-request connection reject if { src_conn_rate(Abuse) ge 2 }     # 10 conn in 3 sec
tcp-request connection reject if { src_conn_cur(Abuse) ge 2 }      # 10 concurent conn

Working 1.5.16:

On Server mylb:

docker run --name mylb -v /root/env/myhaproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro -p "80:80" -p "8881:8881" -it -d haproxy:1.5.16 haproxy -db -f /usr/local/etc/haproxy/haproxy.cfg 

On a client:

ab -n 3 -c 3 http://ip_mylb:80/
Benchmarking 185.x.x.x (be patient)...apr_socket_recv: Connection reset by peer (104) --> block fine!

ab -n 2 -c 1 http://ip_mylb:80/
--> connection success

Not working: 1.6

Server mylb:

docker run --name mylb -v /root/env/myhaproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro -p "80:80" -p "8881:8881" -it -d haproxy:1.6 haproxy -db -f /usr/local/etc/haproxy/haproxy.cfg 

On a client:

ab -n 300 -c 300 http://ip_mylb:80/
--> connection success --> not blocking anything. 

I can monitor the Abuse tick-table and see these open connections via

docker exec -it mylb apt-get update
docker exec -it mylb apt-get install socat
docker exec -it mylb bash -c 'echo "show table Abuse" | socat unix:/var/run/haproxy.stats -'

Seems that only the blocking conf do not block connection.

Same config in both tests:

myhaproxy.cfg:

global
    maxconn 4096 # count about 1 GB per 20 000 connections
    user nobody
    group nogroup
    chroot  /tmp
    ulimit-n 65536

    # haproxy stats socket is available at /var/run/haproxy.stats --> echo "show table Abuse" | socat unix:/var/run/haproxy.stats -
    stats socket /var/run/haproxy.stats mode 600 level admin
    stats timeout 2m

    # Security config, cf: https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations
    tune.ssl.default-dh-param 2048
    ssl-default-bind-options no-sslv3 no-tls-tickets
    ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES128-SHA:AES256-SHA256:AES256-SHA:SRP-RSA-3DES-EDE-CBC-SHA:DES-CBC3-SHA

    # lower your record size to improve Time to First Byte (TTFB) - see: https://plus.google.com/+IlyaGrigorik/posts/Q5kgmKve54p
    tune.ssl.maxrecord 1370

defaults
    maxconn 4000 # Must be slight smaller that global, so you can still connect
    log     global
    mode    http
    option  httplog
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option  dontlognull
    option  splice-auto
    option  http-keep-alive
    option  redispatch
    retries 3
    # disconnect slow handshake clients early, protect from resources exhaustion attacks
    timeout http-request    5s #Slowloris protection
    timeout connect         5s
    timeout queue           1m
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    # errorfile 500 /etc/haproxy/errors/500.http

listen stats
    mode http
    log global
    bind *:8881
    maxconn 10
    stats enable
    stats hide-version
    stats refresh 30s
    stats show-node
    #stats auth user:pass
    stats uri /

backend Abuse
    stick-table type ip size 1m expire 30m store conn_rate(3s),conn_cur,gpc0,http_req_rate(10s),http_err_rate(20s)

frontend http-in
    mode http
    option httplog
    bind *:80
    timeout client 10
    rspadd Strict-Transport-Security:\ max-age=15768000

    ###############################################
    ## TCP protect against DOS, SCANNING, etc
    #tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }     # whitelist
    #tcp-request content reject if { src -f /etc/haproxy/blacklist.lst }        # blacklist
    tcp-request connection reject if { src_conn_rate(Abuse) ge 2 }     # 10 conn in 3 sec
    tcp-request connection reject if { src_conn_cur(Abuse) ge 2 }      # 10 concurent conn
    tcp-request connection track-sc1 src table Abuse    # record them in table Abuse
    ################################################

    default_backend www_backend

backend www_backend
    option forwardfor # add the X-Forwarded-For header
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    server myserver 185.x.x.x:80 maxconn 32

I probably missed something obvious.

Thank you for your feedback!
God day!
Greg.

Outdated URL in the 1.6 Dockerfile comment

Line 9 should be
# see http://sources.debian.net/src/haproxy/1.6.4-3/debian/rules/ for some helpful navigation of the possible "make" arguments instead of # see http://sources.debian.net/src/haproxy/1.5.8-1/debian/rules/ for some helpful navigation of the possible "make" arguments.

Certbot integration?

Hello,

Just wondering if certbot(let's encrypt) support in this image was possible/a good idea for a future release.
For the moment I stop haproxy container, create/update the cert with cerbot mapped on 80/443, then restart haproxy with the new cert.
Cert last only 3 months so need to automate the stop/start of haproxy in script, which makes me worried if something goes wrong during the night.

Any feedback on this?

Thank you!
Greg.

100% CPU when resolving with docker nameserver

I'm trying to use docker's resolver in the backend section.
It works as intended (combined with the "check", haproxy catches IP changes very quickly).
But, as soon as haproxy is started, no matter if nginx is up or down, even without any incoming connection, docker stats reveals a 100% CPU of the container, which doesn't occur when I don't use ...resolvers docker_resolver in the backend section.
Tried both alpine / standard and 1.7 & 1.8 using docker 18.03.1.

Any thought ?

defaults
    mode http
    # never fail on address resolution
    default-server init-addr last,libc,none

frontend http-in
    bind *:80
    default_backend servers

# Use docker's dns
resolvers docker_resolver
   nameserver dns 127.0.0.11:53

backend servers
    server nginx nginx:80 check resolvers docker_resolver

haproxy baed on Jessie with package

Hello,

It would be far, far better to create an image based on debian:jessie, and to use the following repository instead of building haproxy:
http://haproxy.debian.net/

This would allow all haproxy versions to run on a up-to-date Jessie without any problem.

I might provide a PR if you're interested.

Cheers,

C.

env-file items not working

I've tried to create a docker instance and running with an --env-file to build the config for other users to easily adapt items such as;

  • SSL Cert
  • SSL Key
  • Listen Port (frontend)
  • Connection Timeouts

It seems a lot of the values don't get passed in, especially numbers. Setting the values to static values in the .cfg file gets me past the error, however there is still an issue with the SSL keys/certs.

I add my .crt and .pem to /usr/local/etc/haproxy and set the following to the frontend bind:
bind 0.0.0.0:443 name frontend_app
ssl crt /usr/local/etc/haproxy/"${CERT}" ca-file /usr/local/etc/haproxy/"${CERTPEM}"

However it doesn't produce any useful errors, is this the correct method for ssl certs and keys, and will the environment variables work?

My envrionment file is runtime.env and contains:
CERT=test.cer
CERTKEY=test.pem

The files are copied during the docker build and present in the filesystem.

Docker Version: 17.09-ce-mac35
Channel: stable

HaProxy Version: 1.7.9 based on alpine/image here.

haproxy reload command does not reload config

Running an unaltered haproxy 1.6.9 image. The config is set up to proxy requests on port 80 to various other ports on the host (I use haproxy as an http proxy for docker-served webhosts).

docker-compose.yml

haproxy:
    image: haproxy:1.6.9
    ports:
      - "80:80"
    volumes:
      - ./config/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg

According to the documentation, I should be able to reload changes to haproxy.cfg by running the command docker kill -s HUP <my-running-haproxy>.

Actions taken

  1. Edit haproxy.cfg; add forwarding for a new host, e.g. newhost
  2. docker kill -s HUP proxy_haproxy_1

Result

  1. docker-compose logs displays:

    haproxy_1           | <5>haproxy-systemd-wrapper: re-executing on SIGHUP.
    haproxy_1           | <7>haproxy-systemd-wrapper: executing /usr/local/sbin/haproxy -p /run/haproxy.pid -f /usr/local/etc/haproxy/haproxy.cfg -Ds -sf 7
    
  2. Visiting http://newhost in a browser results in a 503 Service Unavailable error

  3. Issue docker-compose restart

  4. Visiting http://newhost now works

Expected Result

  1. Visiting http://newhost works immediately following the execution of docker kill -s HUP proxy_haproxy_1

Alpine image using systemd wrapper

Is there a reason the alpine image uses haproxy-systemd-wrapper, or was that just a copy & paste oversight? It looks like Alpine uses OpenRC. The systemd wrapper works for the most part, but it seems to be breaking the logging functionality when I use syslogd to pipe the logs to stdout.

https://github.com/docker-library/haproxy/blob/master/1.7/alpine/docker-entrypoint.sh#L12

This Dockerfile does work:

FROM haproxy:1.7.8-alpine
RUN sed -i '2a/sbin/syslogd -O /dev/stdout' docker-entrypoint.sh
RUN sed -i 's/haproxy-systemd-wrapper/haproxy/g' docker-entrypoint.sh

Use lua from system package

Here
https://pkgs.alpinelinux.org/package/v3.7/main/x86_64/haproxy
is haproxy package from Alpine, it's outdated but for us is interesting to see on depends packages.

It depends on libressl (for security reasons, less bugs than in openssl) and lua5.3-libs.

I'm already wrote about libressl in another issue (#60) and here I suggest to use system lua libs package instead of manually installed... If I understand correctly reason was with outdated package version, but now it's is available from Alpine package system and it should be preferred way in my opinion if we have not any other reasons...

Add wget to building deps

Just hit this weird bug:

When using the latest Dockerfile, I am unable to build docker image due to failure to download haproxy.tar.gz package (ssl issue)

Sending build context to Docker daemon  4.096kB
Step 1/9 : FROM alpine:3.9
 ---> 055936d39205
Step 2/9 : ENV HAPROXY_VERSION 2.0.0
 ---> Using cache
 ---> df47d0fbe104
Step 3/9 : ENV HAPROXY_URL https://www.haproxy.org/download/2.0/src/haproxy-2.0.0.tar.gz
 ---> Using cache
 ---> 0b7b7daed0df
Step 4/9 : ENV HAPROXY_SHA256 fe0a0d69e1091066a91b8d39199c19af8748e0e872961c6fc43c91ec7a28ff20
 ---> Using cache
 ---> 5d2c8103c90b
Step 5/9 : RUN set -x           && apk add --no-cache --virtual .build-deps             ca-certificates                 gcc             libc-dev                linux-headers           lua5.3-dev                 make            openssl                 openssl-dev             pcre2-dev               readline-dev            tar             zlib-dev                && wget -O haproxy.tar.gz "$HAPROXY_URL"   && echo "$HAPROXY_SHA256 *haproxy.tar.gz" | sha256sum -c        && mkdir -p /usr/src/haproxy    && tar -xzf haproxy.tar.gz -C /usr/src/haproxy --strip-components=1        && rm haproxy.tar.gz            && makeOpts='           TARGET=linux-glibc              USE_LUA=1 LUA_INC=/usr/include/lua5.3 LUA_LIB=/usr/lib/lua5.3           USE_GETADDRINFO=1          USE_OPENSSL=1           USE_PCRE2=1 USE_PCRE2_JIT=1             USE_ZLIB=1              EXTRA_OBJS="contrib/prometheus-exporter/service-prometheus.o"   '       && make -C /usr/src/haproxy -j "$(getconf _NPROCESSORS_ONLN)" all $makeOpts        && make -C /usr/src/haproxy install-bin $makeOpts               && mkdir -p /usr/local/etc/haproxy      && cp -R /usr/src/haproxy/examples/errorfiles /usr/local/etc/haproxy/errors        && rm -rf /usr/src/haproxy              && runDeps="$(          scanelf --needed --nobanner --format '%n#p' --recursive /usr/local                         | tr ',' '\n'                   | sort -u                       | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }'   )"       && apk add --virtual .haproxy-rundeps $runDeps  && apk del .build-deps
 ---> Running in b66fe0568474
+ apk add --no-cache --virtual .build-deps ca-certificates gcc libc-dev linux-headers lua5.3-dev make openssl openssl-dev pcre2-dev readline-dev tar zlib-dev
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
(1/38) Installing ca-certificates (20190108-r0)
(2/38) Installing binutils (2.31.1-r2)
(3/38) Installing gmp (6.1.2-r1)
(4/38) Installing isl (0.18-r0)
(5/38) Installing libgomp (8.3.0-r0)
(6/38) Installing libatomic (8.3.0-r0)
(7/38) Installing libgcc (8.3.0-r0)
(8/38) Installing mpfr3 (3.1.5-r1)
(9/38) Installing mpc1 (1.0.3-r1)
(10/38) Installing libstdc++ (8.3.0-r0)
(11/38) Installing gcc (8.3.0-r0)
(12/38) Installing musl-dev (1.1.20-r4)
(13/38) Installing libc-dev (0.7.1-r0)
(14/38) Installing linux-headers (4.18.13-r1)
(15/38) Installing linenoise (1.0-r1)
(16/38) Installing lua5.3-libs (5.3.5-r2)
(17/38) Installing lua5.3 (5.3.5-r2)
(18/38) Installing pkgconf (1.6.0-r0)
(19/38) Installing lua5.3-dev (5.3.5-r2)
(20/38) Installing make (4.2.1-r2)
(21/38) Installing openssl (1.1.1b-r1)
(22/38) Installing openssl-dev (1.1.1b-r1)
(23/38) Installing ncurses-terminfo-base (6.1_p20190105-r0)
(24/38) Installing ncurses-terminfo (6.1_p20190105-r0)
(25/38) Installing ncurses-libs (6.1_p20190105-r0)
(26/38) Installing ncurses-dev (6.1_p20190105-r0)
(27/38) Installing libedit (20181209.3.1-r0)
(28/38) Installing libedit-dev (20181209.3.1-r0)
(29/38) Installing zlib-dev (1.2.11-r1)
(30/38) Installing libpcre2-16 (10.32-r1)
(31/38) Installing libpcre2-32 (10.32-r1)
(32/38) Installing pcre2 (10.32-r1)
(33/38) Installing pcre2-dev (10.32-r1)
(34/38) Installing libhistory (7.0.003-r1)
(35/38) Installing readline (7.0.003-r1)
(36/38) Installing readline-dev (7.0.003-r1)
(37/38) Installing tar (1.32-r0)
(38/38) Installing .build-deps (0)
Executing busybox-1.29.3-r10.trigger
Executing ca-certificates-20190108-r0.trigger
OK: 145 MiB in 52 packages
+ wget -O haproxy.tar.gz https://www.haproxy.org/download/2.0/src/haproxy-2.0.0.tar.gz
Connecting to www.haproxy.org (51.15.8.218:443)
wget: error getting response: Connection reset by peer
The command '/bin/sh -c set -x          && apk add --no-cache --virtual .build-deps             ca-certificates                 gcc             libc-dev                linux-headers     lua5.3-dev               make            openssl                 openssl-dev             pcre2-dev               readline-dev            tar             zlib-dev                && wget -O haproxy.tar.gz "$HAPROXY_URL"   && echo "$HAPROXY_SHA256 *haproxy.tar.gz" | sha256sum -c        && mkdir -p /usr/src/haproxy    && tar -xzf haproxy.tar.gz -C /usr/src/haproxy --strip-components=1        && rm haproxy.tar.gz            && makeOpts='           TARGET=linux-glibc              USE_LUA=1 LUA_INC=/usr/include/lua5.3 LUA_LIB=/usr/lib/lua5.3           USE_GETADDRINFO=1          USE_OPENSSL=1           USE_PCRE2=1 USE_PCRE2_JIT=1             USE_ZLIB=1              EXTRA_OBJS="contrib/prometheus-exporter/service-prometheus.o"   '       && make -C /usr/src/haproxy -j "$(getconf _NPROCESSORS_ONLN)" all $makeOpts        && make -C /usr/src/haproxy install-bin $makeOpts               && mkdir -p /usr/local/etc/haproxy      && cp -R /usr/src/haproxy/examples/errorfiles /usr/local/etc/haproxy/errors        && rm -rf /usr/src/haproxy              && runDeps="$(          scanelf --needed --nobanner --format '%n#p' --recursive /usr/local                         | tr ',' '\n'                   | sort -u                       | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }'   )"       && apk add --virtual .haproxy-rundeps $runDeps  && apk del .build-deps' returned a non-zero code: 1

A similar issue is discussed here and indeed adding wget to the list of installs

# see https://sources.debian.net/src/haproxy/jessie/debian/rules/ for some helpful navigation of the possible "make" arguments
RUN set -x \
        \
        && apk add --no-cache --virtual .build-deps \
                ca-certificates \
                gcc \
                libc-dev \
                linux-headers \
                lua5.3-dev \
                make \
                openssl \
                openssl-dev \
                pcre2-dev \
                readline-dev \
                tar \
                wget \
                zlib-dev \
        \
        && wget -O haproxy.tar.gz "$HAPROXY_URL" \

solves the problem and installation continues.

It should not be too big of an overhead since it would be removed later as a build dep anyway.

Container fails to startup unless adding the debug flag

I've encountered a strange issue, and i'm not sure of the root cause. A disclaimer that I'm relatively new to both docker and haproxy, so it is very likely user error.

By default I've got haproxy set to run without the debug flag, if I run debug start it immediately fails with no information in docker logs. If I add the debug option to the global section it starts up and runs perfectly. I've tested multiple times adding and removing the flag.

/usr/bin/docker run -d --name haproxy -p 80:80 -v /opt/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro haproxy:1.5.14
global
  maxconn 4096
  daemon
  node lb1
  spread-checks 5

defaults
  log     global
  mode    http
  option  httplog
  option  dontlognull
  retries 3
  option redispatch
  maxconn 2000
  timeout connect      5000
  timeout client      50000
  timeout server      50000

frontend web
  bind *:80
  mode http
  monitor-uri /haproxy?monitor

  use_backend service if { path_beg /service }
  default_backend service

backend service
  mode http
  option httpclose
  option forwardfor

  balance roundrobin

  cookie SRVID insert indirect nocache
  option nolinger

  server app1_1 microserviceurl:80 cookie app1_1 check inter 10s rise 2 fall 2

Any suggestions on why this might be happening?

TLS 1.3 and OpenSSL 1.1.1

11 September 2018 was released final version of OpenSSL 1.1.1 (LTS)
How about use it in docker image for supporting TLS 1.3 and 0RTT ?

alpine3.8 breaks TLS in tcp mode proxy?

Following config works on image based on haproxy@sha256:705f8128eef8c12285e6b2c8b590d1a78dbaf1a9c5bb84276baa204a97338147 (which was 1.8.12 with alpine3.7)

and breaks on image based on haproxy:1.8.12-alpine (currently based on alpine 3.8, image id haproxy@sha256:6a0fee4cf59409cc83fc0fc3e3064a193f23e9181170d38e987036df9d2366da)
:

global
  log /tmp/log local0

defaults
  timeout client 30s
  timeout server 30s
  timeout connect 5s


listen HAProxyLocalStats
        bind 127.0.0.1:2200 name localstats
        mode http
        stats enable
        stats admin if FALSE
        stats uri /stats

frontend ft
  bind 0.0.0.0:8000
  mode tcp
  option tcplog
  log global
  tcp-request inspect-delay 5s
  tcp-request content accept if { req.ssl_hello_type 1 }
  # deny clients not sending an SNI header in 5 seconds
  tcp-request content reject
  acl allowed_domains req.ssl_sni -n  -m end -f /config/allowed_domains.txt
  use_backend proxy if allowed_domains

backend zproxy
  mode tcp
  option ssl-hello-chk
  server proxy transparent-mode-proxy-specified-via-dns-name:443 check

It breaks in the way that connection from client is accepted , connection to upstream is established, but request hangs. Here is how it looks like from haproxy point of view :

netstat -n
tcp        0   2231 172.20.7.236:8000       172.20.4.240:49396      ESTABLISHED 
tcp        0      0 172.20.7.236:60664      proxy.ip.address:443       ESTABLISHED 

so client doesn't seem to be reading response from haproxy (2231 bytes still sit unacknowledged), which is strange and should point to the problem with the client, but changing haproxy to alpine 3.7 image solves it.

Here is how it looks from client curl when it works (172.21.24.11 is an IP address which is DNATed to haproxy's port 8000):

curl -v https://allowed-domain.com
* Rebuilt URL to: https://allowed-domain.com/
*   Trying 172.21.24.11...
* TCP_NODELAY set
* Connected to allowed-domain.com (172.21.24.11) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / AES256-GCM-SHA384
* ALPN, server did not agree to a protocol

here is how it looks when haproxy runs on a alpine3.8 based image:

curl -v https://allowed-domain.com
* Rebuilt URL to: https://allowed-domain.com/
*   Trying 172.21.24.11...
* TCP_NODELAY set
* Connected to allowed-domain.com (172.21.24.11) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
.... HANGS ....

We build haproxy images with following slightly edited Dockerfile

FROM internal.registry/infra/baseimages/alpine:3.7 as tini
FROM haproxy:1.8.12-alpine

COPY certs/* /usr/local/share/ca-certificates/
RUN apk add --no-cache socklog && apk add --no-cache -t .deps ca-certificates && update-ca-certificates && apk del .deps

COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg

COPY --from=tini /sbin/tini /sbin/tini

# user daemon inside image has UID 2
USER 2

COPY startup.sh /

ENTRYPOINT [ "/sbin/tini", "--", "/startup.sh", "-f", "/usr/local/etc/haproxy/haproxy.cfg" ]

and startup.sh is:

#!/bin/sh
set -ue
nohup socklog unix /tmp/log  &
exec haproxy "$@"

haproxy.cfg not found when deploying to heroku

I have setup a working example and a bad example (working example on branch heroku-good):

https://github.com/admosity/docker-heroku-haproxy-fail

I am unable to get this to run correctly using the default Dockerfile configuration:

FROM haproxy:1.6-alpine
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg

After deploying to heroku I get:

2016-09-08T21:32:28.522203+00:00 app[web.1]: /docker-entrypoint.sh: exec: line 15: haproxy -f /usr/local/etc/haproxy/haproxy.cfg: not found

In the working example I copied the dockerfile specified here and commented out the entry point and put the haproxy.cfg copy on the line where that was. I'm pretty new to docker, so not sure if I am doing something wrong.

Here it is working with the good example (I'm proxying example.com):
https://evening-thicket-58251.herokuapp.com/

image

Error when using docker-compose

I get the following error when running haproxy with docker-compose:

Recreating opt_haproxy_1...
Cannot start container {hash}: [8] System error: mounting into / is prohibited

This is my docker-compose.yml:

haproxy:
  image: haproxy:1.5
  ports:
    - "80:80"
  volumes:
    /opt/docker-haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro

Removing the complete volumes section makes no difference.

The same configuration with docker works.

Cannot write logs into haproxy.log (v1.5)

I'm trying to activate logging in haproxy (v1.5) just to write logs in '/var/log/haproxy.log'
but does not work.
Running a docker logs ..

sendto logger failed: Connection refused (errno=111)

Here is my haproxy.cfg

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log 127.0.0.1 local0
    log 127.0.0.1 local0 notice

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4096
    user        haproxy
    group       haproxy
    daemon

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

listen stats *:25
mode tcp
option tcplog
balance roundrobin

server smtp1 ${SMTP_SERVER}:${SMTP_PORT} check

Any clue?
I really appreciate any help you can provide!

Socket error during DNS discovery

I try to use docker version of haproxy in Kubernetes to use stick tables for scaling some stateful servers. The crucial thing that should work is service discovery, however there is some problem which is not so easy to debug.
After launch (v2.0.2), logs show the next:

[NOTICE] 198/151404 (1) : New worker #1 (7) forked
[WARNING] 198/151404 (7) : Server media-servers/srv1 is DOWN, reason: Socket error, check duration: 0ms. 4 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[WARNING] 198/151404 (7) : Server media-servers/srv2 is DOWN, reason: Socket error, check duration: 0ms. 3 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[WARNING] 198/151404 (7) : Server media-servers/srv3 is DOWN, reason: Socket error, check duration: 0ms. 2 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[WARNING] 198/151404 (7) : Server media-servers/srv4 is DOWN, reason: Socket error, check duration: 0ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[WARNING] 198/151405 (7) : Server media-servers/srv5 is DOWN, reason: Socket error, check duration: 0ms. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[ALERT] 198/151405 (7) : backend 'media-servers' has no server available!

So, no servers are available.
My config is next:

backend media-servers
      balance leastconn
      stick-table type string size 1m expire 24h
      option httpchk GET /
      http-check expect status 200
      stick on url_param(lb) table media-servers
      #server srv1 10.210.101.228:8089
      server-template srv 5 _http._tcp.media-server.default.svc.cluster.local check inter 1000

I tried to use dig:
dig -t SRV _http._tcp.media-server.default.svc.cluster.local
The result is OK:

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> -t SRV _http._tcp.media-server.default.svc.cluster.local
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42150
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;_http._tcp.media-server.default.svc.cluster.local. IN SRV

;; ANSWER SECTION:
_http._tcp.media-server.default.svc.cluster.local. 30 IN	SRV 10 100 8089 6664306463616264.media-server.default.svc.cluster.local.

;; ADDITIONAL SECTION:
6664306463616264.media-server.default.svc.cluster.local.	30 IN A	10.210.101.228

;; Query time: 0 msec
;; SERVER: 100.64.0.10#53(100.64.0.10)
;; WHEN: Thu Jul 18 16:03:32 UTC 2019
;; MSG SIZE  rcvd: 172

Regular static server definitions work normally. What am I doing wrong? In regular haproxy everything works fine and servers are discovered. (I exposed kube-dns server and did tests with regular haproxy)

cannot find user id for 'haproxy'

My config is as follows.

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    #1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    #2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    # Refer to [HTTP log format](http://cbonte.github.io/haproxy-dconv/configuration-1.4.html#8.2.3)
    # for more information on the format of the HAProxy log.
    log 127.0.0.1             local0
    chroot                    /var/lib/haproxy
    user                      haproxy
    group                     haproxy

Despite the fact that on line 22 and 23 I have defined haproxy as a user, I get the following error:

haproxy_1 | [ALERT] 130/094703 (1) : parsing [/usr/local/etc/haproxy/haproxy.cfg:22] : cannot find user id for 'haproxy' (0:Success)
haproxy_1 | [ALERT] 130/094703 (1) : parsing [/usr/local/etc/haproxy/haproxy.cfg:23] : cannot find group id for 'haproxy' (0:Success)
haproxy_1 | [ALERT] 130/094703 (1) : Error(s) found in configuration file : /usr/local/etc/haproxy/haproxy.cfg
haproxy_1 | [ALERT] 130/094703 (1) : Fatal errors found in configuration.

This is because the underlying container doesn't have haproxy user created.

If I try to remove those settings from the configuration file, I still run into another problem:

haproxy_1 | [ALERT] 130/094534 (1) : [haproxy.main()] Cannot chroot(/var/lib/haproxy).

Ok. Found out the directory doesn't exist.

So, I support the Dockerfile for haproxy should create the user most commonly used by users.

For now I had to create my own Dockerfile based on this image and create system group and user, then create the directory manually.

Reloading config on HAProxy 1.8

Is the documentation up-to-date regarding reloading the configuration on haproxy 1.8?
I am asking since the documentation still references haproxy-systemd-wrapper, which is not used anymore and because the entrypoint.sh now reads

allows for reload via "SIGUSR2"

Can't Access Environment Vars

I am unable to access environment variables when using the 1.5.x version of ha proxy. I have tried with env and $ and both do not work. having trouble looking into the issue since I can't access /proc/??/environ inside the docker container.

[1.8] SSL/TLS Mode Async

I have tried to make HAProxy work with async SSL/TLS as explained here, by adding :

global
  ssl-engine rdrand 
  ssl-mode-async

but I get

[ALERT] 331/144013 (1) : ssl-engine rdrand: failed to get structural reference

Am I missing something here?

Thanks in advance

Getting 404s on apt-get update

We're basing one of our images off of this image and seeing the following:

Dockerfile start:

FROM haproxy:1.5

RUN apt-get update && \
  apt-get install -y g++ --no-install-recommends \
  gcc \
  libc6-dev \
  make \
  curl \
  && rm -rf /var/lib/apt/lists/*

Logs:

Step 4 : RUN apt-get update &&   apt-get install -y g++ --no-install-recommends   gcc   libc6-dev   make   curl   && rm -rf /var/lib/apt/lists/*
 ---> Running in 02c66aeca374
Ign http://security.debian.org jessie/updates InRelease
Ign http://security.debian.org jessie/updates Release.gpg
Ign http://security.debian.org jessie/updates Release
Err http://security.debian.org jessie/updates/main amd64 Packages

Err http://security.debian.org jessie/updates/main amd64 Packages

Ign http://httpredir.debian.org jessie InRelease
Err http://security.debian.org jessie/updates/main amd64 Packages

Ign http://httpredir.debian.org jessie-updates InRelease
Err http://security.debian.org jessie/updates/main amd64 Packages

Ign http://httpredir.debian.org jessie Release.gpg
Err http://security.debian.org jessie/updates/main amd64 Packages
  404  Not Found [IP: 149.20.20.19 80]
Ign http://httpredir.debian.org jessie-updates Release.gpg
Ign http://httpredir.debian.org jessie Release
Ign http://httpredir.debian.org jessie-updates Release
Err http://httpredir.debian.org jessie/main amd64 Packages
  404  Not Found [IP: 176.9.184.93 80]
Err http://httpredir.debian.org jessie-updates/main amd64 Packages
  404  Not Found [IP: 176.9.184.93 80]
W: Failed to fetch http://security.debian.org/dists/jessie/updates/main/binary-amd64/Packages  404  Not Found [IP: 149.20.20.19 80]

W: Failed to fetch http://httpredir.debian.org/debian/dists/jessie/main/binary-amd64/Packages  404  Not Found [IP: 176.9.184.93 80]

W: Failed to fetch http://httpredir.debian.org/debian/dists/jessie-updates/main/binary-amd64/Packages  404  Not Found [IP: 176.9.184.93 80]

E: Some index files failed to download. They have been ignored, or old ones used instead.

I also get a 404 when trying to get those URLs.

Here's some more info:

$ docker run haproxy:1.5 cat /etc/apt/sources.list
deb http://httpredir.debian.org/debian jessie main
deb http://httpredir.debian.org/debian jessie-updates main
deb http://security.debian.org jessie/updates main
$ docker run haproxy:1.5 cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 192.168.64.1

I don't think this is a network issue. Seems like bad sources in the apt lists.

Any idea? This worked fine with earlier versions of this image.

edit: Originally I thought this was only since the jessie upgrade, but it seems to be the same issue with haproxy:1.5.14 which uses wheezy.

Adding curl or wget to container image for external-check

Haproxy supports defining external health check for the servers.
The curl or wget are very useful tools for implementing external servers health check.
I think it could be very useful to include curl or wget in the container image.

Thanks
Yossi

haproxy:1.7.11-alpine luarocks (OpenSSL) invalid application of 'sizeof' to incomplete type 'EVP_MD_CTX'

Hello, I think this is the right place to mention this issue. I just started using the latest version of haproxy:1.7.11 which recently bumped alpine linux from 3.8 to 3.9. I'm getting a few OpenSSL error messages from lua as the container is being built:

luajwtjitsi 1.3-7 depends on luacrypto >= 0.3.2-1 (not installed)
Installing https://luarocks.org/luacrypto-0.3.2-2.src.rock
src/lcrypto.c: In function 'digest_pnew':
src/lcrypto.c:81:61: error: invalid application of 'sizeof' to incomplete type 'EVP_MD_CTX' {aka 'struct evp_md_ctx_st'}
     EVP_MD_CTX *c = (EVP_MD_CTX *)lua_newuserdata(L, sizeof(EVP_MD_CTX));
                                                             ^~~~~~~~~~
src/lcrypto.c: In function 'digest_reset':
src/lcrypto.c:120:10: warning: implicit declaration of function 'EVP_MD_CTX_cleanup'; did you mean 'EVP_MD_CTX_create'? [-Wimplicit-function-declaration]
     if (!EVP_MD_CTX_cleanup(c))
          ^~~~~~~~~~~~~~~~~~
          EVP_MD_CTX_create
src/lcrypto.c: In function 'encrypt_pnew':
src/lcrypto.c:331:69: error: invalid application of 'sizeof' to incomplete type 'EVP_CIPHER_CTX' {aka 'struct evp_cipher_ctx_st'}
     EVP_CIPHER_CTX *c = (EVP_CIPHER_CTX *)lua_newuserdata(L, sizeof(EVP_CIPHER_CTX));
                                                                     ^~~~~~~~~~~~~~
src/lcrypto.c: In function 'encrypt_fencrypt':
src/lcrypto.c:425:20: error: storage size of 'c' isn't known
     EVP_CIPHER_CTX c;
                    ^
. . .

I'm still a newb with docker, but I just rebuilt the Dockerfile with the original alpine:3.8 setup and was able to get everything working properly.

I suspect this has something to do with Alpine's move from LibreSSL to OpenSSL, if that is any help.

Consider adding ability to reload HAProxy

It would be really nice if there was an easy way to reload the haproxy instance in this image via doing something like docker exec -i -t haproxy /reload whilst it's running so it isn't necessary to restart the container itself (which then executes the like of haproxy -f <config> -p <pidfile> -d -D -sf $(cat <pidfile>))

However, I'm pretty sure the only way to do that is by providing a different init 1 process (i.e. supervisor) which may be unfavorable based on what these official repos/images are supposed to provide (which means I won't be too mad if this issue gets closed ;P)

Update Alpine to 3.7, openssl -> libressl, update packages

Hello!

I have 3 suggestions how we can improve this image.

Here:
https://github.com/docker-library/haproxy/blob/master/1.8/alpine/Dockerfile#L1

replace
FROM alpine:3.6
with
FROM alpine:3.7

We can update packages before installing HAProxy. They will not break something because of they are from same release (3.6 or 3.7), usually it's just bugfixes to software.

Before
https://github.com/docker-library/haproxy/blob/master/1.8/alpine/Dockerfile#L14

add

    && apk upgrade --no-cache \

Also we can replace openssl to libressl
https://github.com/docker-library/haproxy/blob/master/1.8/alpine/Dockerfile#L20-L21

replace

		openssl \
		openssl-dev \

with

		libressl \
		libressl-dev \

Unable to start haproxy:1.5.11 due to missing library (libpcreposix.so.3)

Getting this error when starting an haproxy container:

haproxy: error while loading shared libraries: libpcreposix.so.3: cannot open shared object file: No such file or directory

I believe I'm using the latest haproxy image:

[jyundt@laptop ~]$ docker inspect haproxy
[{
    "Architecture": "amd64",
    "Author": "",
    "Checksum": "tarsum.dev+sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "Comment": "",
    "Config": {
        "AttachStderr": false,
        "AttachStdin": false,
        "AttachStdout": false,
        "Cmd": [
            "haproxy",
            "-f",
            "/usr/local/etc/haproxy/haproxy.cfg"
        ],
        "CpuShares": 0,
        "Cpuset": "",
        "Domainname": "",
        "Entrypoint": null,
        "Env": [
            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
            "HAPROXY_MAJOR=1.5",
            "HAPROXY_VERSION=1.5.11",
            "HAPROXY_MD5=5500a79d0d2b238d4a1e9749bd0c2cb2"
        ],
        "ExposedPorts": null,
        "Hostname": "feec6e4827bc",
        "Image": "9abea1acdfb00b7aadd63433190074126d027d5f0860f810c810d06b43c4e6d7",
        "Labels": null,
        "MacAddress": "",
        "Memory": 0,
        "MemorySwap": 0,
        "NetworkDisabled": false,
        "OnBuild": [],
        "OpenStdin": false,
        "PortSpecs": null,
        "SecurityOpt": null,
        "StdinOnce": false,
        "Tty": false,
        "User": "",
        "Volumes": null,
        "WorkingDir": ""
    },
    "Container": "84458acf47c4c03b322cbde39d938d52a66a46108398f7cacb8b36c3533ad007",
    "ContainerConfig": {
        "AttachStderr": false,
        "AttachStdin": false,
        "AttachStdout": false,
        "Cmd": [
            "/bin/sh",
            "-c",
            "#(nop) CMD [haproxy -f /usr/local/etc/haproxy/haproxy.cfg]"
        ],
        "CpuShares": 0,
        "Cpuset": "",
        "Domainname": "",
        "Entrypoint": null,
        "Env": [
            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
            "HAPROXY_MAJOR=1.5",
            "HAPROXY_VERSION=1.5.11",
            "HAPROXY_MD5=5500a79d0d2b238d4a1e9749bd0c2cb2"
        ],
        "ExposedPorts": null,
        "Hostname": "feec6e4827bc",
        "Image": "9abea1acdfb00b7aadd63433190074126d027d5f0860f810c810d06b43c4e6d7",
        "Labels": null,
        "MacAddress": "",
        "Memory": 0,
        "MemorySwap": 0,
        "NetworkDisabled": false,
        "OnBuild": [],
        "OpenStdin": false,
        "PortSpecs": null,
        "SecurityOpt": null,
        "StdinOnce": false,
        "Tty": false,
        "User": "",
        "Volumes": null,
        "WorkingDir": ""
    },
    "Created": "2015-03-19T23:36:52.807406697Z",
    "DockerVersion": "1.4.1",
    "Id": "eb68593a717c8753dbf408e3170662db5ab5c09a8bc7c77e94f65135ad16821c",
    "Os": "linux",
    "Parent": "9abea1acdfb00b7aadd63433190074126d027d5f0860f810c810d06b43c4e6d7",
    "Size": 0,
    "VirtualSize": 97467894
}
]
[jyundt@laptop ~]$ docker run --rm haproxy
haproxy: error while loading shared libraries: libpcreposix.so.3: cannot open shared object file: No such file or directory
[jyundt@laptop ~]$ 

Error when using with redis cluster

Hi!

We are using your container, and we are getting some problems with redis cluster.

We have based our configuration file on this HAProxy blog entry.

What we've seen is that even if it assumes two of the nodes are down on the stats page, it stills redirect the request to two instances (to the master and one of the slaves), so, it's not working properly. We think this is problem of using it inside a docker, because if using outside, it does not happen.

Our cfg is the following:

global
    log 127.0.0.1 local0
    log 127.0.0.1 local1 notice
    stats timeout 30s
    maxconn 131070
    ulimit-n 262500
    nbproc 1
    user root
    group root

listen stats :1936
    mode http
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /
    stats auth admin:admin

listen redis :6379
    mode tcp
    option tcplog
    option tcp-check
    tcp-check send PING\r\n
    tcp-check expect string +PONG
    tcp-check send info\ replication\r\n
    tcp-check expect string role:master
    tcp-check send QUIT\r\n
    tcp-check expect string +OK
    server redis_01 X.X.X.1:6379 maxconn 1024 check inter 1s
    server redis_02 X.X.X.2:6379 maxconn 1024 check inter 1s
    server redis_03 X.X.X.3:6379 maxconn 1024 check inter 1s

Could anyone tell us if this has been seen before? Is there any problem on our config file?

Thanks in advance!

Container exits when using "docker-compose up"

Hi,

is this the normal behavior? Shouldn't this container stay up as haproxy is supposed to be a service?

My docker-compose.yml file looks like this:

version: '2'
services:
    haproxy:
        image: haproxy:1.7
        ports:
            - 80:80
        expose:
            - 80
        network_mode: host
        volumes:
            - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg

Any help would be appreciated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.