Docker

Docker-related notes section

Dockerfile

Dockerfiles for several technologies

Golang

Optimized Dockerfile

# Build container
FROM golang:1.17-bullseye AS build

# Set build workdir
WORKDIR /app

# Copy app sources
COPY . .

# Build app
RUN go build -o app .

# ---
# Production container
FROM debian:bullseye-slim

# Set app workdir
WORKDIR /app

# Copy binary
COPY --from=build /app/app .

# Run app
CMD ["./app"]

Common Dockerfile

FROM golang:1.17

# Set app workdir
WORKDIR /go/src/app

# Copy dependencies list
COPY go.mod go.sum ./

# Download dependencies
RUN go mod download

# Copy application sources
COPY . .

# Build app
RUN go build -o app .

# Run app
CMD ["./app"]

NodeJS

Static Site (Webpack)

Dockerfile

# Build container
FROM node:17.3.0-bullseye-slim AS build

# Set build workdir
WORKDIR /usr/src/app

# Copy dependencies list
COPY package*.json ./

# Install dependencies
RUN npm ci

# Copy app sources
COPY . .

# Run tests
RUN CI=true npm run test

# Build app
RUN npm run build

# ---
# Production container
FROM nginx:1.21.5-alpine

# Copy nginx.conf
COPY --from=build /usr/src/app/nginx.conf /etc/nginx/conf.d/default.conf

# Copy static files
COPY --from=build /usr/src/app/build/ /usr/share/nginx/html/

nginx.conf

server { 
    listen 80;
    server_name _ default_server;
    location / {
        root /usr/share/nginx/html;
        try_files $uri /index.html;
    }
}

Common Dockerfile

FROM node:17.3.0-bullseye-slim

# Set app workdir
WORKDIR /usr/src/app

# Copy dependencies list
COPY package*.json ./

# Install dependencies
RUN npm ci

# Copy app sources
COPY . .

# Run tests
RUN CI=true npm run test

# Run app
CMD ["npm", "run", "production"]

Python

Common Dockerfile

FROM python:3.9

# Stdout without buffer
ENV PYTHONUNBUFFERED=1

# Set app workdir
WORKDIR /usr/src/app

# Copy dependencies list
COPY ./requirements.txt .

# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy app sources
COPY . .

# Run app
CMD ["python", "app.py"]

Flutter

Flutter Web App

Dockerfile

# Build container
FROM cirrusci/flutter:2.8.1 AS build

# Set build workdir
WORKDIR /usr/src/app

# Copy app sources
COPY . .

# Build app
RUN flutter build web -t lib/main.dart

# ---
# Production container
FROM nginx:1.21.5

# Copy nginx.conf
COPY --from=build /usr/src/app/nginx.conf /etc/nginx/conf.d/default.conf

# Copy static files
COPY --from=build /usr/src/app/build/web/ /usr/share/nginx/html/

nginx.conf

server { 
    listen 80;
    server_name _ default_server;
    location / {
        root /usr/share/nginx/html;
        try_files $uri /index.html;
    }
}

Docker-compose

Examples of compose files for several technologies

PostgreSQL

version: "3.3"

services:
  postgres:
    image: postgres:13.3
    restart: always
    environment:
      POSTGRES_DB: "dbname"
      POSTGRES_PASSWORD: "superpassword"
    ports:
      - "127.0.0.1:5432:5432"
    volumes:
      - "./data:/var/lib/postgresql/data"

*Replace dbname and superpassword with your values

MongoDB

version: "3.3"

services:
  mongo:
    image: mongo:4.4
    restart: always
    environment:
      MONGO_INITDB_DATABASE: "dbname"
      MONGO_INITDB_ROOT_USERNAME: "root"
      MONGO_INITDB_ROOT_PASSWORD: "superpassword"
    ports:
      - "127.0.0.1:27017:27017"
    volumes:
      - "./data:/data/db"

*Replace dbname and superpassword with your values

Redis

version: "3.3"

services:
  redis:
    image: redis:6.2.6
    restart: always
    ports:
      - "127.0.0.1:6379:6379"
    volumes:
      - "./data:/var/lib/redis"

Gitlab Runner Installation

docker-compose.yml

version: "3.3"

services:
  runner:
    image: gitlab/gitlab-runner
    restart: always
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "./config.toml:/etc/gitlab-runner/config.toml"

config.toml Docs

[[runners]]
name = "Runner Name"
url = "https://gitlab.com/"
token = "supersecrettoken"
executor = "docker"
concurrent = 10
[runners.docker]
tls_verify = false
image = "docker"
privileged = true
disable_cache = false
volumes = ["/certs/client", "/cache"]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]

*Replace supersecrettoken with your value

Drone CI Installation (Gitlab)

version: "3.3"

