diff --git a/Docker.md b/Docker.md index e54f8d1eb..878d780c5 100644 --- a/Docker.md +++ b/Docker.md @@ -13,10 +13,12 @@ For example, you should see in the logs: > > database_1 | Version: '10.1.46-MariaDB-1\~bionic' socket: '/var/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution +Or you can check the `database` container status to be "healthy". + Then, open a second terminal and run: ``` -docker-compose run linuxfr.org bin/rails db:setup +docker-compose exec linuxfr.org bin/rails db:setup ``` Finally, the environment is ready and you can open [http://dlfp.lo](http://dlfp.lo) diff --git a/deployment/database/Dockerfile b/deployment/database/Dockerfile index 1cadc5f9a..9b0bfd24d 100644 --- a/deployment/database/Dockerfile +++ b/deployment/database/Dockerfile @@ -1,3 +1,3 @@ -FROM mariadb:10.1 +FROM docker.io/mariadb:10.1 COPY ./docker-entrypoint-initdb.d /docker-entrypoint-initdb.d diff --git a/deployment/linuxfr-board/Dockerfile b/deployment/linuxfr-board/Dockerfile index ebde3155e..b64158800 100644 --- a/deployment/linuxfr-board/Dockerfile +++ b/deployment/linuxfr-board/Dockerfile @@ -1,22 +1,39 @@ -FROM ruby:2-slim-buster +FROM docker.io/ruby:2-slim-buster -LABEL maintainer="adrien@adorsaz.ch" -LABEL version="1.0" -LABEL description="Run LinuxFr board service for LinuxFr.org Ruby on Rails website" +LABEL org.opencontainers.image.title="Board for LinuxFr.org" +LABEL org.opencontainers.image.description="Users of the LinuxFr.org website can chat on a space called the board (« la tribune » in french). \ +This Ruby daemon notifies the users when something is said with Server-Sent Event / EventSource." +LABEL org.opencontainers.image.source="https://github.com/linuxfrorg/board-sse-linuxfr.org" +LABEL org.opencontainers.image.url="https://github.com/linuxfrorg/board-sse-linuxfr.org" +LABEL org.opencontainers.image.licenses="AGPL-3.0-only" +LABEL org.opencontainers.image.version="1.1" +LABEL org.opencontainers.image.authors="Adrien Dorsaz " -WORKDIR /linuxfr-board +ARG UID=1200 + +RUN \ + set -eux; \ + IFS=$'\n\t'; \ + apt-get update; \ + # Install dependencies \ + # and add curl to be used by the healthcheck defined in compose.yaml \ + apt-get install -y --no-install-recommends \ + build-essential git ruby ruby-dev \ + curl; \ + apt-get clean; -# Install dependencies -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential ruby ruby-dev \ - && apt-get clean +USER ${UID} +WORKDIR /linuxfr-board +ENV HOME=/linuxfr-board # Install board-linuxfr RUN gem install board-linuxfr -v '~> 0.1.3' -RUN apt purge --autoremove -y build-essential ruby-dev +# Clean development dependencies +USER 0 +RUN apt-get purge --autoremove -y build-essential ruby-dev +USER ${UID} EXPOSE 9000 CMD ["board-linuxfr"] diff --git a/deployment/linuxfr-img/Dockerfile b/deployment/linuxfr-img/Dockerfile index 039b107dc..1c58bf955 100644 --- a/deployment/linuxfr-img/Dockerfile +++ b/deployment/linuxfr-img/Dockerfile @@ -1,24 +1,50 @@ -FROM debian:bullseye-slim as build - -LABEL maintainer="adrien@adorsaz.ch" -LABEL version="2.0" -LABEL description="Run LinuxFr image caching service for LinuxFr.org" - +FROM docker.io/debian:bullseye-slim as build + +LABEL org.opencontainers.image.title="LinuxFr.org image caching service" +LABEL org.opencontainers.image.description="Store external images into a cache to not flood external website" +LABEL org.opencontainers.image.source="https://github.com/linuxfrorg/img-LinuxFr.org" +LABEL org.opencontainers.image.url="https://github.com/linuxfrorg/linuxfr.org/blob/master/Container.md" +LABEL org.opencontainers.image.licenses="AGPL-3.0-only" +LABEL org.opencontainers.image.version="2.1" +LABEL org.opencontainers.image.authors="Adrien Dorsaz " + +ARG UID=1200 + +RUN \ + set -eux; \ + IFS=$'\n\t'; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + golang git ca-certificates; \ + apt-get clean; + +USER ${UID} ENV GOPATH=/linuxfr-img +ENV HOME=/linuxfr-img WORKDIR /linuxfr-img # Build linuxfr-img -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - golang git ca-certificates \ - && apt-get clean \ - && go get -u github.com/linuxfrorg/img-LinuxFr.org +RUN go get -u github.com/linuxfrorg/img-LinuxFr.org + +FROM docker.io/debian:bullseye-slim as deploy -FROM debian:bullseye-slim as deploy +ARG UID=1200 +# Install curl to be used by the healthcheck defined in compose.yaml +RUN \ + set -eux; \ + IFS=$'\n\t'; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + curl; \ + apt-get clean; + +USER ${UID} +ENV GOPATH=/linuxfr-img +ENV HOME=/linuxfr-img WORKDIR /linuxfr-img -COPY --from=build /linuxfr-img/bin/img-LinuxFr.org . +COPY --from=build --chown=${UID}:0 --chmod=770 /linuxfr-img/bin/img-LinuxFr.org . EXPOSE 8000 diff --git a/deployment/linuxfr.org/Dockerfile b/deployment/linuxfr.org/Dockerfile index 8506410aa..98ed3949c 100644 --- a/deployment/linuxfr.org/Dockerfile +++ b/deployment/linuxfr.org/Dockerfile @@ -1,48 +1,58 @@ -FROM debian:stretch-slim +FROM docker.io/debian:bullseye-slim -LABEL maintainer="adrien@adorsaz.ch" -LABEL version="1.0" -LABEL description="Run LinuxFr.org Ruby on Rails website" +LABEL org.opencontainers.image.title="LinuxFr.org website" +LABEL org.opencontainers.image.description="Run LinuxFr.org Ruby on Rails website" +LABEL org.opencontainers.image.source="https://github.com/linuxfrorg/linuxfr.org" +LABEL org.opencontainers.image.url="https://github.com/linuxfrorg/linuxfr.org/blob/master/Docker.md" +LABEL org.opencontainers.image.licenses="AGPL-3.0-only" +LABEL org.opencontainers.image.version="2.0" +LABEL org.opencontainers.image.authors="Adrien Dorsaz " -WORKDIR /linuxfr.org +ARG UID=1200 # Install system dependencies -# Debian Stretch has been archived so we replace the sources with the archived ones -RUN echo 'deb http://archive.debian.org/debian stretch main' > '/etc/apt/sources.list' \ - && echo 'deb http://archive.debian.org/debian stretch-proposed-updates main' >> '/etc/apt/sources.list' \ - && echo 'deb http://archive.debian.org/debian stretch-backports main' >> '/etc/apt/sources.list.d/linuxfr.list' \ - && apt-get update \ - && apt-get install -y --no-install-recommends --allow-downgrades \ - mysql-client libmysql++-dev git \ - build-essential openssl libreadline-dev curl libcurl4-openssl-dev zlib1g=1:1.2.8.dfsg-5 \ +RUN \ + set -eux; \ + IFS=$'\n\t'; \ + apt-get update; \ + apt-get install -y --no-install-recommends --allow-downgrades \ + mariadb-client libmariadb++-dev git \ + build-essential openssl libreadline-dev curl libcurl4-openssl-dev zlib1g \ zlib1g-dev libssl-dev libxml2-dev libxslt-dev autoconf libgmp-dev libyaml-dev \ ncurses-dev bison automake libtool imagemagick libc6-dev hunspell \ hunspell-fr-comprehensive ruby ruby-dev ruby-rack \ - && apt-get install -t stretch-backports -y --no-install-recommends \ - nodejs npm \ - && gem install bundler -v 1.17.3 \ - && apt-get clean + nodejs npm; \ + gem install bundler -v 1.17.3; \ + apt-get clean -RUN mkdir /home/linuxfr.org -ENV HOME /home/linuxfr.org +USER ${UID} +ENV HOME=/linuxfr.org +WORKDIR /linuxfr.org # Install node external dependencies -COPY package*.json ./ +COPY --chown=${UID}:0 --chmod=770 package*.json ./ RUN npm ci # Install external dependencies -COPY Gemfile* ./ +COPY --chown=${UID}:0 --chmod=770 Gemfile* ./ + +USER 0 +RUN \ + set -eux; \ + IFS=$'\n\t'; \ + bundle config set path 'vendor/bundle'; \ + bundle config set deployment 'true'; \ + bundle install; \ + chown ${UID}:0 -R .; -RUN bundle config set path 'vendor/bundle' \ - && bundle config set deployment 'true' \ - && bundle install +USER ${UID} # Configure the application -COPY deployment/linuxfr.org/database.yml config/database.yml -COPY config/secrets.yml.sample config/secrets.yml +COPY --chown=${UID}:0 --chmod=770 deployment/linuxfr.org/database.yml config/database.yml +COPY --chown=${UID}:0 --chmod=770 config/secrets.yml.sample config/secrets.yml # Bundle source code -COPY . /linuxfr.org +COPY --chown=${UID}:0 --chmod=770 . /linuxfr.org EXPOSE 3000 diff --git a/docker-compose.yaml b/docker-compose.yaml index ff1db0a4d..653e65b8b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,5 +1,3 @@ -version: '3.1' - services: linuxfr.org: build: @@ -10,50 +8,75 @@ services: volumes: # Share host directories so, the developer can edit them # and see the result without need to restart the container - - ./app:/linuxfr.org/app - - ./db:/linuxfr.org/db - - ./public:/linuxfr.org/public - - ./test:/linuxfr.org/test + - ./app:/linuxfr.org/app:Z + - ./db:/linuxfr.org/db:Z + - ./lib:/linuxfr.org/lib:Z + - ./public:/linuxfr.org/public:Z + - ./test:/linuxfr.org/test:Z # uploads are shared with the nginx service - data-uploads:/linuxfr.org/uploads tmpfs: - /linuxfr.org/public/tmp:size=100M + healthcheck: + test: curl --fail http://localhost:3000 depends_on: - - database - - redis + database: + condition: service_healthy + restart: true + redis: + condition: service_healthy + restart: true linuxfr-board: build: context: deployment/linuxfr-board env_file: - deployment/default.env + healthcheck: + test: curl --fail -I http://localhost:9000 depends_on: - - redis + redis: + condition: service_healthy + restart: true linuxfr-img: build: context: deployment/linuxfr-img env_file: - deployment/default.env + healthcheck: + test: curl --fail http://localhost:8000/status depends_on: - - redis + redis: + condition: service_healthy + restart: true volumes: - cache-img:/linuxfr-img/cache nginx: - image: nginx:stable + image: docker.io/nginx:stable env_file: - deployment/default.env volumes: - - ./deployment/nginx/templates:/etc/nginx/templates - - ./public/fonts:/var/linuxfr/fonts + - ./deployment/nginx/templates:/etc/nginx/templates:Z + - ./public/fonts:/var/linuxfr/fonts:Z - data-uploads:/var/linuxfr/uploads ports: - - "80:80" + - target: 80 + published: 127.0.0.1:80 + protocol: tcp + healthcheck: + test: curl --fail http://$$DOMAIN && curl --fail http://$$DOMAIN/img && curl --fail -I http://$$DOMAIN/b depends_on: - - linuxfr.org - - linuxfr-board - - linuxfr-img + linuxfr.org: + condition: service_healthy + restart: true + linuxfr-board: + condition: service_healthy + restart: true + linuxfr-img: + condition: service_healthy + restart: true database: build: @@ -61,12 +84,18 @@ services: env_file: - deployment/default.env ports: - - "3306:3306" + - target: 3306 + published: 127.0.0.1:3306 + protocol: tcp + healthcheck: + test: mysql -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD --execute "SHOW DATABASES;" volumes: - data-database:/var/lib/mysql redis: - image: redis:5 + image: docker.io/redis:5 + healthcheck: + test: redis-cli --raw incr ping volumes: - data-redis:/data