Docker

Docker-related notes section

Dockerfile

Dockerfiles for several technologies

Golang

Optimized Dockerfile

# Build container
FROM golang:1.22-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.22

# 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:21.7.3-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.25.4-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:21.7.3-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.12

# 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

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

volumes:
  postgres_data:

*Replace dbname and superpassword with your values

MongoDB

services:
  mongo:
    image: mongo:7.0.9
    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:
      - "mongo_data:/data/db"

volumes:
  mongo_data:

*Use mongo:4.4 image if your system does not support AVX instructions
**Replace dbname and superpassword with your values

Redis

services:
  redis:
    image: redis:7.2.4
    restart: always
    ports:
      - "127.0.0.1:6379:6379"
    volumes:
      - "redis_data:/var/lib/redis"

volumes:
  redis_data:

Gitlab Runner Installation

docker-compose.yml

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)

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 $SSH_USER@$SSH_HOST "command1"
    - ssh -i $SSH_KEY -o StrictHostKeyChecking=no $SSH_USER@$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

Drone CI

Drone CI notes section

Build Docker Image

kind: pipeline
type: docker
name: build

steps:
  - name: build
    image: plugins/docker
    settings:
      registry: registry.gitlab.com
      username:
        from_secret: docker_username
      password:
        from_secret: docker_password
      repo: registry.gitlab.com/USER/REPO/${DRONE_COMMIT_BRANCH}
      tags:
        - latest
        - ${DRONE_COMMIT_SHA}
      cache_from:
        - registry.gitlab.com/USER/REPO/${DRONE_COMMIT_BRANCH}:latest

*Replace USER and REPO by your values

CI Variables

docker_username

docker_password

Run SSH command

kind: pipeline
type: docker
name: deploy

clone:
  disable: true

steps:
  - name: deploy
    image: appleboy/drone-ssh
    settings:
      host:
        from_secret: ssh_address
      username:
        from_secret: ssh_username
      key:
        from_secret: ssh_key
      port: 22
      script_stop: true
      script:
        - command1
        - command2

trigger:
  branch:
    - master
  event:
    - push

CI Variables

ssh_key

\n at the end of the file!

ssh_address

ssh_username

Run Ansible playbook

kind: pipeline
type: docker
name: deploy

steps:
  - name: deploy
    image: librespace/ansible:latest
    environment:
      ANSIBLE_INVENTORY:
        from_secret: ansible_inventory
      ANSIBLE_SSH_KEY:
        from_secret: ansible_ssh_key
    commands:
      - apt update && apt-get install -y ssh
      - echo "$ANSIBLE_INVENTORY" > ansible/inventory.yml
      - echo "$ANSIBLE_SSH_KEY" > ansible/id_ecdsa && chmod 600 ansible/id_ecdsa

      - ansible-galaxy collection install -r ansible/requirements.yml # Install requirements (If needed)
      
      - ansible-playbook -i ansible/inventory.yml --private-key ansible/id_ecdsa --ssh-common-args='-o StrictHostKeyChecking=no' ansible/playbook.yml

trigger:
  branch:
    - master
  event:
    - push

CI Variables

ansible_ssh_key

\n at the end of the file!

ansible_inventory

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 $SSH_USER@$SSH_HOST
            - echo "command2" | ssh $SSH_USER@$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/checkout@v2

      - 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: Deploy

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      # ...

      - name: ssh-pipeline
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.SSH_HOST }}
          port: ${{ secrets.SSH_PORT }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            someSshCommand

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/");