services:
  drone:
    image: drone/drone
    restart: always
    environment:
      DRONE_GITLAB_SERVER: "https://gitlab.com"
      DRONE_GITLAB_CLIENT_ID: "gitlab_oauth_client_id"
      DRONE_GITLAB_CLIENT_SECRET: "gitlab_oauth_secret"
      DRONE_RPC_SECRET: "drone_rpc_secret"
      DRONE_SERVER_HOST: "drone.example.com"
      DRONE_SERVER_PROTO: "https"
      DRONE_USER_CREATE: "username:SomeGitlabUser,admin:true"
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - "./data:/data"

  drone-runner:
    image: drone/drone-runner-docker
    restart: always
    environment:
      DRONE_RUNNER_NAME: "drone_runner_name"
      DRONE_RUNNER_CAPACITY: "10"
      DRONE_RPC_SECRET: "drone_rpc_secret"
      DRONE_RPC_HOST: "drone.example.com"
      DRONE_RPC_PROTO: "https"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

*Replace drone_*, gitlab_* and drone.example.com with your values

GitLab

GitlabCI-related notes section

Build Docker image

stages:
  - build

services:
  - docker:20.10.12-dind

variables:
  TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest
  TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA

build:
  image: docker:20.10.12
  stage: build

  before_script:
    # Login to GitLab Registry
    - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
    # Pull last image to use cache
    - docker pull "$TAG_LATEST" || true
  script:
    # Build Image
    - docker build --cache-from "$TAG_LATEST" -t $TAG_COMMIT -t $TAG_LATEST .
    # Push to GitLab Registry
    - docker push $TAG_COMMIT
    - docker push $TAG_LATEST

Run SSH command

stages:
  # ...
  - deploy

deploy:
  stage: deploy
  before_script:
    - chmod 600 $SSH_KEY
    - apk update && apk add openssh-client
  script:
    - ssh -i $SSH_KEY -o StrictHostKeyChecking=no [email protected]$SSH_HOST "command1"
    - ssh -i $SSH_KEY -o StrictHostKeyChecking=no [email protected]$SSH_HOST "command2"
#  only:
#    - master
#  environment: production

CI Variables

SSH_KEY

Type: File
\n at the end of the file!

SSH_HOST

Type: Variable

SSH_USER

Type: Variable

Deploy to Kubernetes via Helm

stages:
  # ...
  - deploy

deploy:
  stage: deploy
  image: alpine/helm:3.7.2
  script:
    # Update Chart Version
    - "sed -i \"s/^appVersion:.*$/appVersion: $CI_COMMIT_SHORT_SHA/\" chart/Chart.yaml"
    # Deploy
    - helm upgrade $CI_PROJECT_NAME chart --install --namespace=$KUBERNETES_NAMESPACE --kubeconfig=$KUBERNETES_CONFIG
#  only:
#    - master
#  environment: production

CI Variables

KUBERNETES_CONFIG

Type: File

KUBERNETES_NAMESPACE

Type: Variable

Bitbucket

Bitbucket-related notes section

Run SSH command

image: atlassian/default-image:latest

pipelines:
  branches:
    master:
      - step:
          deployment: production
          clone:
            enabled: false
          script:
            - echo "command1" | ssh [email protected]$SSH_HOST
            - echo "command2" | ssh [email protected]$SSH_HOST

CI Variables

SSH_HOST

SSH_USER

Copy SSH pubkey to server (Repo Settings/Pipelines/SSH keys)

GitHub Actions

Actions-related notes section

Build Docker Image

name: Docker

on: [ push ]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout repository
        uses: actions/[email protected]

      - name: Log into registry ${{ env.REGISTRY }}
        if: github.event_name != 'pull_request'
        uses: docker/[email protected]
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract Docker metadata
        id: meta
        uses: docker/[email protected]
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

      - name: Build and push Docker image
        uses: docker/[email protected]
        with:
          context: .
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

Run SSH command

name: Docker

on: [ push ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      # ...
      
      - name: ssh-pipeline
        uses: cross-the-world/[email protected]
        with:
          host: ${{ secrets.SSH_HOST }}
          port: ${{ secrets.SSH_PORT }}
          user: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            command1
            command2

Secrets

  • SSH_HOST
  • SSH_PORT
  • SSH_USER
  • SSH_KEY

Deploy to GitHub Pages

name: Github Pages

on: [ push ]

jobs:
  pages:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/[email protected]

      - name: Build HTML
        run: |
          npm ci
          npm build

      - name: Deploy
        uses: JamesIves/[email protected]
        with:
          branch: gh-pages
          folder: build

Miscellaneous stuff

Single notes without a category

Bitrix admin panel without password

<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
global $USER;
$USER->Authorize(1);
@unlink(__FILE__); // Delete file
LocalRedirect("/bitrix/admin/");